Splunk OpenTelemetry Collectorでホスト、NGINX、MySQLを可視化

Observability 川口 明彦

ISUCON は、お題となる Web サービスを、決められたルールの中で限界まで高速化するチューニングコンテストです。1〜3 名のチームが限られた時間内にアプリケーションやミドルウェアを改善し、ベンチマーカーが計測したスコアを競います。

ISUCON の練習では、トレースを追う前に、ホスト、リバースプロキシー、データベースの負荷を確認すると、次に調べる対象を絞り込めます。

本記事では、Linux 1 台に Splunk Distribution of the OpenTelemetry Collector(以下 Splunk OTel Collector)を導入します。ホスト、NGINX、MySQL のメトリックを Splunk Observability Cloud へ送り、ボトルネック候補を確認する手順を紹介します。

検証は ISUCON 過去問(ISUCON14)の練習用仮想マシン 1 台で行いました。本記事の内容は、2026 年 10 月 4 日時点の公式インストーラーと画面で確認しています。

本記事で扱う範囲

本記事で扱う範囲は次のとおりです。

本記事では、ボトルネック候補を絞るためのメトリックに範囲を限定します。

前提

次を前提とします。

インストーラーのメモリー設定は既定で 512 MiB です。本検証では、メモリー 4 GiB のホストで --memory 128 を指定しました。この値は Collector に割り当てるメモリーの設定です。OS が強制する RSS の上限ではありません。メモリー制限の警告やデータの欠落が発生する場合は、既定値へ戻すか値を増やしてください。

トークンやパスワードの実際の値は記事に書きません。コマンド例ではプレースホルダーを使います。実行時は、実際の値に置き換えてください。

Splunk OTel Collector の導入

Splunk Observability Cloud の realm(レルム)と、取り込み用アクセストークンを用意します。次の例では、realm を環境変数に設定し、アクセストークンをファイルに保存します。

Linux 向けインストーラー は agent モードが既定です。メモリーだけ 128 MiB にします。

export SPLUNK_REALM="<your-realm>" 
install -d -m 700 "$HOME/.config/splunk" 
cat > "$HOME/.config/splunk/ingest.token" <<'EOF' 
<ingest-access-token> 
EOF 
chmod 600 "$HOME/.config/splunk/ingest.token" 
 
curl -fsSL https://dl.observability.splunkcloud.com/splunk-otel-collector.sh \ 
  -o /tmp/splunk-otel-collector.sh && 
sudo sh /tmp/splunk-otel-collector.sh \ 
  --realm "$SPLUNK_REALM" \ 
  --memory 128 \ 
  --mode agent \ 
  < "$HOME/.config/splunk/ingest.token" 
 
sudo rm -f /tmp/splunk-otel-collector.sh 

--discovery は付けません。自動検出を使う場合も、NGINX の stub_status と MySQL のモニターユーザーは別途必要です。本記事では、収集対象が設定ファイルで分かるように receiver を明示します。

インストールしたバージョンと、同じホストで動く NGINX、MySQL のバージョンを確認します。

dpkg-query -W -f='${Package} ${Version}\n' splunk-otel-collector 
nginx -v 
mysql --version

インストーラーが作る既定設定には host metrics receiver が含まれます。CPU、メモリー、ディスク、ファイルシステム、ロード、ネットワークのメトリックを収集できます。プロセス単位のスクレイパーは既定で無効です。後の節で NGINX、MySQL、アプリの 3 種類に絞って有効にします。

インストール後は、同じホストで Collector の起動を確認します。確認先はループバックのポート 13133 です。

curl -fsS http://127.0.0.1:13133

Server available を含む JSON が返れば、Collector プロセスは起動しています。この応答だけでは、各 receiver の収集やデータ送信の成功までは確認できません。

NGINX、MySQL、プロセスメトリックの追加

ホストメトリックは既定で収集されます。続いて NGINX、MySQL、プロセス単位の設定を追加します。

Collector のバージョンによって、ホストメトリックの receiver ID が host_metrics または hostmetrics の場合があります。以降の例では本検証環境の host_metrics を使います。既存の設定が hostmetrics の場合は、その ID を変更せずに使ってください。

以下の YAML は、既存設定に加える差分です。トップレベルの receivers: や service: を重複して作らず、既存の processor、exporter、receiver を残してください。

NGINX の stub_status と receiver

NGINX receiver は、ngx_http_stub_status_module のエンドポイントをスクレイプします。公式サンプルの既定 URL は http://localhost:80/status です。本検証では、80 番の default_server に設定を加え、ループバックからの接続だけを許可しました。

http://127.0.0.1/nginx_status は、この 80 番の default_server に届きます。次のパスは、本検証の ISUCON14 のものです。他の年の ISUCON では、NGINX の構成に合わせて対象ファイルを読み替えてください。

sudo vim /etc/nginx/sites-available/isuride.conf

編集後の先頭の server は、次のとおりです。既存の location / は残します。

server { 
  listen 80 default_server; 
  server_name _; 
  index index.html index.htm index.nginx-debian.html; 
  root /var/www/html; 
 
  location = /nginx_status { 
    stub_status; 
    access_log off; 
    allow 127.0.0.1; 
    deny all; 
  } 
 
  location / { 
    try_files $uri $uri/ =404; 
  } 
} 

構文を確認してから再読み込みします。続けて Active connections が見えることを確認します。

sudo nginx -t && sudo systemctl reload nginx 
curl -fsS http://127.0.0.1/nginx_status 

Collector の設定ファイルを開きます。

sudo vim /etc/otel/collector/agent_config.yaml 

receivers: に nginx を追加します。metrics パイプラインは receivers 行だけを変更します。既存の processor と exporter は残します。

 receivers: 
+  nginx: 
+    endpoint: http://127.0.0.1/nginx_status 
+    collection_interval: 10s 
 
 service: 
   pipelines: 
     metrics: 
-      receivers: [host_metrics, otlp] 
+      receivers: [host_metrics, otlp, nginx] 

MySQL のモニターユーザー

MySQL receiver は、グローバルステータスなどを取得します。アプリ用の DB ユーザーは使わず、必要な権限だけを持つモニターユーザーを作ります。

<password> は、この手順であなたが新しく決める任意のパスワードへ置き換えてください。同じ値を Collector の MYSQL_PASSWORD に設定します。

MySQL クライアントを起動します。

sudo mysql

MySQL プロンプトで Performance Schema の状態を確認します。

SHOW VARIABLES LIKE 'performance_schema'; 

ON なら、次の手順へ進みます。OFF の場合は、設定ファイルに performance_schema=ON を追加してください。その後、MySQL を再起動します。再度状態を確認し、ON になったらモニターユーザーを作ります。

CREATE USER 'otel'@'127.0.0.1' IDENTIFIED BY '<password>'; 
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'otel'@'127.0.0.1'; 
GRANT SELECT ON performance_schema.* TO 'otel'@'127.0.0.1'; 
SHOW GRANTS FOR 'otel'@'127.0.0.1'; 

本記事ではクエリーサンプルや実行計画を収集しないため、アプリのスキーマに対する SELECT は付与しません。MySQL receiver の既定のメトリック収集は、クエリーサンプルとは別に performance_schema を参照します。対象はテーブル I/O、インデックス I/O、ステートメント統計、テーブルロック待ちです。MySQL receiver のユーザー作成例に従い、performance_schema.* への SELECT を付与します。

すでにモニターユーザーだけを作っている場合は、同じ GRANT SELECT を追加してください。この権限が無いと、10 秒ごとに Error 1142 がログへ出ます。

シェルプロンプトへ戻り、作成したユーザーでステータスを取得できることを確認します。-p の後にはパスワードを書かず、表示されるプロンプトで入力してください。

mysql -h 127.0.0.1 -u otel -p \ 
  -e "SHOW GLOBAL STATUS LIKE 'Threads_running';" 

次に、パスワードを Collector の環境変数ファイルへ書きます。既存の SPLUNK_* 行は残します。

sudo vim /etc/otel/collector/splunk-otel-collector.conf 

ファイルの末尾へ、次の 2 行を足します。

MYSQL_USER=otel 
MYSQL_PASSWORD=<password> 

ファイルを保存したら、所有者と権限を確認します。他のローカルユーザーが読める場合は、権限を 600 に制限してください。

sudo stat -c '%U:%G %a %n' \ 
  /etc/otel/collector/splunk-otel-collector.conf 
sudo chmod 600 /etc/otel/collector/splunk-otel-collector.conf 

Collector の設定を再び開きます。

sudo vim /etc/otel/collector/agent_config.yaml 

receivers: に mysql を追加します。metrics パイプラインの既存設定は残します。

 receivers: 
+  mysql: 
+    endpoint: 127.0.0.1:3306 
+    username: ${env:MYSQL_USER} 
+    password: ${env:MYSQL_PASSWORD} 
+    collection_interval: 10s 
 
 service: 
   pipelines: 
     metrics: 
-      receivers: [host_metrics, otlp, nginx] 
+      receivers: [host_metrics, otlp, nginx, mysql] 

Database Monitoring 向けの db.server.query_sample や db.server.top_query は有効にしません。これらを無効にしても、テーブル I/O などの performance_schema メトリックは収集されます。そのため、前の節の SELECT が必要です。

プロセス単位の CPU

NGINX、アプリ、MySQL のどれが CPU を使っているかを分けるため、プロセス単位のスクレイパーをこの 3 つに絞って有効にします。

同じ Collector 設定を再び開きます。

sudo vim /etc/otel/collector/agent_config.yaml

host_metrics の scrapers: にある # process: を、次の差分のように置き換えます。cpu、memory、disk など、ほかの scraper はそのまま残します。

 receivers: 
   host_metrics: 
     scrapers: 
-      # process: 
+      process: 
+        include: 
+          names: [nginx, mysqld, isuride] 
+          match_type: strict 
+        mute_process_exe_error: true 
+        mute_process_name_error: true 
+        resource_attributes: 
+          process.command_line: 
+            enabled: false 
+        metrics: 
+          process.cpu.utilization: 
+            enabled: true 

isuride は ISUCON14 の Go 実装のプロセス名です。ほかの言語では ps でプロセス名を確認して置き換えてください。

process scraper は、既定でコマンドラインなどの属性も収集できます。アプリの起動引数に認証情報が含まれる場合に備え、この例では process.command_line を無効にしています。

設定の検証

設定を反映するため、サービスを再起動します。

sudo systemctl restart splunk-otel-collector 
sudo systemctl is-active splunk-otel-collector 
curl -fsS http://127.0.0.1:13133 

active と表示され、health check が成功することを確認します。続いて、直近のログを確認します。エラーが出力されないことを確認してください。

sudo journalctl -u splunk-otel-collector \ 
  --since "-5 minutes" --no-pager 

チャートが空のままにならないよう、確認用の短い負荷をかけます。本検証では、練習用の HTTP 負荷を 1 分ほど流しました。

process.cpu.utilization は、最初の収集時には値を生成しません。負荷を開始して 20 秒以上待ってから Splunk Observability Cloud の Metrics を開き、次を確認してください。

画面の読み方

ホスト CPU、プロセス CPU、MySQL のチャートは Metrics から開きます。本検証環境では、NGINX の情報を Dashboards から確認できました。掲載する 4 枚の画面では、ホスト名やアカウント ID をマスクしています。

SignalFlow を使うチャートは、Metric Finder の View in chart から開きます。その後、Plot editor タブの View SignalFlow で式を置き換えます。

複数のホストが登録されている場合は、チャートのフィルターで対象ホスト 1 台を選んでください。以降の式と数値は、対象ホストを絞り込んだ状態を前提とします。

ホスト CPU

図 1: 負荷区間のホスト CPU 使用率

cpu.utilization です。負荷をかけた約 1 分間、100% に張り付きました。どのプロセスが使っているかは、次のプロセス別のチャートで確かめます。

プロセス別の CPU

図 2: プロセス別の CPU 使用率

process.cpu.utilization をプロセス名(process.executable.name)ごとに合計したチャートです。メトリックは 0 から 1 の比率なので、百分率で表示するために 100 倍します。

SignalFlow での表記は、次のとおりです。

A = data('process.cpu.utilization').sum(by=['process.executable.name']).scale(100).publish(label='A') 

各系列のプロセス名と値は、Data table タブで確かめられます。本検証の初期実装では、負荷をかけた区間で mysqld が約 85%、isuride が 1 割未満でした。mysqld が大半なら MySQL 側を、isuride が大半ならアプリ側を先に確認します。

選択していないプロセスやカーネル処理も CPU を使うため、プロセス別の合計がホスト CPU と一致するとは限りません。

NGINX の接続

図 3: NGINX の接続状態と接続処理数

本検証環境では、Dashboards で NGINX を検索し、NGINX servers を開くとデータを確認できました。NGINX receiver の標準ダッシュボード対応はバージョンや構成によって異なります。表示されない場合は、Metrics から NGINX receiver のメトリックを選び、カスタムチャートを作成してください。

Active は現在のクライアント接続数で、Reading、Writing、Waiting を含みます。Waiting は、次のリクエストを待つアイドル状態の keep-alive 接続です。増加だけで異常とは判断しません。

accepted と handled は、NGINX の起動後からの累積カウンターです。通常は同じ値になります。handled が accepted を継続的に下回り、Connections drop が増える場合は、worker_connections などの接続上限を確認します。本検証では Connections drop はほぼ 0% でした。

MySQL のスレッド

図 4: MySQL の接続スレッド数と実行中スレッド数

mysql.threads を、kind が connected と running のものに絞ったチャートです。connected は開いている接続数を示します。running は休止していないスレッド数を示します。

SignalFlow での表記は、次のとおりです。

A = data('mysql.threads', filter=filter('kind', 'connected', 'running')).sum(by=['kind']).publish(label='A') 

負荷をかけた区間で、connected は 3 から 51 へ、running は 2 から 27 へ増えました。CPU 使用率と running が同時に増える場合は、クエリーの並行実行、遅いクエリー、ロック待ちなどを調べる手掛かりになります。ただし、このメトリックだけでは原因を特定できません。

本記事の設定では、NGINX のアクセスログや MySQL の低速なクエリーのログを収集しません。必要な場合は、ログ用の receiver とパイプラインを別途設定してください。

計測時の注意

Collector 自体も CPU とメモリーを使用します。診断用の計測では Collector を動かし、ボトルネック候補を絞ります。公式スコアを比較するときは大会のルールを確認し、計測目的に応じて Collector を止める選択肢があります。

Collector を止めると、新しいメトリックは送信されません。スコア計測後に再開する場合は、次のように操作します。

sudo systemctl stop splunk-otel-collector 
# スコア計測 
sudo systemctl start splunk-otel-collector 

ISUCON2026 のレギュレーションによると、競技終了後の追試では主催者がサーバーを再起動します。本番で Collector を使った場合は、追試の再起動で起動しないよう、競技終了前に自動起動も無効にします。

sudo systemctl disable --now splunk-otel-collector 

複数台構成への応用

複数台のサーバーを使う場合は、各サーバーに Collector を導入します。NGINX と MySQL の receiver は、それぞれが動くサーバーだけで有効にします。役割を分けた後は、ホストごとのチャートで負荷の偏りを確認できます。

まとめ

本記事では、次の順序でボトルネック候補を絞りました。

APM やログ分析へ進む前に、この順序でメトリックを確認すると、次に調べる対象を絞り込めます。

本記事は練習環境を前提にしましたが、同じ手順は ISUCON の本番にも応用できます。本番も NGINX と MySQL を使う場合は、NGINX の設定ファイルとアプリのプロセス名を読み替えて導入できます。最終的なスコアを計測する前には、「計測時の注意」のとおり Collector を止めてください。

次のステップ

関連記事

オブザーバビリティの実現が必要な理由 環境の複雑化とビジネスの高速化
オブザーバビリティ
6 分程度

オブザーバビリティの実現が必要な理由 環境の複雑化とビジネスの高速化

コロナ禍により、多くの企業のシステム環境がクラウドネイティブのアーキテクチャを採用し、早いサイクルでサービスを開発し提供しています。複雑化し動的に変化するシステムでは、全体の状況把握が困難になり、障害への対応が遅れがちになります。今回は、こうした課題を解決するオブザーバビリティと、それを実現するSplunk Observability Cloudを紹介します。
データストレージコストの不安を解消:Archived Metricsのご紹介
オブザーバビリティ
4 分程度

データストレージコストの不安を解消:Archived Metricsのご紹介

SplunkのMetrics Pipeline Managementでデータを低コストで保存し、アクセス性を向上させて、コストを削減するための機能、Archived Metricsについてご紹介します。
DevOpsのCI/CDパイプライン:概要
オブザーバビリティ
11 分程度

DevOpsのCI/CDパイプライン:概要

このブログ記事では、CI/CD (継続的インテグレーション/継続的デリバリー)パイプラインの概要と、現代のデジタル企業におけるその役割について取り上げます。