{ "cells": [ { "cell_type": "markdown", "id": "f0ba404d-342f-418d-8cda-bb90605601a8", "metadata": {}, "source": [ "# Data Analysis with Jupyter\n", "\n", "As described in the previous module, we can view the automated experiment output from the VM resource log files.\n", "In this module, we will use the JSON-formatted files to begin to analyze the data (i.e., the latency of getting the web page).\n", "As there is only one client, the initial data will be uninteresting, but the following modules will add complexity\n", "and build on this experiment to enable more interesting data analysis.\n", "\n", "In this module, you will use standard Python-based data science tools including [Jupyter](https://jupyter.org/), [pandas](https://pandas.pydata.org/), [seaborn](https://seaborn.pydata.org/), and [Matplotlib](https://matplotlib.org/) and learn how to assess experiment data with them.\n", "This module is simply an example of how experiment data can be analyzed and there are numerous other tools to do so (e.g., Elasticsearch/Kibana).\n", "While we strive to provide comments explaining what each section of code is accomplishing in-depth discussion/tutorials about these tools is outside the scope of this module.\n", "\n", "First we will install [Jupyter](https://jupyter.org/), [pandas](https://pandas.pydata.org/), [seaborn](https://seaborn.pydata.org/), and [Matplotlib](https://matplotlib.org/) into our Python virtual environment.\n", "\n", "```bash\n", "$ source /opt/firewheel/fwpy/bin/activate\n", "$ python -m pip install jupyter pandas seaborn matplotlib\n", "```\n", "\n", "\n", "## Opening Jupyter\n", "Once installed, you can start Jupyter by running `jupyter-notebook`, which will result in similar output:\n", "\n", "```bash \n", "$ jupyter-notebook\n", "[I 2024-06-03 09:57:15.026 ServerApp] jupyter_lsp | extension was successfully linked.\n", "[I 2024-06-03 09:57:15.031 ServerApp] jupyter_server_terminals | extension was successfully linked.\n", "[I 2024-06-03 09:57:15.037 ServerApp] jupyterlab | extension was successfully linked.\n", "[I 2024-06-03 09:57:15.042 ServerApp] notebook | extension was successfully linked.\n", "...\n", "[I 2024-06-03 09:57:15.346 ServerApp] Jupyter Server 2.14.1 is running at:\n", "[I 2024-06-03 09:57:15.346 ServerApp] http://localhost:8888/tree?token=d68f967dfce80a2f0e4204452ff13046275d75ea420ad0b2\n", "[I 2024-06-03 09:57:15.346 ServerApp] http://127.0.0.1:8888/tree?token=d68f967dfce80a2f0e4204452ff13046275d75ea420ad0b2\n", "[I 2024-06-03 09:57:15.346 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).\n", "```\n", "\n", "**Important:** Take note of the lines with the URL/token as that will be used to access the notebook.\n", "\n", "Depending on how your cluster is configured, Jupyter will likely be running on ``http://localhost:8888``.\n", "If you had to port-forward your miniweb dashboard, you will need to do the same for Jupyter (e.g., ``ssh -Llocalhost:8888:localhost:8888 <node>``).\n", "\n", "Now we can access the notebook via the link provided in the `jupyter-notebook` output (e.g., ``http://localhost:8888/tree?token=d68f...``).\n", "\n", "Create a new notebook and add the following import statements." ] }, { "cell_type": "code", "execution_count": 1, "id": "573ef911-3b94-419f-8109-f22a74f4673b", "metadata": {}, "outputs": [], "source": [ "import glob # noqa: F401\n", "from pathlib import Path\n", "\n", "import pandas as pd\n", "import seaborn as sns\n", "import matplotlib.pyplot as plt\n", "\n", "from firewheel.config import Config" ] }, { "cell_type": "markdown", "id": "b30511b7-67a7-4337-8270-730d0d6e8183", "metadata": {}, "source": [ "## Getting the Right Path\n", "\n", "First we need to identify where the VM resource logs are located. This was described in the previous module, but it can easily be programmatically identified by accessing FIREWHEEL configuration and concatenating the `logging.root_dir` parameter with the `logging.vmr_log_dir` parameter. As a reminder, an example of the `logging` subsection of the configuration is provided below:\n", "\n", "```yaml\n", "logging:\n", " cli_log: cli.log\n", " discovery_log: discovery.log\n", " firewheel_log: firewheel.log\n", " level: DEBUG\n", " minimega_log: minimega.log\n", " root_dir: /scratch/\n", " vmr_log_dir: vm_resource_logs\n", "```" ] }, { "cell_type": "code", "execution_count": 2, "id": "89163212-8738-4712-80a9-4ee0c2cb0acc", "metadata": {}, "outputs": [], "source": [ "# First we should identify the VM resource logging directory\n", "fw_config = Config().config\n", "\n", "# Get the full path to the VM resource logs\n", "vm_resource_log_path = Path(fw_config[\"logging\"][\"root_dir\"]) / Path(\n", " fw_config[\"logging\"][\"vmr_log_dir\"]\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "id": "b9236c7a-630a-486b-9932-6b779b5c370e", "metadata": {}, "outputs": [], "source": [ "# Now we should get all the client data\n", "\n", "# USE THIS LINE FOR THE SINGLE CLIENT EXPERIMENT\n", "paths = vm_resource_log_path.glob(\"Client.json\") # For the single client case\n", "\n", "# USE THIS LINE FOR THE MULTI-CLIENT EXPERIMENT\n", "# paths = vm_resource_log_path.glob(\n", "# \"client-*.json\"\n", "# ) # When we add complexity in later modules.\n", "\n", "\n", "# We can use an empty list to store a single dataframe per VM resource log\n", "dfs = []\n", "for file in paths:\n", " # Read the line-delienated JSON data\n", " data = pd.read_json(file, lines=True)\n", "\n", " # Add Client Name\n", " data[\"client\"] = file.stem\n", "\n", " # Append the data frame to the list\n", " dfs.append(data)\n", "\n", "# Concatenate all the data frames into a single data frame\n", "df = pd.concat(dfs, ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "42c86210-0264-4085-bf52-1421a7e65bea", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>msg</th>\n", " <th>timestamp</th>\n", " <th>time</th>\n", " <th>client</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>Disabling apt-daily.service and apt-daily.timer</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>Checking apt-daily status</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>● apt-daily.service</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>Loaded: masked (/dev/null; bad)</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>Active: inactive (dead) since Mon 2024-06-03 0...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>5</th>\n", " <td>Main PID: 831 (code=exited, status=0/SUCCESS)</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>6</th>\n", " <td></td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>7</th>\n", " <td>Jun 03 09:45:11 host systemd[1]: Starting Dail...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>8</th>\n", " <td>Jun 03 09:45:14 host systemd[1]: Started Daily...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>9</th>\n", " <td>Jun 03 09:46:05 host systemd[1]: Stopped Daily...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>10</th>\n", " <td>● apt-daily.timer - Daily apt download activities</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>11</th>\n", " <td>Loaded: loaded (/lib/systemd/system/apt-daily....</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>12</th>\n", " <td>Active: inactive (dead) since Mon 2024-06-03 0...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>13</th>\n", " <td></td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>14</th>\n", " <td>Jun 03 09:45:11 host systemd[1]: Started Daily...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>15</th>\n", " <td>Jun 03 09:46:05 host systemd[1]: Stopped Daily...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>16</th>\n", " <td>Killing running apt processes</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>17</th>\n", " <td>Warning: Stopping apt-daily.service, but it ca...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>18</th>\n", " <td>apt-daily.timer</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>19</th>\n", " <td>Removed symlink /etc/systemd/system/timers.tar...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>20</th>\n", " <td>Created symlink from /etc/systemd/system/apt-d...</td>\n", " <td>2024-06-03 08:46:07</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>21</th>\n", " <td>ens1 -> 00:00:00:00:00:02</td>\n", " <td>2024-06-03 08:46:41</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>22</th>\n", " <td>SETTING ens1 to IP: 1.0.0.2/24</td>\n", " <td>2024-06-03 08:46:41</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>23</th>\n", " <td>inet 1.0.0.2/24 scope global ens1</td>\n", " <td>2024-06-03 08:46:41</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>24</th>\n", " <td>connect: Network is unreachable</td>\n", " <td>2024-06-03 08:46:52</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>25</th>\n", " <td>NaN</td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>0.157</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>26</th>\n", " <td>% Total % Received % Xferd Average Speed ...</td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>27</th>\n", " <td>Dload Upload Total Spent Left Speed</td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>28</th>\n", " <td></td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>29</th>\n", " <td>0 0 0 0 0 0 0 0 --...</td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " <tr>\n", " <th>30</th>\n", " <td>100 50.0M 100 50.0M 0 0 318M 0 ...</td>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>NaN</td>\n", " <td>Client</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " msg timestamp \\\n", "0 Disabling apt-daily.service and apt-daily.timer 2024-06-03 08:46:07 \n", "1 Checking apt-daily status 2024-06-03 08:46:07 \n", "2 ● apt-daily.service 2024-06-03 08:46:07 \n", "3 Loaded: masked (/dev/null; bad) 2024-06-03 08:46:07 \n", "4 Active: inactive (dead) since Mon 2024-06-03 0... 2024-06-03 08:46:07 \n", "5 Main PID: 831 (code=exited, status=0/SUCCESS) 2024-06-03 08:46:07 \n", "6 2024-06-03 08:46:07 \n", "7 Jun 03 09:45:11 host systemd[1]: Starting Dail... 2024-06-03 08:46:07 \n", "8 Jun 03 09:45:14 host systemd[1]: Started Daily... 2024-06-03 08:46:07 \n", "9 Jun 03 09:46:05 host systemd[1]: Stopped Daily... 2024-06-03 08:46:07 \n", "10 ● apt-daily.timer - Daily apt download activities 2024-06-03 08:46:07 \n", "11 Loaded: loaded (/lib/systemd/system/apt-daily.... 2024-06-03 08:46:07 \n", "12 Active: inactive (dead) since Mon 2024-06-03 0... 2024-06-03 08:46:07 \n", "13 2024-06-03 08:46:07 \n", "14 Jun 03 09:45:11 host systemd[1]: Started Daily... 2024-06-03 08:46:07 \n", "15 Jun 03 09:46:05 host systemd[1]: Stopped Daily... 2024-06-03 08:46:07 \n", "16 Killing running apt processes 2024-06-03 08:46:07 \n", "17 Warning: Stopping apt-daily.service, but it ca... 2024-06-03 08:46:07 \n", "18 apt-daily.timer 2024-06-03 08:46:07 \n", "19 Removed symlink /etc/systemd/system/timers.tar... 2024-06-03 08:46:07 \n", "20 Created symlink from /etc/systemd/system/apt-d... 2024-06-03 08:46:07 \n", "21 ens1 -> 00:00:00:00:00:02 2024-06-03 08:46:41 \n", "22 SETTING ens1 to IP: 1.0.0.2/24 2024-06-03 08:46:41 \n", "23 inet 1.0.0.2/24 scope global ens1 2024-06-03 08:46:41 \n", "24 connect: Network is unreachable 2024-06-03 08:46:52 \n", "25 NaN 2024-06-03 08:48:13 \n", "26 % Total % Received % Xferd Average Speed ... 2024-06-03 08:48:13 \n", "27 Dload Upload Total Spent Left Speed 2024-06-03 08:48:13 \n", "28 2024-06-03 08:48:13 \n", "29 0 0 0 0 0 0 0 0 --... 2024-06-03 08:48:13 \n", "30 100 50.0M 100 50.0M 0 0 318M 0 ... 2024-06-03 08:48:13 \n", "\n", " time client \n", "0 NaN Client \n", "1 NaN Client \n", "2 NaN Client \n", "3 NaN Client \n", "4 NaN Client \n", "5 NaN Client \n", "6 NaN Client \n", "7 NaN Client \n", "8 NaN Client \n", "9 NaN Client \n", "10 NaN Client \n", "11 NaN Client \n", "12 NaN Client \n", "13 NaN Client \n", "14 NaN Client \n", "15 NaN Client \n", "16 NaN Client \n", "17 NaN Client \n", "18 NaN Client \n", "19 NaN Client \n", "20 NaN Client \n", "21 NaN Client \n", "22 NaN Client \n", "23 NaN Client \n", "24 NaN Client \n", "25 0.157 Client \n", "26 NaN Client \n", "27 NaN Client \n", "28 NaN Client \n", "29 NaN Client \n", "30 NaN Client " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Now we have a single dataframe that should look akin to:\n", "df" ] }, { "cell_type": "markdown", "id": "b3e0fbeb-2476-4cab-ba09-968122df4b23", "metadata": {}, "source": [ "## Removing Unnecessary Data\n", "In this particular experiment, we are only interested in the well-formatted JSON provided by cURL.\n", "FIREWHEEL attempts to format non-JSON messages into a parsable format and will always provide a `msg` and `timestamp` field.\n", "However, in our case we have also added the `time` field (as the measure of how long cURL took). Therefore, we can ignore all rows without the `time` field." ] }, { "cell_type": "code", "execution_count": 5, "id": "ccd9ddd0-0540-4d80-a7a8-fa06a2c33a4f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>timestamp</th>\n", " <th>time</th>\n", " <th>client</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>25</th>\n", " <td>2024-06-03 08:48:13</td>\n", " <td>0.157</td>\n", " <td>Client</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " timestamp time client\n", "25 2024-06-03 08:48:13 0.157 Client" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Drop all rows (axis=0) where the `time` column is `NaN`\n", "# Then drop all columns where no data exists (in this case the `msg` column\n", "dropped = df.dropna(axis=0, subset=[\"time\"]).dropna(axis=1)\n", "dropped" ] }, { "cell_type": "markdown", "id": "87255cfa-9f6c-455a-882e-e76ea2075a5e", "metadata": {}, "source": [ "## Plot the data\n", "Now we can use [seaborn](https://seaborn.pydata.org/) to plot the data in a simple bar chart." ] }, { "cell_type": "code", "execution_count": 6, "id": "01c383f7-beeb-41aa-9389-b586526deecd", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "<Figure size 1000x600 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Ensure the image is large enough\n", "plt.figure(figsize=(10, 6))\n", "\n", "# Plot a simple bar chart with each client along the x-axis\n", "# and the time it took along the y-axix\n", "fig = sns.barplot(data=dropped, x=\"client\", y=\"time\")\n", "\n", "# Enhance the output image with a title and better axis labels\n", "plt.xlabel(\"Client Name\")\n", "plt.ylabel(\"Time to get web page\")\n", "plt.title(\"Amount of Time To Fetch the Experiment Web page\")\n", "\n", "# Show the image\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.0" } }, "nbformat": 4, "nbformat_minor": 5 }