はじめに
少し前の話ですが、「Apacheのアクセスログを何かに活用できないかしら」との話を社内で貰たので、勉強がてらデータ分析してみた内容を備忘録的に書きます。
データ分析・Apache・記事投稿、どれをとっても初心者のため拙い文章ですが、ご容赦くださいませ。
アクセスログの分析
モジュールのインポート
今回は下記のモジュールを使ってます。
# データの処理
import pandas as pd
import numpy as np
# グラフ表示
import plotly.express as px
from plotly import tools
import seaborn as sns
import matplotlib.pyplot as plt
# その他
import datetime,time
import ipaddress
データの読み込み
ログファイルをとりあえず全部読み込みました。
col_names = ['ip','c1','c2', 'datetime', 'timezone', 'request', 'status', 'size', 'referer', 'user_agent']
df = pd.read_csv("データのパス", sep=' ', dtype=str, names=col_names)
df[:1]
データの整形
IP version
IPv4とIPv6を分別したいのでipaddressモジュールを使って新しいカラムにIP Versionのデータを追加します。
def ipcheck(x):
return ipaddress.ip_address(x.iloc[0]).version
df["ip_ver"] = np.nan
df["ip_ver"] = df.apply(ipcheck, axis=1)
端末情報
強引ですが、UserAgentからOSを判別してデータを追加します。
def device(x):
ua = x.iloc[9]
dev = "etc"
if "iPhone" in ua:
dev="iPhone"
elif "Android" in ua:
dev="Android"
elif "Win" in ua:
dev="Windows"
elif "Mac" in ua:
dev="Macintosh"
elif "Linux" in ua:
dev="Linux"
return dev
df["device"] = np.nan
df["device"] = df.apply(device, axis=1)
日時
読み込んだ時に日時とタイムゾーンが分かれてしまったので、いい感じにPythonのdatetime型にして格納します。
#datetime,timezoneをpythonのdatetime型に変換して挿入
datetime_str = df.datetime + df.timezone
time_trimmed = datetime_str.map(lambda s: s.strip('[]').split('+')[0])
df['datetime'] = pd.to_datetime(time_trimmed, format='%d/%b/%Y:%H:%M:%S')
ヒートマップ用に時間だけのデータも追加します。(わざわざ追加しなくてもよかったかもですが…)
def hourcheck(x):
dt = x.iloc[3]
return dt.strftime('%H')
df["hour"] = np.nan
df["hour"] = df.apply(hourcheck, axis=1)
不要なデータの削除
カラム名をc1,c2と置いているところは「クライアントの識別子」と「認証ユーザー名」のようですが、今回のログでは特に情報無いため消します。タイムゾーンももう必要ないので消します。
del df['c1']
del df['c2']
del df['timezone']
円グラフで可視化してみる
まずplotly.expressを使って可視化してみます。
IPv4/IPv6の比率
数の多いstatus:200に絞ってIPv4/IPv6の比率を可視化してみます。
df_ip = df.pivot_table(index="ip_ver",columns="status",aggfunc='size',fill_value=0)
ip_fig_title = 'IPv4/v6比率'
ip_fig = px.pie(data_frame=df_ip,
values='200',
names=df_ip.index,
hover_name=df_ip.index,
labels={'ip_ver':'IP version','200':'count'})
ip_fig.update_layout(xaxis={'categoryorder':'category ascending'}, title=ip_fig_title)
ip_fig.update_traces(textinfo='percent+label')
ip_fig.show()
端末種別の割合
こちらもstatus:200に絞って端末種別の割合を表示してみます。
df_device = df.pivot_table(index="device",columns="status",aggfunc='size',fill_value=0)
ip_fig_title = 'IPv4/v6比率'
ip_fig = px.pie(data_frame=df_ip,
values='200',
names=df_ip.index,
hover_name=df_ip.index,
labels={'ip_ver':'IP version','200':'count'})
ip_fig.update_layout(xaxis={'categoryorder':'category ascending'}, title=ip_fig_title)
ip_fig.update_traces(textinfo='percent+label')
ip_fig.show()
Windows、iPhone、Androidで9割越えの結果に。
やはりAndroidよりiPhoneユーザの方が多いですね。
IPv4/IPv6それぞれの端末種別の割合
今度はIPv4/IPv6それぞれで端末種別の割合を見てみます。
df_device_ip = df.pivot_table(index="device",columns="ip_ver",aggfunc='size',fill_value=0)
device_fig_ip_title = '端末種別比率(v4)'
device_fig_ip = px.pie(data_frame=df_device_ip,
values=4,
names=df_device_ip.index,
hover_name=df_device_ip.index,
labels={'device':'Device',4:'count'})
device_fig_ip.update_layout(xaxis={'categoryorder':'category ascending'}, title=device_fig_ip_title)
device_fig_ip.update_traces(textinfo='percent+label')
device_fig_ip.show()
device_fig_ip6_title = '端末種別比率(v6)'
device_fig_ip6 = px.pie(data_frame=df_device_ip,
values=6,
names=df_device_ip.index,
hover_name=df_device_ip.index,
labels={'device':'Device',6:'count'})
device_fig_ip6.update_layout(xaxis={'categoryorder':'category ascending'}, title=device_fig_ip6_title)
device_fig_ip6.update_traces(textinfo='percent+label')
device_fig_ip6.show()
若干ではありますがIPv4はPCが多く、逆にIPv6ではモバイル端末が多いのが見えてきました。
今回は何で差が出るかまでは調べてないですが、ちょっと気になりますね。
ヒートマップで可視化してみる
次はseabornを使ってヒートマップを見てみます。
時間帯ごとのアクセス数
- IPv4/IPV6
figure = sns.heatmap(pd.crosstab(df['ip_ver'], df['hour']), fmt="1.1f", lw=0.7, cmap='Blues')
- 端末種別ごと
figure = sns.heatmap(pd.crosstab(df['device'], df['hour']), fmt="1.1f", lw=0.7, cmap='Blues')
ヒートマップもなんとなく特徴が出ました。
・昼間はPCから(社内のアクセスも多いのかな?)
・夜の20-21時は帰宅中の電車でスマホから見てるのかなー
とか思いながらヒートマップを見てみると意外と面白かったです。
参考にしたページ
余談
勉強がてらデータ分析をしてみたところ、若干ですが特徴が見えてきて、いろいろ想像も膨らんで面白かったです。
今後の展開でアクセスログの活用方法として、サービスの障害情報を発信するページへのアクセスログを分析できないかという案が出ました。「アクセス増加」⇒「サービス使えていない人が増加」⇒「サービス障害の可能性」となり、アラームを検知しないサイレント障害の気づきになるのでは…!? と思っていましたが、弊社WEBサイトの更改がありApacheではなくなってしまったので、そちらはまた別途取り組んでいけたらなと思っています。。。