nginx + Stackdriver Logging + BigQuery で構造化ロギングを扱う

GCE 上の nginx のログを Stackdriver + BigQuery + Google Data Studio で可視化する大まかな流れはわかった。

しかし、現在のログの取り扱い方だと、URL や HttpStatus が BigQuery 上で textPayload というカラムに文字列として入ってしまっているため、DataStudio で詳細な分析がやりにくい。

BigQuery のテーブルに UA や IP アドレスのカラムが個別に作成され、そこにデータが入るようにするため、構造化ロギングの設定を行う。

Nginx

Stackdriver Logging は Json 形式でログを保管しているため、 Nginx 側でも出力するように修正する。

nginx の log_format を確認する。

vi /etc/nginx/nginx.conf

デフォルトの設定。

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main

このフォーマットで出力されるログの形式を確認する。

tail /var/log/nginx/access.log

以下となる。

193.169.52.39 - - [08/Sep/2018:19:12:50 +0900] "GET / HTTP/1.1" 200 28783 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.132 Safari/537.36" "-"

このログを Stackdriver で構造化ロギングを行う。

Stackdriver Logging

Stackdriver で構造化ロギングを行うためには、「–structured」を付けてインストールする必要がある。

sudo bash install-logging-agent.sh --structured

Stackdriver Logging Agent の設定を変更する。

vi /etc/google-fluentd/config.d/nginx.conf

以下のような source ディレクティブを作成。format が nginx とデフォルトで入っている。

<source>
  @type tail
  format nginx
  path /var/log/nginx/access.log
  pos_file /var/lib/google-fluentd/pos/nginx-access.pos
  read_from_head true
  tag nginx-access
</source>

google-fluentd 自体のログを確認してみる。

tail /var/log/google-fluentd/google-fluentd.log

すると pattern not match というログが出力されている。フォーマットが合ってない。

2018-09-10 23:10:04 +0900 [warn]: #0 pattern not match: "126.19.107.49 - - [10/Sep/2018:23:10:04 +0900] \"GET / HTTP/2.0\" 200 28762 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\" \"-\""

本家 fluentd のサイトを参考に、format を修正する。

<source>
  @type tail
  # format nginx
  format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)"(?:\s+(?<http_x_forwarded_for>[^ ]+))?)?$/time_format %d/%b/%Y:%H:%M:%S %z
  path /var/log/nginx/access.log
  pos_file /var/lib/google-fluentd/pos/nginx-access.pos
  read_from_head true
  tag nginx-access
</source>

これで GCP コンソール上の Stackdriver Logging 画面を確認すると、jsonPayload 内で key/value として認識されるようになっている。

このログを BigQuery にいれよう。

BigQuery

Stackdriver Logging のログを BigQuery へログをエクスポートする。

Stackdriver Logging 画面より、「エクスポートの作成」を選択し、以下を入力。

  • シンク名 : nginx_access
  • シンクサービス : BigQuery
  • シンクのエクスポート先 : nginx_stackdriver

BigQuery の画面を確認するとデータセットとテーブルが作成されている。

さらには、前回でできていなかった JsonPayload 内のデータが個別にカラムに保存されている。

Google Data Studioでもこのカラムのデータを可視化する。

参考

構造化ロギング

コメント

タイトルとURLをコピーしました