Skip to content

Latest commit

 

History

History
104 lines (54 loc) · 12.3 KB

README.md

File metadata and controls

104 lines (54 loc) · 12.3 KB

Logging Dashboard

Context

At Fractal, we have thousands of log.txt files that are generated by our streaming technology every time a user connects to their virtual machine. These logs are stored in an AWS S3 bucket, and each log has a public-facing URL. For example: https://fractal-technical-interview-data.s3.amazonaws.com/client19772.txt (Note: these logs have been artificially generated for the purpose of this question).

The purpose of these logs is to allow our engineers to debug, and to extract insights and summary statistics from the logs. We currently have an internal employee dashboard that displays these logs and analytics in a clean UI. Your task is to implement your own version of this internal dashboard, given the raw log.txt files and a set of guidelines outlined below.

This project is intentionally very open-ended. As you complete this project, you should pretend that you are a software engineer who has complete autonomy over the design and capabilities of the project, given a certain set of expected features.

Estimated Completion Time: 8 Hours

Setting It Up

We have provided a barebone React app and Python Flask application, which is meant to help you get started. NOTE: If you are familiar with another framework or would like to set up your own client/server, feel free to do so--the setup process below is meant to let you get started as quickly as possible.

If you have any problems setting up, please feel free to contact Ming via [email protected], or text 617-997-9751 if he doesn't respond within a few minutes.

  1. git clone this repo. You'll see that this repo is divided into two folders: client and server. These two folders are completely separate. The client folder contains all the code of a barebone React app with all the frameworks you'll need already set up for you (Redux, blank React components for you to fill in, etc.). The server folder contains all the code of a barebone Python Flask REST API, with everything already set up for you (file structure, blueprints, etc.). Your task will be to modify these two files with code as you see fit.

  2. Let's start by setting up the client (React) folder. In your terminal, cd into client folder.

  3. Make sure you have Node.js and npm installed. In your terminal, type npm i to install the necessary dependencies. Then, type npm start. A browser should automatically open up with the React app running on localhost. (Note: because the server has not been set up yet, React may throw an error. Don't worry about this for now, just proceed to Step #4).

  4. Now, let's set up the server (Python Flask) folder. cd .. out of the client folder, and cd into the server folder.

  5. Make sure that you have Python 3 installed on your computer. To check your current Python version, type py or python into your terminal, and the version number should appear. If you don't have Python 3, you can download it from the Python website (I would recommend Python 3.6.8, since that's the version that we use to develop this server). You are also welcome to Dockerize your backend if you'd like, which may help if you have conflicts with Python versions.

  6. Assuming you have Python 3 running as the default Python on your computer, create a virtual environment by running virtualenv env in the server folder on the terminal. If you have Python 2 as your default but have installed Python 3 on your computer, locate the path of your Python 3 executable, and type virtualenv --python=[DIRECTORY PATH] env into your terminal. If successful, you should see an env folder created in your server folder.

  7. Activate the virtual environment by running env\Scripts\activate (Windows) or source env/bin/activate (MacOS/Linux) from the same directory as above in the terminal.

  8. Install all the packages into your virtual environment by running pip install -r requirements.txt. This will take some time. Make sure that your virtual environment is activated from #7 before doing this.

  9. Tell the local environment what the entry point is to the webserver by typing set FLASK_APP=run.py.

  10. Type flask run to start the webserver on localhost. If everything has been set up correctly, you will see the server running on localhost in your terminal.

  11. Take note of the localhost URL, and navigate back the client folder. Within the client folder, locate the src/constants.js file. Replace the URL on Line 4 with the localhost URL that is currently running on your computer.

  12. Reload the React app by refreshing your browser. You should see a blank page with some dummy code!

Your Task

If you open up your console by going to the browser, right clicking, selecting "Inspect", and then navigating to the "Console" window, you'll see that the log.txt files have already been stored in Redux state for you, courtesy of the server. You'll see that the log.txt files are stored in a big list of JSON objects, where each JSON has a server/client key, and a username/ip/last_updated/connection_id key/version.

server_logs and client_logs: The reason that we have server/client logs is because our streaming tech requires two computers: a server (the virtual machine) and a client (your local computer). So, the server logs are the logs generated by the server, and the client logs are the logs generated by the client for every connection.

Connection_id: Every connection is assigned a unique ID, which we use to identify unique connections.

ip: The IP address of the server in this connection.

last_updated: The time that the logs were received.

version: An internal version number that helps us keep track of which GitHub commit the streaming tech is running on.

