Last active
December 18, 2017 11:52
-
-
Save yuta-imai/a0ac981598216ec1f014a4b8bb14bbda to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Preparation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os\n", | |
"import requests\n", | |
"import time\n", | |
"from datetime import datetime\n", | |
"from pandas import *\n", | |
"from pylab import *\n", | |
"%matplotlib inline\n", | |
"import matplotlib.pyplot as plt\n", | |
"plt.style.use('ggplot') " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"operator_id = os.environ['operatorId']\n", | |
"credentials = pandas.io.json.dumps({\n", | |
" \"authKeyId\":os.environ[\"authKeyId\"],\n", | |
" \"authKey\":os.environ['authKey']\n", | |
"})\n", | |
"\n", | |
"api_url_base = \"https://api.soracom.io/v1\"" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from datetime import datetime\n", | |
"\n", | |
"# API認証トークンを取得するための関数\n", | |
"def auth():\n", | |
" url = api_url_base + \"/auth\"\n", | |
" r = requests.post(url, data=credentials, headers={'Content-Type': 'application/json'})\n", | |
" return r.json()\n", | |
"\n", | |
"# SIMごとの利用状況を日別データとして取得するための関数\n", | |
"def getAirStatsByDay(days):\n", | |
" url = api_url_base + \"/stats/air/operators/\" + operator_id + \"/export\"\n", | |
" api_credentials = auth()\n", | |
"\n", | |
" headers = {\n", | |
" \"Content-Type\":\"application/json\",\n", | |
" \"X-Soracom-API-Key\":api_credentials[\"apiKey\"],\n", | |
" \"X-Soracom-Token\":api_credentials[\"token\"]\n", | |
" }\n", | |
"\n", | |
" params = {\n", | |
" \"export_mode\":\"sync\"\n", | |
" }\n", | |
"\n", | |
" now = int(time.time())\n", | |
" body = {\n", | |
" \"from\": now - 86400*days,\n", | |
" \"to\": now,\n", | |
" \"period\":\"day\"\n", | |
" }\n", | |
"\n", | |
" f = requests.post(url,data=pandas.io.json.dumps(body),params=params,headers=headers)\n", | |
" f = f.json()\n", | |
" traffic = pandas.read_csv(f['url'])\n", | |
" traffic['dates'] = traffic['date'].apply(lambda x: datetime.strptime(str(x),'%Y%m%d'))\n", | |
" traffic.index = traffic['dates']\n", | |
" return traffic\n", | |
"\n", | |
"# エラーログを取得するための関数\n", | |
"def getLogs(days):\n", | |
" url = api_url_base + \"/logs\"\n", | |
" api_credentials = auth()\n", | |
" headers = {\n", | |
" \"Content-Type\":\"application/json\",\n", | |
" \"X-Soracom-API-Key\":api_credentials[\"apiKey\"],\n", | |
" \"X-Soracom-Token\":api_credentials[\"token\"]\n", | |
" }\n", | |
" \n", | |
" now = int(time.time())\n", | |
" params = {\n", | |
" \"from\": now - 86400*days,\n", | |
" \"to\":now,\n", | |
" \"limit\":10000\n", | |
" }\n", | |
" \n", | |
" f = requests.get(url,params=params,headers=headers)\n", | |
" logs = f.json()\n", | |
" for log in logs:\n", | |
" log['time'] = datetime.fromtimestamp(log['time']/1000)\n", | |
" log['message'] = log['body']['message']\n", | |
"\n", | |
" logs = DataFrame(data=logs)\n", | |
" logs.index = logs['time']\n", | |
" return logs" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Traffic analysis" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"過去7日分の、当該SORACOMアカウントのすべてのSIMの日毎の利用状況をDataFrameとして取得します" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"traffic = getAirStatsByDay(7)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"まずは速度クラスごとにダウンロード通信の利用量合計を可視化してみましょう" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"traffic['downloadMB'] = traffic['downloadByteSizeTotal'].apply(lambda x: x/1024/1024)\n", | |
"traffic.groupby(['dates','type'])['downloadMB'].sum().unstack().plot(figsize=(20,10))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"次に利用量Top10の回線をグラフ化してみます。同時に「downloadMB」という名前で、すべての回線の平均値もグラフに一緒にプロットします。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"topN = traffic.groupby(['imsi'])['downloadMB'].sum().head(10).index.tolist()\n", | |
"\n", | |
"fig, ax = plt.subplots()\n", | |
"traffic[traffic['imsi'].isin(topN)].groupby(['dates','imsi'])['downloadMB'].sum().unstack().plot(figsize=(20,10),ax=ax)\n", | |
"traffic.groupby(['dates'])['downloadMB'].mean().plot(figsize=(20,10),ax=ax,legend=True)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"回線IDではなく、SIMの名前をキーにグラフを描画しなおします。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"topN = traffic.groupby(['imsi'])['downloadMB'].sum().head(10).index.tolist()\n", | |
"\n", | |
"fig, ax = plt.subplots()\n", | |
"traffic[traffic['imsi'].isin(topN)].groupby(['dates','name'])['downloadMB'].sum().unstack().plot(figsize=(20,10),ax=ax)\n", | |
"traffic.groupby(['dates'])['downloadMB'].mean().plot(figsize=(20,10),ax=ax,legend=True)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Error analysis" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"今後はエラーログの分析を行います。先程と同様にまずは過去7日分のデータをDataFrameに読み込みます。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"logs = getLogs(7)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"そしてまずはエラーメッセージ毎に回数をカウントしてみます。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"logs.groupby(['message'])['message'].count().plot(kind='bar',figsize=(20,10))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"次に「エラーメッセージx回線ID」でグラフを描画しなおします。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"logs.groupby(['message','resourceId'])['message'].count().plot(kind='bar',figsize=(20,10))" | |
] | |
} | |
], | |
"metadata": { | |
"anaconda-cloud": {}, | |
"kernelspec": { | |
"display_name": "Python [conda root]", | |
"language": "python", | |
"name": "conda-root-py" | |
}, | |
"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.5.2" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment