概要
今回 NGINX 公式の Openteremetry モジュールがオープンソースで公開されていたので、検証してみました。導入が簡単になっていてパフォーマンスも改善しているというメリットがありました。
NGINX の OpenTelemetry(OTel)を使った計装の方法は以前 Qiita の記事を作成しましたが、導入時にビルドが必要だったりと導入ハードルが高いものでした。それを理由に諦めていた人はぜひ今回の内容を見て再挑戦してみてください。また、サードパーティのモジュールを使用している人は、パフォーマンス改善の恩恵が大きいので切り替えを検討してください。
最新のアップデートの詳細はこちら
New Relic アップデート一覧
無料のアカウントで試してみよう!
今回のポイント
NGINX 公式の Openteremetry モジュールを使用する利点は、次の3つです。
1. NGINX公式のオープンソースモジュール
これまではサードパーティのモジュールだったため、ドキュメントが整備されていないなど導入しづらい点もありました。公式のオープンソースモジュールなのでNGINXの公式ドキュメントにも設定のパラメータ情報等が記載されています。また、NGINX Plusとの連携も可能です。
2. インストール、設定が簡単!
パッケージマネージャ(yum, apt)を使ったインストールに対応。さらにモジュールがインストールされたDockerイメージも提供されています。(Alpine Linux のパッケージマネージャには対応していないのでイメージの配布は嬉しい)
モジュールの設定も NGINX のコンフィグファイルに設定を追加するだけなので新しい設定ファイルの追加も必要ありません。
3.パフォーマンスも大幅に改善
サードパーティの Openteremetry モジュールは、リクエスト処理のパフォーマンスが最大 50% 低下します。一方でNGINX 公式のモジュールは、この影響を 約10~15% に制限しているそうです。
セットアップ方法
NGINX 公式のモジュールは、インストールが簡単です。パッケージマネージャを使ってインストールして、 NGINX のコンフィグファイルを編集するという2つのステップで完結します。今回は New Relic の Logs in Context の機能も使いたいのでその方法も併せて紹介します。
セットアップの方法は、GitHub に記載された内容と NGINX の公式ドキュメントを参考にしています。
また、収集したデータを New Relic に連携するために OpenTelemetry Collector(OTel Collector) を使用しています。OTel Collectorの設定は、Qiitaの記事で公開していて、今回も同じ設定をそのまま使用しています。
OpenTelemetry モジュールのインストール
RHEL, CentOS および その派生製品
sudo yum install nginx-module-otel
Debian, Ubuntu および その派生製品
sudo apt install nginx-module-otel
Dockerイメージの利用
FROM nginx:stable-alpine-otel
***-otel
と記載されているイメージには、OTel モジュールが導入されています。
インストールすることで /etc/nginx/modules
に OTel モジュールの ngx_otel_module.so
が配置されます。
今回はDockerイメージを使って検証を行いました。
ファイルの設定
トレースデータの収集 ・ 転送設定
NGINX の設定ファイルに OTel モジュールの設定を追加するとトレースデータの収集と OTel Collector へのデータ転送ができます。具体的な設定内容は下記のとおりです。
user nginx;
worker_processes 1;
+ # ngx_otel_module.soをロード
+ load_module modules/ngx_otel_module.so;
error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
+ # OTel Collector へデータを転送する設定
+ otel_exporter {
+ endpoint otel-collector:4317;
+ }
+ # New Relic で表示するエンティティ名の設定
+ otel_service_name nginx-native-eccube-proxy;
+
server {
# Proxy
location / {
+ # トレースの有効化
+ otel_trace on;
+ # トレース情報を伝搬する方法を設定
+ otel_trace_context propagate;
+ # トランザクション名 ・ スパン名の設定
+ otel_span_name $request_uri;
それぞれ設定しているのは下記の項目です。
1. OTel モジュール ngx_otel_module.so のロード
パッケージマネージャでインストールすると /etc/nginx/modules
配下にモジュールが配置されるため、設定ファイルからの相対パスでファイルを指定してロードします。
2. OTel Collector へデータを転送する設定(http配下)
OTel Collector のエンドポイント(endopoint)やデータ転送の間隔(interval)を設定できます。認証情報が設定できないため、New Relic へデータを転送する場合は OTel Collector が必須です。
3. エンティティ名の設定(http配下)
New Relic で表示されるエンティティ名を設定します。
4. トレースの有効化(http, server, location配下)
OTel モジュールのトレースを有効(on)または無効(off)にします。
5. トレース情報を伝搬する方法を設定(http, server, location配下)
traceparent/tracestate ヘッダーを伝播する方法を指定します。下記4つの設定が可能でトレースコンテキストの設定方法には違いがあります。
-
extract
NGINX が受信したリクエストに付与されたトレースコンテキストを継承します。NGINX 自身がトレースのルートスパンになることはありません。 -
inject
NGINX 自身が常にトレースのルートスパンになるようにトレースコンテキストを設定します。 -
propagate
extract と inject の組み合わせで設定されます。トレースコンテキストがない場合は新しく追加し、すでに設定されている場合は継承します。 -
ignore
トレースコンテキストの処理をスキップします。
6. トランザクション名 ・ スパン名の設定(http, server, location配下)
OTelモジュールで計装したスパン名を設定します。New Relic 上ではトランザクション名としても使用されます。
Logs in Context の有効化
NGINX のログに Service Name, Trace ID, Span ID を追加することで New Relic の Logs in Context の機能が利用できます。分散トレーシングで実行されたトランザクション毎に関連したログを表示する機能でトラブルシュートをする際に大変便利な機能です。
下記の設定が Logs in Context の機能を使用する際のログの例です。
log_format json escape=json '{'
'"time": "$time_iso8601",'
'"host": "$remote_addr",'
'"vhost": "$host",'
'"user": "$remote_user",'
'"status": "$status",'
'"protocol": "$server_protocol",'
'"method": "$request_method",'
'"path": "$request_uri",'
'"req": "$request",'
'"size": "$body_bytes_sent",'
'"reqtime": "$request_time",'
'"apptime": "$upstream_response_time",'
'"user_agent": "$http_user_agent",'
'"forwardedfor": "$http_x_forwarded_for",'
'"forwardedproto": "$http_x_forwarded_proto",'
'"referrer": "$http_referer",'
+ '"service.name": "nginx-native-eccube-proxy",'
+ '"trace.id": "$otel_trace_id",'
+ '"span.id": "$otel_span_id"'
'}';
access_log /var/log/nginx/access.log json;
Trace ID, Span ID はそれぞれ $otel_trace_id
, $otel_span_id
の変数を使うことで取得可能です。
New Relicに連携されたデータの確認
収集した NGINX のデータを New Relic の UI で確認しましょう。APM & Services にエンティティが表示されているので、設定した名前のエンティティを選択して情報を確認していきましょう。
この記事の中では、フロントエンドやバックエンドと併せて確認できる Service Map と 分散トレーシング、そして NGINX のログで設定した Logs in Context を確認します。
Service Map
Service Map では発生したリクエストをもとにシステムの構成をマッピングしてくれます。OTel モジュールを使用していない場合は、以下のようにフロントエンドとバックエンドの間にある NGINX が表示されません。
OTel モジュールを有効にしてトレースの情報を収集すると以下のようにフロントエンドとバックエンドの間に設置された NGINX がしっかり表示されます。
分散トレーシング
分散トレーシングでも同様に NGINX が表示されます。これで NGINX がボトルネックになっているのか、バックエンドの処理がボトルネックになっているのか明確に切り分けることができるようになります。
Logs in Context
分散トレーシングの画面からトランザクションで出力されたログを確認することができます。今回は NGINX のログにTraceIDを挿入して、以下のように対象のログのみが自動で関連付けて表示されています。NGINX の膨大なログの中から目的のログを探し出してバックエンドの実行ログと突合する作業から解放されますね。
最後に
NGINX 公式の OpenTelemetry モジュールを使うと簡単に NGINX の計装が可能です。設定もサードパーティのモジュールよりも簡単になっています。コンテナイメージが提供されているため、ちょっとした動作を確認するのも簡単です。New Relic はフリープランを用意しているため、無料で NGINX を計装したデータを確認できます。
ぜひ New Relic と NGINX の OpenTelemetry モジュールを使って、今運用している環境のオブザーバビリティを高めてください。
無料のアカウントで試してみよう!
New Relic フリープランで始めるオブザーバビリティ!
New Relic株式会社のQiita Organizationでは、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。