OpenTelemetry Collector x Grafana lokiでNginxアクセスログを収集・可視化
OpenTelemetry Advent Calendar 2024の21日目を担当させていただきました
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_name
やuri
など)をインデックス化します。
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からログデータを取得できるようにします。
-
データソースの設定ファイル (
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
-
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
- Grafana、Grafana Loki、PromtailでNginxのアクセスログを可視化する最強のダッシュボードを作る
- Ingesting logs to Loki using OpenTelemetry Collector | Grafana Loki documentation
- Getting started with the OpenTelemetry Collector and Loki tutorial | Grafana Loki documentation
- Nginx Metrics and Logs Monitoring with OpenTelemetry
- Nginx Metrics and Logs Monitoring with OpenTelemetry
Discussion