Skip to content

Instantly share code, notes, and snippets.

@yuta-imai
Last active December 18, 2017 11:52
Show Gist options
  • Save yuta-imai/a0ac981598216ec1f014a4b8bb14bbda to your computer and use it in GitHub Desktop.
Save yuta-imai/a0ac981598216ec1f014a4b8bb14bbda to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"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