Embulk をつかって検索ログを抽出する

みんなのウェディング 高井です。

先日、当社で開発した embulk-filter-query_string という Embulk のフィルタープラグインをオープンソースとしてリリースしました。今回はその Embulk のプラグインをつかって、検索ログを抽出する方法を紹介します。


Embulk のユースケースとメリット

たとえば、下記のような一般的なアクセスログがあったとします。このログは、ダミーのログを生成するスクリプトで生成したもので、よく利用される Combined Log 形式のものです。

200.198.91.50 - - [09/Mar/2016:06:34:01 +0900] "POST /search/?c=Software+Games HTTP/1.1" 200 101 "/category/toys" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"
100.183.116.182 - - [09/Mar/2016:06:34:17 +0900] "POST /search/?c=Books HTTP/1.1" 200 110 "/item/software/71" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; YTB730; GTB7.2; EasyBits GO v1.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)"

ここから、最初の行のような検索ページへのアクセスログから検索クエリーを取り出し、分析用データベースに収めるにはどうしたらよいのでしょうか。

みんなのウェディングでは、このようなニーズを満たすために Embulk を利用しています。Embulk は、データソースからデータを読み込み、それを加工したうえで、データベースなどにロードするためのツールです。

今まで、そういったニーズのためには、個別にバッチプログラムを作成していました。そうすると、開発の手間がかかるうえに、汎用性に乏しくなってしまうという欠点がありました。

それに対して、 Embulk は、ほとんどのケースでプログラムを開発することなく、設定のみで要件を満たすことができます。また、 Embulk はプラグインアーキテクチャを採用しています。ですから、設定だけでは対応しきれない場合であっても、プラグインを開発することによって、個別の要求に対応させることもできます。

データソースの読み込み

Embulk に Web サーバーのログをデータソースとして読み込ませるためには、 apache-custom-log プラグインを利用するのが簡単です。プラグインのインストールは、 embulk コマンドを利用して行ないます。

$ embulk gem install embulk-parser-apache-custom-log

それから、 log ディレクトリに保存されている Combined Log 形式のテキストファイルを読み込むには、下記のようにYAML形式の設定ファイルを記述します。

in:
  type: file
  path_prefix: log/
  parser:
    type: apache-custom-log
    format: "%h %l %u %t \"%m %r %H\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
out:
  type: stdout

上記を seed.yml というファイルに保存し、 Embulk の preview コマンドを実行すると、ログファイルがどのように解釈されるかが出力されます。 Embulk の出力先にデータベースを選択していると、表示されている形式でカラムにデータがロードされるというわけです。

$ embulk preview -G seed.yml
2016-01-01 00:00:00.000 +0900: Embulk v0.8.6
...
*************************** 1 ***************************
              remote-host (   string) : 200.198.91.50
          remote-log-name (   string) :
             request-user (   string) :
             request-time (timestamp) : 2016-03-08 21:34:01 UTC
           request-method (   string) : POST
             request-line (   string) : /search/?c=Software+Games
         request-protocol (   string) : HTTP/1.1
          response-status (     long) : 200
           response-bytes (     long) : 101
   request-header-Referer (   string) : /category/toys
request-header-User-agent (   string) : Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

query_string フィルター

さて、この request-line にあるクエリー文字列を抽出して、ひとつのカラムにロードしたい場合はどのようにすればいいでしょうか。そのために、 embulk-filter-query_string プラグインを利用することができます。

プラグインのインストールは、先ほどと同様に embulk コマンドを利用して行ないます。

$ embulk gem install embulk-filter-query_string

また、設定ファイルに、フィルターの設定を追加します。

in:
  type: file
  path_prefix: log/
  parser:
    type: apache-custom-log
    format: "%h %l %u %t \"%m %r %H\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
filters:
  - type: query_string
    query_string_column_name: request-line
    expanded_columns:
      - {name: c, type: string}
out:
  type: stdout

設定のうち、 query_string_column_name は、対象となるカラムです。このカラムにあるクエリー文字列をパースし、 expand_columns で指定されているクエリー文字列のフィールドを独立したカラムとして展開します。

ここまでできたら、また preview コマンドを実行してみましょう。 c というカラムにクエリー文字列がロードされているのが確認できます。

$ embulk preview -G seed.yml
2016-01-01 00:00:00.000 +0900: Embulk v0.8.6
...
*************************** 1 ***************************
              remote-host (   string) : 200.198.91.50
          remote-log-name (   string) :
             request-user (   string) :
             request-time (timestamp) : 2016-03-08 21:34:01 UTC
           request-method (   string) : POST
                        c (   string) : Software Games
         request-protocol (   string) : HTTP/1.1
          response-status (     long) : 200
           response-bytes (     long) : 101
   request-header-Referer (   string) : /category/toys
request-header-User-agent (   string) : Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

実際に運用するにあたっては、 embulk-filter-column プラグインを利用して不要なカラムを落としたり、 embulk-filter-rename プラグインを利用してカラム名を変更したりすると便利でしょう。

また、 embulk-output-redshift プラグインによってデータを RedShift に投入したり、 embulk-output-elasticsearch プラグインで Elasticsearch に投入したりすることもできます。

まとめ

Embulk の embulk-filter-query_string プラグインの紹介をしました。Embulk を利用すると、設定だけでデータを加工したうえで、色々なデータベースなどにロードすることができます。ぜひ興味のある方は、embulk-filter-query_string プラグインを触ってみてください。 また、 GitHub のイシューなどでフィードバックをいただけると嬉しいです。

余談となりますが、みんなのウェディングでは、オープンソースソフトウェアポリシーを定めて、エンジニアが業務時間に開発したソフトウェアについて、オープンソースソフトウェアとして発表したり貢献したりできるようにしています。みんなのウェディングで公開しているオープンソースソフトウェアについては、 GitHub をご覧ください。


みんなのウェディングは、ソフトウェアエンジニアを募集中です。興味のある方は、 Wantedly からご応募ください。もちろん、社内の人間と面識があるのでしたら、直接にご連絡いただいてもかまいません。