🥽

OpenTelemetry Collector x Grafana lokiでNginxアクセスログを収集・可視化

2024/12/21に公開

OpenTelemetry Advent Calendar 2024の21日目を担当させていただきました

https://qiita.com/advent-calendar/2024/opentelemetry

Nginxのアクセスログを効率的に収集・可視化するために、OpenTelemetry CollectorとGrafana Lokiを組み合わせる方法をご紹介します。

環境の準備

  • Nginx: Webサーバーとして動作し、アクセスログを生成します。
  • OpenTelemetry Collector: ログデータを収集し、処理・転送を行います。
  • Grafana Loki: ログの保存とクエリを担当するログ集約システムです。
  • Grafana: Lokiからログデータを取得し、ダッシュボードで可視化します。

手順

1. Nginxのログフォーマット設定

Nginxのnginx.confで、アクセスログのフォーマットを設定します。以下は、LTSV形式での設定例です。

log_format ltsv "time:$time_local"
                "\thost:$remote_addr"
                "\tforwardedfor:$http_x_forwarded_for"
                "\treq:$request"
                "\tstatus:$status"
                "\tmethod:$request_method"
                "\turi:$request_uri"
                "\tsize:$body_bytes_sent"
                "\treferer:$http_referer"
                "\tua:$http_user_agent"
                "\treqtime:$request_time"
                "\tcache:$upstream_http_x_cache"
                "\truntime:$upstream_http_x_runtime"
                "\tapptime:$upstream_response_time"
                "\tvhost:$host";

この設定により、アクセスログがLTSV形式で出力されます。

2. OpenTelemetry Collectorの設定

OpenTelemetry Collectorをインストールし、以下のように設定します。

Receivers

filelogレシーバーを使用して、Nginxのアクセスログを監視します。includeフィールドでログファイルのパスを指定し、operatorsで正規表現パーサーを設定して、ログの各フィールドを抽出します。

receivers:
  filelog:
    include: [/var/log/nginx/access.log]
    operators:
      - type: regex_parser
        regex: '^time:(?P<time>[^\t]+)\thost:(?P<host>[^\t]+)\tforwardedfor:(?P<forwardedfor>[^\t]+)\treq:(?P<req>[^\t]+)\tstatus:(?P<status>\d+)\tmethod:(?P<method>[^\t]+)\turi:(?P<uri>[^\t]+)\tsize:(?P<size>\d+)\treferer:(?P<referer>[^\t]*)\tua:(?P<ua>[^\t]*)\treqtime:(?P<reqtime>[^\t]*)\tcache:(?P<cache>[^\t]*)\truntime:(?P<runtime>[^\t]*)\tapptime:(?P<apptime>[^\t]*)\tvhost:(?P<vhost>[^\t]+)$'

Processors

resourceプロセッサーで、ログにサービス名の属性を追加し、batchプロセッサーでログをバッチ処理して効率的に送信します。

processors:
  resource:
    attributes:
      - key: service.name
        value: "nginx"
        action: upsert
  batch:
    send_batch_size: 1000
    timeout: 10s

Exporters

otlphttpエクスポーターを使用して、ログデータをGrafana Lokiに送信します。endpointにはLokiのOTLPエンドポイントを指定し、insecure設定でTLSによる暗号化を無効化します

exporters:
  otlphttp:
    endpoint: "http://<IP>:3100/otlp"
    tls:
      insecure: true

Service

serviceセクションで、上記のレシーバー、プロセッサー、エクスポーターを組み合わせてログパイプラインを構成します。

service:
  pipelines:
    logs:
      receivers: [filelog]
      processors: [resource, batch]
      exporters: [otlphttp]

この設定により、OpenTelemetry CollectorはNginxのアクセスログを収集し、Grafana Lokiに送信します。詳細な設定方法や追加のオプションについては、Grafana Lokiの公式ドキュメントを参照してください。

3. Grafana Lokiの設定

Grafana Lokiをインストールした後、以下の設定を行います。

limits_config:
  allow_structured_metadata: true
  max_streams_per_user: 10000
  max_entries_limit_per_query: 5000
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label
          attributes:
            - service_name
            - host
            - uri
            - method
            - status
  • limits_config: ログストリーム数やクエリの最大エントリ数を制限し、Lokiのリソース負荷を管理します。
  • otlp_config: OpenTelemetryからのデータを受信し、指定した属性(service_nameuriなど)をインデックス化します。
server:
  http_listen_port: 3100

  • server: Lokiがリッスンするポートを指定します。デフォルトは3100です。
storage_config:
  tsdb_shipper:
    active_index_directory: /loki/index
    cache_location: /loki/index_cache
  aws:
    s3: <s3バケット>
    s3forcepathstyle: true
  • storage_config: TSDB形式でログデータを保存します。Amazon S3をバックエンドとして使用する設定例です。

この設定により、Grafana Lokiは以下を実現します:

  • OpenTelemetry Collectorからのログデータ受信
  • Amazon S3へのログデータ保存
  • クエリ性能向上のためのインデックス化

設定は基本的な構成ですが、本番環境では認証やストレージ設定の強化を推奨します。

4. Grafanaの設定

Grafanaを使用してNginxのアクセスログを可視化するために、以下の手順で設定を進めます。

4.1 Grafana Datasourceの設定

Grafanaでデータソースを設定し、Grafana Lokiからログデータを取得できるようにします。

  1. データソースの設定ファイル (datasource.yml) を作成:
    Grafanaの設定ディレクトリ(通常は /etc/grafana/provisioning/datasources)に以下の内容のファイルを配置します。

    apiVersion: 1
    
    datasources:
      - name: Loki
        type: loki
        access: proxy
        orgId: 1
        url: http://localhost:3100
        basicAuth: false
        isDefault: false
        editable: true
    
    
  2. Web UIで確認:
    GrafanaのWeb UIにログインし、Configuration > Data Sources に移動してLokiデータソースが正しく設定されていることを確認します。

4.2 ダッシュボードの作成

ダッシュボードには以下のパネルを含めました。

  • Request Count (リクエスト数):

    sum(count_over_time({service_name="nginx"} [15m]))
    

    15分間隔でのリクエスト数を合計し、全体的なトラフィックを表示します。

  • [URI] Request Count:

    sum by (uri) (count_over_time({service_name="nginx"} [15m]))
    

    URIごとのリクエスト数を集計し、棒グラフで表示します。

  • [Status] Request Count:

    sum by (status) (count_over_time({service_name="nginx"} [15m]))
    

    HTTPステータスコードごとのリクエスト数を円グラフで可視化します。

  • [Avg] Response Time:

    avg by (uri) (avg_over_time({service_name="nginx"} | unwrap reqtime [15m]))
    

    URIごとの平均レスポンスタイムをテーブル形式で表示します。

  • [Max] Response Time:

    max by (uri) (max_over_time({service_name="nginx"} | unwrap reqtime [15m]))
    

    URIごとの最大レスポンスタイムをタイムシリーズで可視化します。

  • [Top3] Request Count:

    topk(3, sum by (uri) (count_over_time({service_name="nginx"} [15m])))
    

    リクエスト数の多い上位3つのURIを棒グラフで表示します。

Reference

Discussion