Given these logs, your task is to implement the following features in a single-page dashboard:

  1. An interface to view the logs: Build a nice, clean UI where we can scroll through the big list and easily access the server/client logs and view the other fields (connection_id, ip, last_updated, etc.). For example, something really simple would be to build a table where each row of the table is an entry in the list.

  2. A way to load more logs upon request If you go to src/sagas/index.js, you'll see that Line 11 is where we query the server for the logs. We currently have it set to retrieve only the first 100 logs, but if you go to app/constants/logs.py in the server folder, you'll see that we actually have thousands of logs. The reason that we only do the first 100 is because we don't want to flood the browser with too much data all at once. Implement some sort of infinite scrolling or "load more" feature where we can request more logs once we've reached the bottom of the page.

  3. Log analytics and plotting This is where things get interesting. If you open up one of the log files (for instance, https://fractal-technical-interview-data.s3.amazonaws.com/client19772.txt), you'll see that each line follows a consistent format (separated using the "|" character), which means that we can load this .txt file into a Python dataframe. In particular, we are interested in the following log events:

    • Latency: if you Ctrl-F/Cmd-F the word "latency" in any client log, you'll see that we have latency metrics (in seconds), which measures the user's round-trip network latency.
    • Avg Decode Time: if you Ctrl-F/Cmd-F the phrase "Avg Decode Time" in any client log, you'll see that we have avg decode times (in seconds), which measures how long the client's video decoder takes to decode a single video frame.
    • Average Encode Time: if you Ctrl-F/Cmd-F the phrase "Average Encode Time" in any server log (here's one for reference: https://fractal-technical-interview-data.s3.amazonaws.com/server54508.txt), you'll see that we have average encode times (in seconds), which measures how long it's taking the server's GPU to encode a single video frame.
    • Average Encode Size: if you Ctrl-F/Cmd-F the phrase "Average Encode Size" in any server log, you'll see that we measure the size of each frame in bytes.

For each log, we want to extract the above values from a log.txt file as a time series, and plot the time series in the dashboard. So, for each entry in our list, we would have 4 time series plots (assuming both client and server logs exist). Note: you'll want to do this server-side by creating a new endpoint in app/blueprints/log_blueprint.py in the server.

  1. Handling missing information You'll notice that for some entries in the list, the client or server logs are missing. We want to be able to handle this in the UI, to let the user know that a certain log.txt file is missing.

  2. Log filtering We want to be able to search for logs by username. Implement a search bar that lets us find all the logs associated with a particular user (Note: not just the logs that have been loaded into the browser, but all the logs that are stored in the server).

  3. Bonus features If you open up any log files, you'll see that each line comes with a status code of INFO, WARNING, or ERROR. For each log file, we are interested in how many ERRORs and WARNINGs there are, both in absolute terms and as a percentage of total lines in the log file. Note: you'll want to do this server-side by creating a new endpoint in app/blueprints/log_blueprint.py in the server, or appending more code to your endpoint in part #3. Additionally, feel free to get creative and think about features that would be useful to a user, like log bookmarking, summary statistics of errors (i.e. across all the logs, which errors are most common?), summary statistics of time series (what is the median of the time series? correlations between number of errors and median network latency?), etc. or anything else that comes to mind. Impress us by thinking outside the box!

We strongly encourage you to think of a clean UI that can convey all of the above information in a single paged dashboard (no multiple tabs or multiple pages!). For best results, we also strongly recommend using a design/prototyping tool to figure out how you want your dashboard to look before you actually start coding (e.g. Figma, Adobe Illustrator), if you're familiar with such tools.

How You Will Be Assessed

The most important criteria we are looking for is a production-grade product that shows maturity in both UX design and code design. That is to say--if this were a live product and I were a user seeing what you built for the first time, would I think that this looks more like a trustworthy, well-developed product or a school project? If I were a software engineer looking at your code base for the first time, would I easily be able to read through it? Of course, we don't expect perfection given your limited amount of time, but we are actively looking for signs of mature, thoughtful software engineering.

More specifically, you will be assessed on the following four categories:

  1. Quality of completion Were all the features implemented, and were they implemented well/without bugs?

  2. Design We place a strong emphasis on creating beautiful, clean user interfaces. How well was the UI designed? How read-able and easily understandable is the dashboard to a new user? Do I have to spend a lot of time clicking to figure things out or does everything just make sense upon first glance?

  3. Code Design How readable and organized is the code?

  4. Performance What considerations were given to loading times, scaling to large numbers of concurrent requests/connections, etc.?

How To Submit

To submit, simply create your own branch and push to that branch. We expect you to complete this challenge within 8 hours, although we do understand that there can be unexepected delays in setting up so we will allow for some extra time if needed. After submitting, we may set up a brief phone conversation, where we will discuss your design considerations and show you the actual, internal version of the dashboard that we use.

This Boilerplate is Not Perfect...

If you decide to use the Flask/React boilerplate we gave you, you may notice that there are some design decisions we made that are not ideal or at the very least debatable. If you find anything about our boilerplate code design that you would change or improve upon, please include it in NOTES.md for bonus points.

Final Thoughts

Technical assessments aside, the goal of this project is for you to have fun implementing a full React app and server (almost) from scratch! Please be as creative as you'd like, and enjoy! :)