Symfoware

Symfowareについての考察blog

PythonでApacheログの解析(apache-log-parser)

PythonでApacheログの解析を行おうと思ったのですが、ログの正規表現探して、
パースして・・・というのが面倒くさい。

なにかいいライブラリないかなと思い探したら、apache-log-parserを見つけました。
https://pypi.python.org/pypi/apache-log-parser/

インストールして使ってみます。


インストール



インストールはeasy_installで行いました。


$ sudo easy_install apache-log-parser





使ってみる



とりあえず使ってみます。
小さなライブラリなので、ちゃんとした解説ページはない模様。
ソースとテストコードを見ながら使い方を調べました。


http://httpd.apache.org/docs/2.2/ja/logs.html
こちらにあるログの内容を解析してみます。

サンプルのソースはこんな感じ。


  1. # -*- coding:utf-8 -*-
  2. import apache_log_parser
  3. # 解析したいapacheログ
  4. sample = '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"'
  5. # パーサーを作成
  6. # 指定するのは、httpd.confに記載しているLogFormatの書式
  7. parser = apache_log_parser.make_parser('%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"')
  8. # 解析実行
  9. log_data = parser(sample)
  10. # 解析結果はdictになっている
  11. # 必要な情報を出力
  12. print 'status:' + log_data['status']
  13. print 'request_first_line:' + log_data['request_first_line']
  14. print 'request_url:' + log_data['request_url']
  15. print 'request_header_user_agent:' + log_data['request_header_user_agent']




実行結果は以下の通り。


$ python sample.py
status:200
request_first_line:GET /apache_pb.gif HTTP/1.0
request_url:/apache_pb.gif
request_header_user_agent:Mozilla/4.08 [en] (Win98; I ;Nav)









LogFormatとの対応表



LogFormatで指定したキーワードと、dictに変換された時のキーの対応はこんなかんじです。
※ソースから抽出したので誤っているかも。

Apacheログの書式はこちら。
http://httpd.apache.org/docs/2.2/ja/mod/mod_log_config.html

フォーマット文字列dictのキー説明
%%-パーセント記号
%aremote_ipリモート IP アドレス
%Alocal_ipローカル IP アドレス
%Bresponse_bytesレスポンスのバイト数。HTTP ヘッダは除く。
%bresponse_bytes_clfレスポンスのバイト数。HTTP ヘッダは除く。CLF 書式。 すなわち、1 バイトも送られなかったときは 0 ではなく、 '-' になる
%{Foobar}Ccookie_サーバに送られたリクエスト中のクッキー Foobar の値
%Dtime_usリクエストを処理するのにかかった時間、マイクロ秒単位
%{FOOBAR}eenv環境変数 FOOBAR の内容
%ffilenameファイル名
%hremote_hostリモートホスト
%Hprotocolリクエストプロトコル
%lremote_logname(identd からもし提供されていれば) リモートログ名。 これは mod_ident がサーバに存在して、 IdentityCheck ディレクティブが On に設定されていない限り、 - になります。
%mmethodリクエストメソッド
%{Foobar}nnote_他のモジュールからのメモ Foobar の内容
%{Foobar}oresponse_header_応答の Foobar: ヘッダの内容
%pserver_portリクエストを扱っているサーバの正式なポート
%Ppidリクエストを扱った子プロセスのプロセス ID
%{format}Ppid_リクエストを扱ったワーカーのプロセス ID かスレッド ID。 format として有効な値は pid, tid, hextid です。hextid を使うには APR 1.2.0 以降が必要です。
%qquery_string問い合せ文字列 (存在する場合は前に ? が追加される。 そうでない場合は空文字列)
%rrequest_first_lineリクエストの最初の行
%sstatusステータス。内部でリダイレクトされたリクエストは、元々の リクエストのステータス
%ttime_recievedリクエストを受付けた時刻。 CLF の時刻の書式 (標準の英語の書式)
%{format}ttime_format で与えられた書式による時刻。format は strftime (3) の 書式である必要がある。(地域化されている可能性がある)
%Ttime_sリクエストを扱うのにかかった時間、秒単位
%uremote_userリモートユーザ (認証によるもの。ステータス (%s) が 401 のときは意味がないものである可能性がある)
%Uurl_pathリクエストされた URL パス。クエリ文字列は含まない
%vserver_nameリクエストを扱っているサーバの正式な ServerName
%Vserver_name2UseCanonicalName の設定によるサーバ名
%Xconn_status応答が完了したときの接続ステータス
%Ibytes_rxリクエストとヘッダを含む、受け取ったバイト数。 0 にはならない。 これを使用するためには mod_logio が必要
%Obytes_txヘッダを含む、送信したバイト数。0 にはならない。 これを使用するためには mod_logio が必要
%{Referer}irequest_header_refererリファラー
%{User-agent}irequest_header_user_agentユーザーエージェント




特殊な置換



datetimeオブジェクトに変換したアクセス時間。
リクエストのメソッドやURLを分解。
ユーザーエージェントからOSやブラウザを推測した値も取得できるようです。


  1. # -*- coding:utf-8 -*-
  2. import apache_log_parser
  3. # 解析したいapacheログ
  4. sample = '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"'
  5. # パーサーを作成
  6. # 指定するのは、httpd.confに記載しているLogFormatの書式
  7. parser = apache_log_parser.make_parser('%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"')
  8. # 解析実行
  9. log_data = parser(sample)
  10. # 解析結果はdictになっている
  11. # 必要な情報を出力
  12. # 日付
  13. print log_data['time_recieved']
  14. # オブジェクトに変換した日付
  15. print log_data['time_recieved_datetimeobj']
  16. # isoフォーマット
  17. print log_data['time_recieved_isoformat']
  18. print '-' * 10
  19. # リクエスト
  20. print log_data['request_first_line']
  21. # リクエストメソッド
  22. print log_data['request_method']
  23. # リクエストURL
  24. print log_data['request_url']
  25. # httpバージョン
  26. print log_data['request_http_ver']
  27. print '-' * 10
  28. # ユーザーエージェント
  29. print log_data['request_header_user_agent']
  30. # ブラウザ、os、モバイル端末であるかなど
  31. print log_data['request_header_user_agent__browser__family']
  32. print log_data['request_header_user_agent__browser__version_string']
  33. print log_data['request_header_user_agent__os__family']
  34. print log_data['request_header_user_agent__os__version_string']
  35. print log_data['request_header_user_agent__os__family']
  36. print log_data['request_header_user_agent__is_mobile']




実行結果。


$ python sample.py
[10/Oct/2000:13:55:36 -0700]
2000-10-10 13:55:36
2000-10-10T13:55:36
----------
GET /apache_pb.gif HTTP/1.0
GET
/apache_pb.gif
1.0
----------
Mozilla/4.08 [en] (Win98; I ;Nav)
Other

Windows 98

Windows 98
False






%tオプション



ちゃんと試せていないのですが、apacheでは

%{format}t

で、出力する日付のフォーマットを指定できるようです。
指定する書式は、strftime (3) に従うとのこと。

http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/strftime.3.html

これも指定すれば解析してくれるはず。
※ここは備忘録として。
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2014/06/02(月) 23:13:53|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<FreeBSD 10 + samba 4で、Windowsからeveryoneアクセス可能な共有フォルダを作成 | ホーム | matplotlibで、出力するグラフの画像サイズを指定する>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1422-176271dd
この記事にトラックバックする(FC2ブログユーザー)