Always-On Profiling & DB Query Performance

15 minutes  

前の章で見てきたように、APMを使用して、コードに触れることなく、さまざまなサービス間のインタラクションをトレースすることができ、問題をより迅速に特定できます。

トレーシングに加えて、automatic discovery and configurationは、問題をさらに迅速に発見するのに役立つ追加機能を最初から提供します。このセクションでは、そのうちの2つを見ていきます:

  • Always-on Profiling and Java Metrics
  • Database Query Performance

Always-on ProfilingまたはDatabase Query Performanceについてさらに深く学びたい場合は、Debug Problems in Microservicesという別のNinja Workshopがありますので、そちらをご覧ください。

Last Modified 2026/01/05

6. Advanced Featuresのサブセクション

Always-On Profiling & Metrics

先ほどHelmチャートを使用してSplunk Distribution of the OpenTelemetry Collectorをインストールした際、AlwaysOn ProfilingMetricsを有効にするように設定しました。これにより、OpenTelemetry JavaはアプリケーションのCPUとメモリのプロファイリングを自動的に生成し、Splunk Observability Cloudに送信します。

PetClinicアプリケーションをデプロイしてアノテーションを設定すると、collectorは自動的にアプリケーションを検出し、トレースとプロファイリングのためにインストルメントします。これを確認するために、次のスクリプトを実行して、インストルメントしているJavaコンテナの1つの起動ログを調べることができます:

ログには、Javaの自動検出と設定によって取得されたフラグが表示されます:

