WEBサーバーのログ
WEBサーバーのログについて、サーバーごとにログパーサーがあって、それで表示するのが手っ取り早い。
WEBサーバーのログ以外に、PCやネットワーク機器のログと結合させてトレースしたい場合など、標準的なログ解析ツールがあれば便利かなと思いPythonでのログ処理を実装してみる。
IISとApacheのログファイルをJupyter notebookでpandasに読み込ませることを想定。
IISのログ
W3C形式で出力する場合、出力フィールドが変更可能、かつフィールド名がコメント行と区別なく書かれているので、独自で設定する必要がある。
以下は、w3cで出力される全フィールドなので、出力していないフィールドは削除する。
#フィールド名の設定
log_field_names = ['date', 'time', 's-sitename', 's-computernam','s-ip', 'cs-method', 'cs-uri-stem', 'cs-uri-query', 's-port', 'cs-username', 'c-ip', 'cs(User-Agent)','cs(Cookie)', 'cs(Referer)','cs-host', 'sc-status', 'sc-substatus', 'sc-win32-status','sc-bytes', 'cs-bytes', 'time-taken']
ログファイルを指定して、sep=' 'で空白区切りをしていして、comment='#'でコメント行を指定して、ames=log_field_namesでフィールド名を指定すればデータフレームに収まる。
iis_log = pd.read_csv('u_ex210910.log', sep=' ', comment='#', names=log_field_names)
日付と時間の型を変換しておく。
#日付・時間への変換
iis_log['date'] = pd.to_datetime(iis_log ['date'])
iis_log['time'] = pd.to_datetime(iis_log ['time'])
Apacheのログ
Apacheのログは、日付の形式が[20/Oct/2020:09:08:31 +0900]となっており、pd.to_datetimeで変換できないので、関数を使って変換する。
こちらを参考にさせて頂きました。
pytzがtimezoneの変換をしてくれるので、以下の関数を準備。
from datetime import datetime
import pytzdef parse_datetime(x):
dt = datetime.strptime(x[1:-7], '%d/%b/%Y:%H:%M:%S')
dt_tz = int(x[-6:-3])*60+int(x[-3:-1])
return dt.replace(tzinfo=pytz.FixedOffset(dt_tz))
区切り文字のsepの指定が複雑です。
convertersに関数を指定して、日付に変換かけています。
apache_log = pd.read_csv(
'access.log',
sep=r'\s(?=(?:[^"]*"[^"]*")*[^"]*$)(?![^\[]*\])',
na_values='-',
header=None,
usecols=[0, 3, 4, 5, 6],
names=['ip', 'time', 'request', 'status', 'size'],
converters={'time': parse_datetime,
'status': int,
'size': int})
次の課題
ここまでくれば、データの集計などが簡単に出来る。その結果をグラフを使ったデータの可視化などに挑戦してみたいと思います。
Pythonで可視化と言えば、SeabornやMatplotlibが有名ですが、plotlyと呼ばれるフレームワークで、より表現力の高いインタラクティブなグラフが作成できるようです。
つ・づ・く