{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Ripe-Atlas log analisis scripts\n", "\n", "This notebook is intended to plot and analyze logs from ripe-atlas probes.\n", "\n", "The *log_url* varible is the url that appears in \"Download URL Preview\" in the \"Download logs\" section of the \"Built-Ins\" tab of the probe information page. In json format.\n", "\n", "![image.png](data:image/png;base64,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)\n" ], "metadata": { "id": "-HuvJmkTuNhJ" } }, { "cell_type": "markdown", "source": [ "## Ping logs\n" ], "metadata": { "id": "chjHbCl9uniJ" } }, { "cell_type": "code", "source": [ "# @title Load file - use the input on the right to place the url with PING logs and run this box.\n", "\n", "import requests\n", "import time\n", "from io import StringIO\n", "import pandas as pd\n", "\n", "dataframes = []\n", "\n", "log_url = \"https://atlas.ripe.net/api/v2/measurements/1001/results/?probe_ids=1008517&start=1725494400&stop=1725839999&format=json\" #@param {type:\"string\"}\n", "data = requests.get(log_url)\n", "ping_df = pd.read_json(StringIO(data.text))\n", "df_sorted = ping_df.sort_values('timestamp', ascending=True)\n", "dataframes.append(df_sorted)\n", "ping_df.head()\n", "\n", "\n", "log_url_1 = \"\" #@param {type:\"string\"}\n", "if log_url_1 != \"\":\n", " time.sleep(2)\n", " data = requests.get(log_url_1)\n", " ping_df = pd.read_json(StringIO(data.text))\n", " df_sorted = ping_df.sort_values('timestamp', ascending=True)\n", " dataframes.append(df_sorted)\n", "\n", "log_url_2 = \"\" #@param {type:\"string\"}\n", "if log_url_2 != \"\":\n", " time.sleep(5)\n", " data = requests.get(log_url_2)\n", " ping_df = pd.read_json(StringIO(data.text))\n", " df_sorted = ping_df.sort_values('timestamp', ascending=True)\n", " dataframes.append(df_sorted)\n", "\n", "# concatenate dataframes\n", "ping_df = pd.concat(dataframes)\n", "\n", "\n", "\n" ], "metadata": { "id": "B7GSvu-nx-md", "cellView": "form" }, "execution_count": 16, "outputs": [] }, { "cell_type": "code", "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 542 }, "id": "EQZ847IkuGQq", "outputId": "122830cc-bffc-4a48-ec9c-6636ff91febf", "cellView": "form" }, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ] }, "metadata": {} } ], "source": [ "# @title Graph time vs avg RTT\n", "from io import StringIO\n", "import pandas as pd\n", "import plotly.express as px\n", "\n", "\n", "# supress future warning triggerd by protly\n", "import warnings\n", "warnings.simplefilter(\"ignore\", category=FutureWarning)\n", "\n", "\"\"\"\n", "# sort daset by timestam\n", "df_sorted = ping_df.sort_values('timestamp', ascending=True)\n", "df_sorted_1 = ping_df_1.sort_values('timestamp', ascending=True)\n", "\n", "# Concatenate the two dataframes\n", "df_concat = pd.concat([df_sorted, df_sorted_1])\n", "\"\"\"\n", "\n", "# Assuming df_sorted is your dataframe with 'timestamp' and 'avg' columns\n", "title = \"Probe {} to: \".format(df_sorted['prb_id'][0])\n", "for n in ping_df['msm_id'].unique():\n", " dst_addr = ping_df[ping_df['msm_id']== n]['dst_addr'][0]\n", " title += \"<{}={}> \".format(n, dst_addr)\n", "\n", "fig = px.line(ping_df, x='timestamp', y='min', color='msm_id', title=title)\n", "\n", "# Customize hover data\n", "fig.update_traces(hovertemplate=\"Date: %{x}
Avg: %{y}\")\n", "\n", "fig.show()\n", "\n" ] }, { "cell_type": "markdown", "source": [ "## HTTP Logs\n", "\n", "These logs have connections made to http servers of the ripe infrastructure, the connections are made in ~1 hour intervals." ], "metadata": { "id": "b7AHoAnfAxev" } }, { "cell_type": "code", "source": [ "# @title Load file - use the input on the right to place the url with HTTP logs and run this box.\n", "\n", "import requests\n", "\n", "log_url = \"https://atlas.ripe.net/api/v2/measurements/12027/results/?probe_ids=1008517&start=1725494400&stop=1725839999&format=json\" #@param {type:\"string\"}\n", "data = requests.get(log_url)\n", "http_df = pd.read_json(StringIO(data.text))\n", "http_df.head()\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 380 }, "collapsed": true, "cellView": "form", "id": "NzIZ8sqfwtP3", "outputId": "6f9a1059-3dcd-4369-b1ce-72b09e89c9f7" }, "execution_count": 6, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ " fw mver lts result \\\n", "0 5080 2.6.2 816873 [{'header': ['X-Client-IP: 186.118.170.139', '... \n", "1 5080 2.6.2 820474 [{'header': ['X-Client-IP: 186.118.170.139', '... \n", "2 5080 2.6.2 824073 [{'header': ['X-Client-IP: 186.118.170.139', '... \n", "3 5080 2.6.2 827672 [{'header': ['X-Client-IP: 186.118.170.139', '... \n", "4 5080 2.6.2 831271 [{'header': ['X-Client-IP: 186.118.170.139', '... \n", "\n", " uri msm_id prb_id timestamp msm_name \\\n", "0 http://193.0.6.141 12027 1008517 2024-09-05 00:29:17 HTTPGet \n", "1 http://193.0.6.141 12027 1008517 2024-09-05 01:29:19 HTTPGet \n", "2 http://193.0.6.141 12027 1008517 2024-09-05 02:29:17 HTTPGet \n", "3 http://193.0.6.141 12027 1008517 2024-09-05 03:29:17 HTTPGet \n", "4 http://193.0.6.141 12027 1008517 2024-09-05 04:29:16 HTTPGet \n", "\n", " from type stored_timestamp \n", "0 186.118.170.139 http 1725496234 \n", "1 186.118.170.139 http 1725499842 \n", "2 186.118.170.139 http 1725503448 \n", "3 186.118.170.139 http 1725507032 \n", "4 186.118.170.139 http 1725510630 " ], "text/html": [ "\n", "
\n", "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
fwmverltsresulturimsm_idprb_idtimestampmsm_namefromtypestored_timestamp
050802.6.2816873[{'header': ['X-Client-IP: 186.118.170.139', '...http://193.0.6.1411202710085172024-09-05 00:29:17HTTPGet186.118.170.139http1725496234
150802.6.2820474[{'header': ['X-Client-IP: 186.118.170.139', '...http://193.0.6.1411202710085172024-09-05 01:29:19HTTPGet186.118.170.139http1725499842
250802.6.2824073[{'header': ['X-Client-IP: 186.118.170.139', '...http://193.0.6.1411202710085172024-09-05 02:29:17HTTPGet186.118.170.139http1725503448
350802.6.2827672[{'header': ['X-Client-IP: 186.118.170.139', '...http://193.0.6.1411202710085172024-09-05 03:29:17HTTPGet186.118.170.139http1725507032
450802.6.2831271[{'header': ['X-Client-IP: 186.118.170.139', '...http://193.0.6.1411202710085172024-09-05 04:29:16HTTPGet186.118.170.139http1725510630
\n", "
\n", "
\n", "\n", "
\n", " \n", "\n", " \n", "\n", " \n", "
\n", "\n", "\n", "
\n", " \n", "\n", "\n", "\n", " \n", "
\n", "\n", "
\n", "
\n" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "http_df", "summary": "{\n \"name\": \"http_df\",\n \"rows\": 94,\n \"fields\": [\n {\n \"column\": \"fw\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 5080,\n \"max\": 5080,\n \"num_unique_values\": 1,\n \"samples\": [\n 5080\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"mver\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.6.2\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"lts\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 98206,\n \"min\": 816873,\n \"max\": 1151672,\n \"num_unique_values\": 94,\n \"samples\": [\n 960874\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"result\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"uri\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"http://193.0.6.141\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"msm_id\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 12027,\n \"max\": 12027,\n \"num_unique_values\": 1,\n \"samples\": [\n 12027\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"prb_id\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 1008517,\n \"max\": 1008517,\n \"num_unique_values\": 1,\n \"samples\": [\n 1008517\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"timestamp\",\n \"properties\": {\n \"dtype\": \"date\",\n \"min\": \"2024-09-05 00:29:17\",\n \"max\": \"2024-09-08 21:29:17\",\n \"num_unique_values\": 94,\n \"samples\": [\n \"2024-09-06 16:29:18\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"msm_name\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"HTTPGet\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"from\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"186.118.170.139\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"type\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"http\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"stored_timestamp\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 98203,\n \"min\": 1725496234,\n \"max\": 1725831047,\n \"num_unique_values\": 94,\n \"samples\": [\n 1725640232\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" } }, "metadata": {}, "execution_count": 6 } ] }, { "cell_type": "code", "source": [ "# @title Table: Disconected time intervals (shows time intervals where the time difference is more than 1.1 hours)\n", "from io import StringIO\n", "import pandas as pd\n", "\n", "# sort daset by timestam\n", "df_sorted = http_df.sort_values('timestamp', ascending=True)\n", "\n", "# Calculate time differences in hours\n", "time_diffs_in_hours = df_sorted['timestamp'].diff() / pd.Timedelta(hours=1)\n", "\n", "# Create a DataFrame with disconnection information\n", "disconnection_df = pd.DataFrame({\n", " 'Start Time': df_sorted['timestamp'].shift(1),\n", " 'End Time': df_sorted['timestamp'],\n", " 'Disconnection Time (hours)': time_diffs_in_hours\n", "}).dropna()\n", "\n", "# Filter for disconnections longer than an hour\n", "disconnection_df = disconnection_df[disconnection_df['Disconnection Time (hours)'] > 1.1]\n", "\n", "# Format the timestamps for better readability (optional)\n", "disconnection_df['Start Time'] = disconnection_df['Start Time'].dt.strftime('%Y-%m-%d %H:%M')\n", "disconnection_df['End Time'] = disconnection_df['End Time'].dt.strftime('%Y-%m-%d %H:%M')\n", "\n", "# Get the start and end time of the entire dataset\n", "dataset_start_time = df_sorted['timestamp'].min().strftime('%Y-%m-%d %H:%M')\n", "dataset_end_time = df_sorted['timestamp'].max().strftime('%Y-%m-%d %H:%M')\n", "\n", "# Get the probe id\n", "probe_id = df_sorted['prb_id'][0]\n", "\n", "# Get uri\n", "uri = df_sorted['uri'][0]\n", "\n", "# Print the dataset time range\n", "print(f\"Time Range for probe {probe_id}: {dataset_start_time} to {dataset_end_time} for {uri}\")\n", "\n", "# Display the table\n", "disconnection_df\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 107 }, "id": "MscEo-9nA7no", "outputId": "9a867e24-2bfa-4a6c-c976-666846de3a9f", "cellView": "form" }, "execution_count": 7, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Time Range for probe 1008517: 2024-09-05 00:29 to 2024-09-08 21:29 for http://193.0.6.141\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ "Empty DataFrame\n", "Columns: [Start Time, End Time, Disconnection Time (hours)]\n", "Index: []" ], "text/html": [ "\n", "
\n", "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Start TimeEnd TimeDisconnection Time (hours)
\n", "
\n", "
\n", "\n", "
\n", " \n", "\n", " \n", "\n", " \n", "
\n", "\n", "\n", "
\n", " \n", " \n", " \n", "
\n", "\n", "
\n", "
\n" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "disconnection_df", "repr_error": "Out of range float values are not JSON compliant: nan" } }, "metadata": {}, "execution_count": 7 } ] }, { "cell_type": "markdown", "source": [ "## Traceroute logs" ], "metadata": { "id": "2ejtv-WoX0z2" } }, { "cell_type": "code", "source": [ "# @title Load file - use the input on the right to place the url with TRACEROUTE logs and run this box.\n", "import pandas as pd\n", "from io import StringIO\n", "import requests\n", "\n", "log_url = \"https://atlas.ripe.net/api/v2/measurements/5001/results/?probe_ids=1008517&start=1725494400&stop=1725839999&format=json\" #@param {type:\"string\"}\n", "data = requests.get(log_url)\n", "tr_df = pd.read_json(StringIO(data.text))\n", "tr_df.head()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 400 }, "collapsed": true, "id": "_roHS3syX5P2", "outputId": "8e390b4e-35ab-4a9f-a3d1-e1d8e8903ef9" }, "execution_count": 8, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ " fw mver lts endtime dst_name dst_addr src_addr \\\n", "0 5080 2.6.2 815268 1725494553 193.0.14.129 193.0.14.129 192.168.3.134 \n", "1 5080 2.6.2 817066 1725496351 193.0.14.129 193.0.14.129 192.168.3.134 \n", "2 5080 2.6.2 818863 1725498148 193.0.14.129 193.0.14.129 192.168.3.134 \n", "3 5080 2.6.2 820668 1725499953 193.0.14.129 193.0.14.129 192.168.3.134 \n", "4 5080 2.6.2 822465 1725501750 193.0.14.129 193.0.14.129 192.168.3.134 \n", "\n", " proto af size paris_id \\\n", "0 UDP 4 40 8 \n", "1 UDP 4 40 9 \n", "2 UDP 4 40 10 \n", "3 UDP 4 40 11 \n", "4 UDP 4 40 12 \n", "\n", " result \\\n", "0 [{'hop': 1, 'result': [{'from': '192.168.3.1',... \n", "1 [{'hop': 1, 'result': [{'from': '192.168.3.1',... \n", "2 [{'hop': 1, 'result': [{'from': '192.168.3.1',... \n", "3 [{'hop': 1, 'result': [{'from': '192.168.3.1',... \n", "4 [{'hop': 1, 'result': [{'from': '192.168.3.1',... \n", "\n", " destination_ip_responded msm_id prb_id timestamp msm_name \\\n", "0 True 5001 1008517 2024-09-05 00:02:20 Traceroute \n", "1 True 5001 1008517 2024-09-05 00:32:18 Traceroute \n", "2 True 5001 1008517 2024-09-05 01:02:17 Traceroute \n", "3 True 5001 1008517 2024-09-05 01:32:20 Traceroute \n", "4 True 5001 1008517 2024-09-05 02:02:18 Traceroute \n", "\n", " from type stored_timestamp \n", "0 186.118.170.139 traceroute 1725494612 \n", "1 186.118.170.139 traceroute 1725496423 \n", "2 186.118.170.139 traceroute 1725498212 \n", "3 186.118.170.139 traceroute 1725500029 \n", "4 186.118.170.139 traceroute 1725501816 " ], "text/html": [ "\n", "
\n", "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
fwmverltsendtimedst_namedst_addrsrc_addrprotoafsizeparis_idresultdestination_ip_respondedmsm_idprb_idtimestampmsm_namefromtypestored_timestamp
050802.6.28152681725494553193.0.14.129193.0.14.129192.168.3.134UDP4408[{'hop': 1, 'result': [{'from': '192.168.3.1',...True500110085172024-09-05 00:02:20Traceroute186.118.170.139traceroute1725494612
150802.6.28170661725496351193.0.14.129193.0.14.129192.168.3.134UDP4409[{'hop': 1, 'result': [{'from': '192.168.3.1',...True500110085172024-09-05 00:32:18Traceroute186.118.170.139traceroute1725496423
250802.6.28188631725498148193.0.14.129193.0.14.129192.168.3.134UDP44010[{'hop': 1, 'result': [{'from': '192.168.3.1',...True500110085172024-09-05 01:02:17Traceroute186.118.170.139traceroute1725498212
350802.6.28206681725499953193.0.14.129193.0.14.129192.168.3.134UDP44011[{'hop': 1, 'result': [{'from': '192.168.3.1',...True500110085172024-09-05 01:32:20Traceroute186.118.170.139traceroute1725500029
450802.6.28224651725501750193.0.14.129193.0.14.129192.168.3.134UDP44012[{'hop': 1, 'result': [{'from': '192.168.3.1',...True500110085172024-09-05 02:02:18Traceroute186.118.170.139traceroute1725501816
\n", "
\n", "
\n", "\n", "
\n", " \n", "\n", " \n", "\n", " \n", "
\n", "\n", "\n", "
\n", " \n", "\n", "\n", "\n", " \n", "
\n", "\n", "
\n", "
\n" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "dataframe", "variable_name": "tr_df", "summary": "{\n \"name\": \"tr_df\",\n \"rows\": 189,\n \"fields\": [\n {\n \"column\": \"fw\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 5080,\n \"max\": 5080,\n \"num_unique_values\": 1,\n \"samples\": [\n 5080\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"mver\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.6.2\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"lts\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 98466,\n \"min\": 815268,\n \"max\": 1153665,\n \"num_unique_values\": 189,\n \"samples\": [\n 1146465\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"endtime\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 98466,\n \"min\": 1725494553,\n \"max\": 1725832950,\n \"num_unique_values\": 189,\n \"samples\": [\n 1725825750\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"dst_name\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"193.0.14.129\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"dst_addr\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"193.0.14.129\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"src_addr\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"192.168.3.134\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"proto\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"UDP\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"af\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 4,\n \"max\": 4,\n \"num_unique_values\": 1,\n \"samples\": [\n 4\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"size\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 40,\n \"max\": 40,\n \"num_unique_values\": 1,\n \"samples\": [\n 40\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"paris_id\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 4,\n \"min\": 0,\n \"max\": 15,\n \"num_unique_values\": 16,\n \"samples\": [\n 8\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"result\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"destination_ip_responded\",\n \"properties\": {\n \"dtype\": \"boolean\",\n \"num_unique_values\": 2,\n \"samples\": [\n false\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"msm_id\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 5001,\n \"max\": 5001,\n \"num_unique_values\": 1,\n \"samples\": [\n 5001\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"prb_id\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 1008517,\n \"max\": 1008517,\n \"num_unique_values\": 1,\n \"samples\": [\n 1008517\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"timestamp\",\n \"properties\": {\n \"dtype\": \"date\",\n \"min\": \"2024-09-05 00:02:20\",\n \"max\": \"2024-09-08 22:02:18\",\n \"num_unique_values\": 189,\n \"samples\": [\n \"2024-09-08 20:02:17\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"msm_name\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"Traceroute\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"from\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"186.118.170.139\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"type\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"traceroute\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"stored_timestamp\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 98463,\n \"min\": 1725494612,\n \"max\": 1725833014,\n \"num_unique_values\": 189,\n \"samples\": [\n 1725825819\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" } }, "metadata": {}, "execution_count": 8 } ] }, { "source": [ "# @title Graph of number of hops for each measurement on a time line\n", "\n", "import plotly.graph_objects as go\n", "import pandas as pd\n", "\n", "# Calculate the hop count for each traceroute\n", "tr_df['hop_count'] = tr_df['result'].apply(len)\n", "\n", "# Sort the dataframe by timestamp\n", "tr_df = tr_df.sort_values('timestamp', ascending=True)\n", "tr_df = tr_df.reset_index(drop=True)\n", "\n", "# Calculate hop count\n", "tr_df['hop_count'] = tr_df['result'].apply(len)\n", "\n", "# Create hover text\n", "result_index = 0\n", "\n", "def hover_text(row):\n", " global result_index\n", " text = \"index: {}
\".format(result_index)\n", " text += \"{}

\".format(row['timestamp'])\n", " result = row['result']\n", " for n in result:\n", " text += \"{}: \".format(n['hop'])\n", " from_found = False\n", " if 'error' in n:\n", " text += \"Error: {}
\".format(n['error'])\n", " continue\n", " for m in n['result']:\n", " if 'from' in m:\n", " text += m['from'] + \"
\"\n", " from_found = True\n", " break\n", " if not from_found:\n", " text += \"*
\"\n", " result_index += 1\n", " return text\n", "\n", "tr_df['hover_text'] = tr_df.apply(hover_text, axis=1)\n", "\n", "# Create the plot\n", "fig = go.Figure(data=go.Scatter(x=tr_df['timestamp'],\n", " y=tr_df['hop_count'],\n", " mode='lines+markers',\n", " text=tr_df['hover_text'],\n", " hoverinfo='text'))\n", "\n", "# Customize the plot (optional)\n", "fig.update_layout(title='Traceroute Hop Count Over Time',\n", " xaxis_title='Time',\n", " yaxis_title='Hop Count')\n", "\n", "# Display the plot\n", "fig.show()" ], "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 542 }, "id": "A-v6hYwHa_KI", "outputId": "f90c53ae-4083-4e07-aa4e-b5a54af98db2", "cellView": "form" }, "execution_count": 9, "outputs": [ { "output_type": "display_data", "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ] }, "metadata": {} } ] }, { "cell_type": "code", "source": [ "# @title Table: Compare two traceroute measurements using the indexes shown on last graph\n", "\n", "index1 = \"57\" # @param {type:'string'}\n", "index2 = \"55\" # @param {type:'string'}\n", "\n", "# Select the first two rows and reset their indices\n", "df1 = tr_df.iloc[[index1]].reset_index(drop=True)\n", "df2 = tr_df.iloc[[index2]].reset_index(drop=True)\n", "\n", "# Reorder columns to place 'result' last\n", "new_column_order = [col for col in df1.columns if col != 'result'] + ['result']\n", "df1 = df1[new_column_order]\n", "df2 = df2[new_column_order]\n", "\n", "# Compare the DataFrames and format the output\n", "comparison = df1.compare(df2, align_axis='rows', keep_shape=True, keep_equal=True)\n", "\n", "# # Custom styling function to pretty-print 'result' column\n", "# def pretty_print_result(val):\n", "# s = \"\"\n", "# for n in val:\n", "# s += \"{}:   \".format(n['hop'])\n", "# for m in n['result']:\n", "# if 'from' in m:\n", "# s += \" {}\".format(m['from'])\n", "# else:\n", "# s += \" *\"\n", "# s += \"
\"\n", "# return s\n", "\n", "# # Pre-process the 'result' column to pretty-print JSON\n", "# comparison['result'] = comparison['result'].apply(pretty_print_result)\n", "\n", "# Transpose for better readability (optional)\n", "comparison_transposed = comparison.transpose()\n", "\n", "# Rename the columns for clarity\n", "comparison_transposed.columns = [\"index :{}\".format(index1), \"index :{}\".format(index2)]\n", "\n", "# Apply the styling, including custom formatting for 'result'\n", "styled_comparison = comparison_transposed.style.set_properties(**{'text-align': 'left'}) \\\n", " .set_table_styles([dict(selector='th', props=[('text-align', 'left')])])\n", "\n", "# Display the styled comparison\n", "display(styled_comparison)\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "cellView": "form", "id": "zP7NnqUhyG5K", "outputId": "4be30414-186e-43ef-d63c-e4027df057b9" }, "execution_count": 11, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "" ], "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 index :57index :55
fw50805080
mver2.6.22.6.2
lts917872914264
endtime17255971571725593549
dst_name193.0.14.129193.0.14.129
dst_addr193.0.14.129193.0.14.129
src_addr192.168.3.134192.168.3.134
protoUDPUDP
af44
size4040
paris_id115
destination_ip_respondedFalseTrue
msm_id50015001
prb_id10085171008517
timestamp2024-09-06 04:32:192024-09-06 03:32:17
msm_nameTracerouteTraceroute
from186.118.170.139186.118.170.139
typetraceroutetraceroute
stored_timestamp17255973391725593625
hop_count814
hover_textindex: 57
2024-09-06 04:32:19

1: 192.168.3.1
2: 186.118.170.137
3: *
4: *
5: *
6: *
7: *
255: *
index: 55
2024-09-06 03:32:17

1: 192.168.3.1
2: 186.118.170.137
3: 10.7.79.201
4: *
5: *
6: 94.142.118.231
7: 213.140.36.27
8: 213.140.36.28
9: 5.53.5.92
10: 84.16.6.43
11: *
12: 189.89.141.38
13: 187.44.146.78
14: 193.0.14.129
result[{'hop': 1, 'result': [{'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.323}, {'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.23800000000000002}, {'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.215}]}, {'hop': 2, 'result': [{'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.366}, {'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.161}, {'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.385}]}, {'hop': 3, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 4, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 5, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 6, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 7, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 255, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}][{'hop': 1, 'result': [{'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.319}, {'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.20800000000000002}, {'from': '192.168.3.1', 'ttl': 64, 'size': 68, 'rtt': 0.223}]}, {'hop': 2, 'result': [{'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.3860000000000001}, {'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.089}, {'from': '186.118.170.137', 'ttl': 254, 'size': 28, 'rtt': 1.166}]}, {'hop': 3, 'result': [{'from': '10.7.79.201', 'ttl': 62, 'size': 68, 'rtt': 0.454}, {'from': '10.7.79.201', 'ttl': 62, 'size': 68, 'rtt': 0.435}, {'from': '10.7.79.201', 'ttl': 62, 'size': 68, 'rtt': 0.41500000000000004}]}, {'hop': 4, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 5, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 6, 'result': [{'from': '94.142.118.231', 'ttl': 248, 'size': 68, 'rtt': 22.238, 'itos': 128}, {'from': '94.142.118.231', 'ttl': 248, 'size': 68, 'rtt': 22.008, 'itos': 128}, {'from': '94.142.118.231', 'ttl': 248, 'size': 68, 'rtt': 22.057, 'itos': 128}]}, {'hop': 7, 'result': [{'from': '213.140.36.27', 'ttl': 245, 'size': 140, 'rtt': 152.803, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}, {'from': '213.140.36.27', 'ttl': 245, 'size': 140, 'rtt': 152.462, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}, {'from': '213.140.36.27', 'ttl': 245, 'size': 140, 'rtt': 152.462, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}]}, {'hop': 8, 'result': [{'from': '213.140.36.28', 'ttl': 246, 'size': 140, 'rtt': 152.165, 'ittl': 2, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}, {'from': '213.140.36.28', 'ttl': 246, 'size': 140, 'rtt': 152.415, 'ittl': 2, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}, {'from': '213.140.36.28', 'ttl': 246, 'size': 140, 'rtt': 152.3, 'ittl': 2, 'itos': 128, 'icmpext': {'version': 0, 'rfc4884': 1, 'obj': [{'class': 0, 'type': 0}]}}]}, {'hop': 9, 'result': [{'from': '5.53.5.92', 'ttl': 246, 'size': 28, 'rtt': 152.32, 'itos': 128}, {'from': '5.53.5.92', 'ttl': 246, 'size': 28, 'rtt': 152.649, 'itos': 128}, {'from': '5.53.5.92', 'ttl': 246, 'size': 28, 'rtt': 152.049, 'itos': 128}]}, {'hop': 10, 'result': [{'from': '84.16.6.43', 'ttl': 246, 'size': 28, 'rtt': 152.566}, {'from': '84.16.6.43', 'ttl': 246, 'size': 28, 'rtt': 156.21}, {'from': '84.16.6.43', 'ttl': 246, 'size': 28, 'rtt': 152.373}]}, {'hop': 11, 'result': [{'x': '*'}, {'x': '*'}, {'x': '*'}]}, {'hop': 12, 'result': [{'from': '189.89.141.38', 'ttl': 244, 'size': 28, 'rtt': 173.841}, {'from': '189.89.141.38', 'ttl': 244, 'size': 28, 'rtt': 166.825}, {'from': '189.89.141.38', 'ttl': 244, 'size': 28, 'rtt': 168.018}]}, {'hop': 13, 'result': [{'from': '187.44.146.78', 'ttl': 52, 'size': 68, 'rtt': 152.42}, {'from': '187.44.146.78', 'ttl': 52, 'size': 68, 'rtt': 152.296}, {'from': '187.44.146.78', 'ttl': 52, 'size': 68, 'rtt': 152.291}]}, {'hop': 14, 'result': [{'from': '193.0.14.129', 'ttl': 51, 'size': 68, 'rtt': 153.028}, {'from': '193.0.14.129', 'ttl': 51, 'size': 68, 'rtt': 152.999}, {'from': '193.0.14.129', 'ttl': 51, 'size': 68, 'rtt': 152.976}]}]
\n" ] }, "metadata": {} } ] } ] }