.  ~/workshop/petclinic/scripts/get_logs.sh
2024/02/15 09:42:00 Problem with dial: dial tcp 10.43.104.25:8761: connect: connection refused. Sleeping 1s
2024/02/15 09:42:01 Problem with dial: dial tcp 10.43.104.25:8761: connect: connection refused. Sleeping 1s
2024/02/15 09:42:02 Connected to tcp://discovery-server:8761
Picked up JAVA_TOOL_OPTIONS:  -javaagent:/otel-auto-instrumentation-java/javaagent.jar
Picked up _JAVA_OPTIONS: -Dspring.profiles.active=docker,mysql -Dsplunk.profiler.call.stack.interval=150
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
[otel.javaagent 2024-02-15 09:42:03:056 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: splunk-1.30.1-otel-1.32.1
[otel.javaagent 2024-02-15 09:42:03:768 +0000] [main] INFO com.splunk.javaagent.shaded.io.micrometer.core.instrument.push.PushMeterRegistry - publishing metrics for SignalFxMeterRegistry every 30s
[otel.javaagent 2024-02-15 09:42:07:478 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-02-15 09:42:07:478 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - Profiler configuration:
[otel.javaagent 2024-02-15 09:42:07:480 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                  splunk.profiler.enabled : true
[otel.javaagent 2024-02-15 09:42:07:505 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                splunk.profiler.directory : /tmp
[otel.javaagent 2024-02-15 09:42:07:505 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -       splunk.profiler.recording.duration : 20s
[otel.javaagent 2024-02-15 09:42:07:506 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -               splunk.profiler.keep-files : false
[otel.javaagent 2024-02-15 09:42:07:510 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -            splunk.profiler.logs-endpoint : http://10.13.2.38:4317
[otel.javaagent 2024-02-15 09:42:07:513 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -              otel.exporter.otlp.endpoint : http://10.13.2.38:4317
[otel.javaagent 2024-02-15 09:42:07:513 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -           splunk.profiler.memory.enabled : true
[otel.javaagent 2024-02-15 09:42:07:515 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -             splunk.profiler.tlab.enabled : true
[otel.javaagent 2024-02-15 09:42:07:516 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -        splunk.profiler.memory.event.rate : 150/s
[otel.javaagent 2024-02-15 09:42:07:516 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.call.stack.interval : PT0.15S
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -  splunk.profiler.include.internal.stacks : false
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.tracing.stacks.only : false
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-02-15 09:42:07:518 +0000] [main] INFO com.splunk.opentelemetry.profiler.JfrActivator - Profiler is active.
私たちが注目しているのは、com.splunk.opentelemetry.profiler.ConfigurationLoggerによって書き込まれたセクション、つまりProfiling Configurationです。

splunk.profiler.directoryなど、制御できるさまざまな設定を確認できます。これは、エージェントがSplunkに送信する前にコールスタックを書き込む場所です。(これは、コンテナの設定方法によって異なる場合があります。)

変更したいもう1つのパラメータはsplunk.profiler.call.stack.intervalです。これは、システムがCPU Stack traceをキャプチャする頻度です。Pet Clinicアプリケーションのような短いスパンがある場合は、このインターバル設定を短くすることをお勧めします。デモアプリケーションでは、デフォルトのインターバル値を変更しなかったため、スパンに常にCPU Call Stackが関連付けられているとは限りません。

これらのパラメータを設定する方法はこちらで確認できます。以下の例では、deployment.yamlでコールスタックのより高い収集レートを設定する方法を示しています。これは、JAVA_OPTIONS configセクションでこの値を設定することで行います。

env:
- name: JAVA_OPTIONS
  value: "-Xdebug -Dsplunk.profiler.call.stack.interval=150"
Last Modified 2026/01/05

Trace Waterfall内のAlways-On Profiling

APM Waterfall ビューでオリジナルの Trace & Span (1)(または類似のもの)を選択し、右側のペインから**Memory Stack Traces (2)**を選択してください:

profiling from span profiling from span

ペインに Memory Stack Trace Flame Graph **(3)**が表示されます。スクロールするか、ペインの右側をドラッグして拡大できます。

AlwaysOn Profiling は、アプリケーションのコードのスナップショット、つまりスタックトレースを常に取得しています。何千ものスタックトレースを読まなければならないことを想像してみてください!それは現実的ではありません。これを支援するために、AlwaysOn Profiling はプロファイリングデータを集約して要約し、Flame Graphと呼ばれるビューで Call Stacks を探索する便利な方法を提供します。これは、アプリケーションからキャプチャされたすべてのスタックトレースの要約を表します。Flame Graph を使用して、パフォーマンスの問題を引き起こしている可能性のあるコードの行を発見し、コードに加えた変更が意図した効果を持っているかどうかを確認できます。

Always-on Profiling をさらに詳しく調べるには、Memory Stack Tracesの下の Profiling Pane で上の画像で参照されている Span **(3)**を選択してください。これにより、Always-on Profiling のメイン画面が開き、Memory ビューがあらかじめ選択されています:

Profiling main Profiling main

  • Time フィルタは、選択したスパンの時間枠に設定されます (1)
  • Java Memory Metric Charts **(2)**では、Heap MemoryのモニターMemory Allocation RateGarbage Collecting Metrics などのApplication Activityを確認できます。
  • スパン **(3)**に関連するメトリクスと Stack Traces のみにフォーカス/表示する機能。これにより、必要に応じて Java アプリケーションで実行されているバックグラウンドアクティビティをフィルタで除外できます。
  • 識別された Java Function calls **(4)**により、その関数から呼び出されたメソッドにドリルダウンできます。
  • プロファイルされたサービスのスタックトレースに基づく階層の視覚化を持つ Flame Graph (5)
  • サービスが複数のバージョンを起動する場合に備えて、Service instance **(6)**を選択する機能。

さらなる調査のために、UI ではスタックトレースをクリックして、呼び出された関数と、フレームチャートから関連する行を確認できます。これを使用して、コーディングプラットフォームで実際のコードの行を表示できます(もちろん、お好みのコーディングプラットフォームによって異なります)。

Last Modified 2026/01/05

Database Query Performance

Database Query Performanceを使用すると、Splunk APMで直接、データベースクエリがサービスの可用性に与える影響をモニターできます。これにより、データベースをインストルメントすることなく、長時間実行されるクエリ、最適化されていないクエリ、または重いクエリを迅速に特定し、それらが引き起こしている可能性のある問題を軽減できます。

データベースクエリのパフォーマンスを確認するには、ブラウザで戻るか、メニューバーのAPMセクションに移動してAPMのService Mapページに移動し、Service Mapタイルをクリックします。

Dependency mapで推論されたデータベースサービス mysql:petclinic Inferred Database serverを選択し (1)、次に右側のペインをスクロールしてDatabase Query Performance Pane **(2)**を見つけます。

DB-query from map DB-query from map

マップで選択したサービスが実際に(推論された)データベースサーバーである場合、このペインには期間に基づく上位90%(P90)のデータベースコールが表示されます。db-queryパフォーマンス機能をさらに詳しく調べるには、ペインの上部にあるDatabase Query Performanceという単語のどこかをクリックします。

これにより、DB-query Performanceの概要画面が表示されます:

DB-query full DB-query full

Database Query Normalization

デフォルトでは、Splunk APMインストルメンテーションはデータベースクエリをサニタイズして、db.statementsからシークレットや個人を特定できる情報(PII)などの機密データを削除またはマスクします。データベースクエリの正規化をオフにする方法はこちらで確認できます。

この画面には、Splunk Observability Cloudに送信されたTraces & Spansに基づいて、アプリケーションからデータベースに対して実行されたすべてのDatabase queries **(1)**が表示されます。時間ブロック間で比較したり、Total Time、P90 Latency & Requests **(2)**でソートしたりできることに注意してください。

リスト内の各Database queryについて、時間ウィンドウ中の最高レイテンシ、コールの総数、および1秒あたりのリクエスト数 **(3)**が表示されます。これにより、クエリを最適化できる場所を特定できます。

右側のペイン **(5)**の2つのチャートを使用して、Database Callsを含むトレースを選択できます。Tag Spotlightペイン **(6)**を使用して、エンドポイントやタグに基づいて、データベースコールに関連するタグを確認します。

クエリの詳細ビューを表示する必要がある場合:

details details

特定のQuery **(1)**をクリックします。これにより、Query Details pane **(2)**が開き、より詳細な調査に使用できます。