Apacheログってのは大量のデータ件数になるわけで
要件によってはOSファイルのままの扱いでは日が暮れるようなことになってしまいます。
んじゃ、DBに入れてしまいましょうということで
ApacheログをPythonで処理して直接PostgreSQLに格納します。
う〜ん、これ便利。
ApacheログのParseはこの辺を参考に。
http://graphistry.github.io/pygraphistry/html/Tutorial%20Part%202%20(Apache%20Logs).html
http://blog.mmast.net/read-apache-access-log-pandas
ちょこっとカスタムして書くとこんな感じ。
import pandas as pd
from urllib.parse import unquote
# ファイルの場所
url = '/tmp/access.log'
# column定義
fields = ['host', 'identity', 'user', 'time_part1', 'time_part2', 'cmd_path_proto',
'http_code', 'response_bytes', 'referer', 'user_agent', 'unknown']
# データ読み込み
data = pd.read_csv(url, sep=' ', header=None, names=fields, na_values=['-'])
# 時刻列parse
time = data.time_part1 + data.time_part2
time_trimmed = time.map(lambda s: s.strip('[]').split('+')[0])
data['time'] = pd.to_datetime(time_trimmed, format='%d/%b/%Y:%H:%M:%S')
# コマンド列parse
data['command'], data['path'], data['protocol'] = zip(*data['cmd_path_proto'].str.split().tolist())
data['path'] = data['path'].map(lambda s: unquote(s))
# 不要列削除
data1 = data.drop(['time_part1', 'time_part2', 'cmd_path_proto'], axis=1)
# 空データ削除
data2 = data1.dropna(axis=1, how='all')
# data frameまで完成
data2
host http_code response_bytes referer user_agent time command path protocol
0 156.141.48.220 200 86 /item/software/2656 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT ... 2018-01-25 17:33:51 GET /category/games HTTP/1.1
1 104.36.145.163 200 115 /search/?c=Cameras+Electronics Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/... 2018-01-25 17:33:51 GET /item/cameras/3857 HTTP/1.1
2 164.24.157.185 200 76 /item/electronics/1257 Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/... 2018-01-25 17:33:51 POST /search/?c=Health HTTP/1.1
3 76.195.39.107 200 40 /search/?c=Software Mozilla/5.0 (compatible; Googlebot/2.1; +http:... 2018-01-25 17:33:51 GET /item/software/1528 HTTP/1.1
4 224.138.43.127 200 63 /category/games Mozilla/5.0 (compatible; MSIE 9.0; Windows NT ... 2018-01-25 17:33:51 GET /category/software HTTP/1.1
5 20.54.131.78 200 90 /search/?c=Networking+Books Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1... 2018-01-25 17:33:51 GET /item/networking/3138 HTTP/1.1
6 92.213.33.71 200 128 /category/cameras Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; r... 2018-01-25 17:33:51 GET /item/sports/1164 HTTP/1.1
7 104.66.93.199 200 93 NaN Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/... 2018-01-25 17:33:51 GET /category/software HTTP/1.1
8 20.36.49.62 200 62 NaN Mozilla/5.0 (compatible; Googlebot/2.1; +http:... 2018-01-25 17:33:51 GET /item/networking/1592 HTTP/1.1
9 84.198.67.176 200 72 /item/software/4560 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKi... 2018-01-25 17:33:51 GET /category/games HTTP/1.1
10 224.180.221.171 200 56 /item/jewelry/3885 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; r... 2018-01-25 17:33:51 GET /category/cameras HTTP/1.1
11 164.177.38.116 200 114 NaN Mozilla/5.0 (compatible; Googlebot/2.1; +http:... 2018-01-25 17:33:51 GET /category/sports?from=10 HTTP/1.1
データベースインスタンスの注意点はこの辺を。
https://www.marketechlabo.com/import-access-log-to-postgres/
やってみて気づいた点
1.テーブル名はすべてを大文字では作らない。一部大文字はOK。
全部大文字だとテーブルをダブルクオートで加工必要がある→いまいちすぎる仕様。
2.動作ログの表示
デフォルトだとログ表示しないのでオプションで設定する。動きが見えて楽しい。
engine = create_engine(url, echo=True)
3.psycopg2がないと怒られる
コード上ではつかっていないのだけどその奥で呼んでいる模様。
インストールしましょう。この辺のつながりはまた別途調査。
import pandas as pd
from sqlalchemy import create_engine
#import psycopg2
#url = 'postgresql://postgres@localhost:5432/web_analysys?charset=utf8'
url = 'postgresql://postgres@localhost:5432/web_analysys'
engine = create_engine(url, echo=True)
data2.to_sql('IHS_log', engine, if_exists='replace', index=False)
テーブル格納、きれいにできてます!
host | http_code | response_bytes | referer | user_agent | time | command | path | protocol |
---|---|---|---|---|---|---|---|---|
156.141.48.220 | 200 | 86 | /item/software/2656 | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB7.2; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C) | 2018-01-25 17:33:51 | GET | /category/games | HTTP/1.1 |
104.36.145.163 | 200 | 115 | /search/?c=Cameras+Electronics | Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 | 2018-01-25 17:33:51 | GET | /item/cameras/3857 | HTTP/1.1 |
164.24.157.185 | 200 | 76 | /item/electronics/1257 | Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 | 2018-01-25 17:33:51 | POST | /search/?c=Health | HTTP/1.1 |
76.195.39.107 | 200 | 40 | /search/?c=Software | Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) | 2018-01-25 17:33:51 | GET | /item/software/1528 | HTTP/1.1 |
ログをみるとDataFrameから自動的にテーブルCREATEしてます。
ほう。。。
web_analysys=# \d IHS_log
Table "public.ihs_log"
Column | Type | Modifiers
----------------+-----------------------------+-----------
host | text |
http_code | bigint |
response_bytes | bigint |
referer | text |
user_agent | text |
time | timestamp without time zone |
command | text |
path | text |
protocol | text |
↓ログから拾うと。。。
CREATE TABLE "IHS_log" (
host TEXT,
http_code BIGINT,
response_bytes BIGINT,
referer TEXT,
user_agent TEXT,
time TIMESTAMP WITHOUT TIME ZONE,
command TEXT,
path TEXT,
protocol TEXT
)