🙆

Vector + KibanaでNginxとRailsのログを一括で見れるようにする

に公開

はじめに

こんにちは。スマサテで開発を担当している佐治です。スマサテでは昨年秋に長期的に取り組みたい技術的課題を皆で話し合い、それらの課題を解決していくためのワーキンググループを結成しました。
今回はワーキンググループの1つである、ログ収集ワーキンググループで行ったVectorに関するトピックです。

Vectorとは?

Vector.dev(ベクター)とは、Rustで書かれたオープンソースのオブザーバビリティデータパイプラインツールです。ログ、メトリクス、トレースなどのオブザーバビリティデータを収集、加工・整形し、多様なデータストアに送信ができます。

ログワーキンググループの目的

今回私たちはVector.devを使うことで、複数のRailsアプリケーションサーバのログやNginxのログ、スロークエリのログなどを一箇所に集約し、Elasticsearch & Kibanaで簡単に閲覧できるようにすることを目指しました。
ログを一箇所に集約することで、日々起きるバグなどの調査の効率を向上させようという算段です!

詳しい全体構成などは別途投稿予定のログワーキンググループの記事(近日公開予定)をご覧ください。

Railsログと対になるNginxのログを見つけやすくする

ここからが本題です。

Vector + Elasticsearch & Kibanaの設定をして、RailsやNginxのログを読めるようにしましたが、 運用をしていく中で「Railsのログを見ている時に同一ユーザの直前のNginxのログを一緒に見たい」という要望が出てきました。リクエストの詳細をスムーズに把握するためには対応したい機能です。
上記課題を解決するために、ログの共通フィールドを用意して絞り込みをすることで 、関連するログを見ることができるようにします。今回は共通フィールドとしてrequest_idを使いました。

Nginx側の設定

Railsには既にrequest_idのログがあるので、今回はNginxに新たにrequest_idフィールドを追加して、Railsとの繋ぎ込みをしていきます。

Nginx.conf

末尾にrequest_id="$request_id"を追加します。

log_format main '$remote_addr - $remote_user .... '
                ....
                '.... request_id="$request_id"';

Vectorでの構造化パースを容易にするため、明示的に request_id= というキー形式で出力するようにしています。

default.conf の一部(locationブロック内)

proxy_set_header Host $http_host;
proxy_set_header X-Request-Id $request_id; # ここの行を追加

このヘッダーを追加することで、NginxがRailsアプリケーションに対してリクエストIDを転送できるようになります。これにより、Vectorで収集したNginxのアクセスログとRailsのアプリケーションログを同一のリクエストIDで紐付けることが可能になり、リクエストの流れを追跡しやすくなります。

Vector側の設定

次にVector側でのNginxのパース処理を修正します。

vector.yaml

  parse_nginx_log:
    type: remap
    inputs: [parse_router.nginx]
    source: |
      .message = string!(.message)

      # request_id の抽出
      request_id_captures, request_id_err = parse_regex(.message, r'request_id="(?P<request_id>[a-fA-F0-9]{32})"')
      if request_id_captures != null {
        .request_id = request_id_captures.request_id
      }

Vector側では、remapトランスフォームを使用してNginxのログメッセージからrequest_idを抽出します。parse_regex関数により、ログ内のrequest_id="xxx"形式の値を正規表現でキャプチャし、構造化フィールドとして.request_idに格納します。
エラーハンドリングも組み込まれており、request_idが見つからない場合でもパイプライン全体が停止することなく、他のログ処理を継続できます。この設定により、KibanaでNginxログとRailsログを同一のrequest_idでフィルタリング・集約することが可能になり、リクエストのトレーシングが容易になります。

適用後のイメージ

Nginxのログの一部です。以下のように末尾にrequest_idが付与されるようになりました。

xx.xx.xx.xx - - [22/Aug/2025:11:07:37 +0900] "GET xxxxx HTTP/1.1" 200 xxxxx "https://xxxxx"
.... request_id="e1b37baa45ca83668c59ce85d3195dac"

Kibanaの画面ではrequest_id: e1b37baa45ca83668c59ce85d3195dacで絞り込みを行うことで、Nginxと対になるRailsのログを一緒に閲覧することができるようになっています。

Nginxのログ:
Nginxのログ

Railsのログ:
Railsのログ

おわりに

今回は、NginxとRailsのログをrequest_idで紐付ける方法を紹介しました。この改善により、エラー調査やパフォーマンス分析の際に、リクエストの全体像を素早く把握できるようになりました。
ログ収集基盤は地味ながらも開発効率に大きく影響する重要な要素です。今後もワーキンググループでは、開発者体験の向上につながる改善を継続していく予定です。

スマサテではエンジニアを募集しています。一緒にチームで技術的課題に取り組みたい方は、ぜひWantedlyのページをご覧ください。
https://www.wantedly.com/projects/2099580

スマサテ Tech Blog

Discussion