Grafana、Grafana Loki、PromtailでNginxのアクセスログを可視化する最強のダッシュボードを作る

はじめに

NginxのアクセスログをPromtailとGrafana Lokiで集約してGrafanaで可視化してみました。
とてもかっこいい最強のダッシュボードができたので、手順などを記録しておこうと思います。
f:id:sublimer:20210914205539p:plain

環境

ソフトウェア

  • Grafana v8.1.3
  • Grafana Loki main-64e2a36
  • Promtail 2.2.1
  • Nginx 1.21.1

サービス

  • Cloudflare

アクセスログのフォーマットを設定する

nginx.confでアクセスログのフォーマットを設定します。
形式はなんでもいいですが、今回はLTSV形式で設定しました。
以下のようなフォーマットを設定しておき、access_logの設定でltsvを使うように指定します。

log_format ltsv 'time:$time_iso8601\t'
                'remote_addr:$remote_addr\t'
                'remote_port:$realip_remote_port\t'
                'country:$http_cf_ipcountry\t'
                'request_method:$request_method\t'
                'request_uri:$request_uri\t'
                'server_protocol:$server_protocol\t'
                'status:$status\t'
                'body_bytes_sent:$body_bytes_sent\t'
                'referer:$http_referer\t'
                'forwardedfor:$http_x_forwarded_for\t'
                'request_time:$request_time\t'
                'useragent:$http_user_agent';

CDNとしてCloudflareを使うと、$http_cf_ipcountryという変数にアクセス元のクライアントの国コードが入ってきます。(要設定)
support.cloudflare.com

Grafana Lokiのインストール

詳細は割愛します。
Dockerイメージを動かしたり、バイナリファイルをダウンロードして、Systemdのサービスとして動かせばOKです。
私はDockerイメージを使いました。
Grafana Lokiはデフォルトでは3100/tcpのポートを使うので、ファイアウォールの設定を変更してこのポートを開けておきましょう。

Promtailの設定

インストール方法は割愛します。
バイナリファイルをダウンロードして、Systemdのサービスとして動かせばOKです。
Promtailの設定はほとんどデフォルトのままでOKです。
clientsの設定で、Grafana Lokiの接続先の設定をしてください。
scrape_configsの設定では、読み込むログファイルの指定をします。
Nginxのアクセスログを読み込んでパースする設定を抜粋するとこんな感じです。

- job_name: nginx
  static_configs:
  - targets:
    - localhost
    labels:
      job: access_log
      __path__: /var/log/nginx/*_access.log
  pipeline_stages:
  - match:
      selector: '{job="access_log"}'
      stages:
      - regex:
          expression: '^time:(?P<time>.*)\tremote_addr:(?P<remote_addr>.*)\tremote_port:(?P<remote_port>.*)\tcountry:(?P<country>.*)\trequest_method:(?P<request_method>.*)\trequest_uri:(?P<request_uri>.*)\tserver_protocol:(?P<server_protocol>.*)\tstatus:(?P<status>.*)\tbody_bytes_sent:(?P<body_bytes_send>.*)\treferer:(?P<referer>.*)\tforwardedfor:(?P<forwardedfor>.*)\trequest_time:(?P<request_time>.*)\tuseragent:(?P<useragent>.*)$'
      - labels:
          time:
          remote_addr:
          remote_port:
          country:
          request_method:
          request_uri:
          server_protocol:
          status:
          body_bytes_send:
          referer:
          forwardedfor:
          request_time:
          useragent:

Grafanaの設定

データソースとしてLokiの設定をします。

クライアントの国の情報をマップ上に表示する

Geomapのパネルのダッシュボードに追加します。
クエリの入力欄に、以下のようなクエリを追加します。

sum (count_over_time({filename="access_log"} | country != "" [$__interval])) by (country)

filenameの値は適宜置き換えてください。
また、Legendの入力欄には{{country}}と入力してください。
その後、パネルの設定欄でData LayerのLocationをLookupに設定してください。
これで、アクセス元のクライアントの国の情報がマップ上に表示されます。
f:id:sublimer:20210915222628p:plain

ログデータを任意のフォーマットで表示する

Logsのパネルをダッシュボードに追加します。
クエリの入力欄には、以下のようなクエリを追加します。

{filename="access_log"} | line_format "{{.request_method}} {{.request_uri}} {{.server_protocol}} {{.status}}"

これで、GET /hoge HTTP/2.0 200のようなフォーマットでログが表示されます。
line_formatの指定を変えることで、任意のフォーマットに変更できます。
f:id:sublimer:20210915222655p:plain

レスポンスを返すまでの処理時間が長いエンドポイントを表示する

「ログデータを任意のフォーマットで表示する」で追加したパネルをコピーし、編集画面の「Transform」のタブで以下のように設定します。

  • Labels to fields
  • Sort by
    • request_time
  • Organize fields
    • 表示させたい値以外を非表示に

次に、パネルの設定欄の「Add field override」をクリックし、「Fields with name」で「request_time」を選択します。
そして、「Add override property」をクリックし、以下の項目を追加・設定します。

  • Thresholds
  • Cell display mode
    • Color text

f:id:sublimer:20210915222307p:plain
これで、どのリクエストに時間がかかっているのかを可視化できます。
f:id:sublimer:20210915222804p:plain

ステータスごとのリクエスト数を表示する

Bar chartのパネルを追加し、クエリの入力欄に以下のクエリを追加します。

sum (count_over_time({filename="access_log"} | status != "" [$__interval])) by (status)

次に「Query options」で「Max data points」を1に設定します。
これでHTTPのステータスごとのリクエスト数を可視化できます。
f:id:sublimer:20210915223422p:plain

おわりに

かっこいいダッシュボードを作れると無限に眺められるのでとても良いです。