すべてのプロダクト
Search
ドキュメントセンター

Application Real-Time Monitoring Service:OpenTelemetry Java SDK を使用してメトリックをカスタマイズする

最終更新日:Nov 09, 2025

ARMS は、一般的な アプリケーションモニタリングメトリック を提供します。OpenTelemetry Java SDK をインポートして、メトリックをカスタマイズできます。このトピックでは、メトリックをカスタマイズし、Grafana でクエリする方法について説明します。

前提条件

  • アプリケーションを ARMS アプリケーションモニタリングに接続済みであること。詳細については、「アプリケーションアクセス」をご参照ください。

  • ARMS エージェントのバージョンが 4.5.0 以降であること。

依存関係のインポート

次の Maven 依存関係を追加して、OpenTelemetry Java SDK をインポートします。詳細については、「公式 OpenTelemetry ドキュメント」をご参照ください。

<dependencies>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-bom</artifactId>
      <version>1.23.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

メトリックをカスタマイズする手順

OpenTelemetry は現在、次の 4 種類のメトリックをサポートしています。ARMS は、Histogram を除くすべての種類をサポートしています。

  • CounterUsage: 単調に増加する累積値を記録します。例: HTTP リクエストの総数、エラー数。

  • UpDownCounterUsage: アクティブな接続数など、増減する可能性のある非単調な値を記録します。例: 同時リクエスト数、キュー内のタスク数。

  • Histogram (サポート対象外)Usage: レイテンシーや応答サイズなどの値の分布を記録し、分位数計算をサポートします。例: リクエストのレイテンシー分布 (P90 および P95)、ファイルアップロードサイズ。

  • GaugeUsage: CPU 使用率やメモリ使用量など、特定の時点での瞬間的な値をキャプチャします。例: システムの温度、リアルタイムのメモリ使用量。

ステップ 1: コードにカスタムメトリックを追加する

次のコードは、2 つのメトリックを定義する簡単なタイムセールの例を示しています。

  • product_seckill_count: タイムセール試行回数。

  • product_current_stock: 現在の在庫。

メトリックを定義するためのファクトリクラスである meter を取得するときに、product_seckill という名前のパラメーターを渡します。このパラメーターはグループ名として機能します。この meter によって定義されたすべてのメトリックは、このグループに属します。このグループ名は、後続の構成で使用されます。

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongGauge;

import javax.annotation.PreDestroy;
import java.util.concurrent.atomic.AtomicInteger;

class ProductService {

    // 静的在庫カウンター
    public final AtomicInteger stock = new AtomicInteger(0);

    private LongCounter seckillCounter;
    private ObservableLongGauge observableLongGauge;
    private final AttributeKey<String> seckillResult = AttributeKey.stringKey("seckill_result");

    public ProductService() {
        OpenTelemetry agentOpenTelemetry = GlobalOpenTelemetry.get();


        // メトリックファクトリクラスを定義します。product_seckill が重要であることに注意してください。
        Meter meter = agentOpenTelemetry.getMeter("product_seckill");
        // タイムセールの試行回数を記録するカウンターメトリックを定義します。
        seckillCounter = meter.counterBuilder("product_seckill_count")
                .setUnit("1")
                .setDescription("seckill product count")
                .build();

        // プロダクトの現在の在庫を表すゲージメトリックを定義します。
        observableLongGauge = meter.gaugeBuilder("product_current_stock").ofLongs().buildWithCallback((measurement -> {
            // 現在のプロダクト数量を記録します。
            measurement.record(stock.get());
        }));

    }
    
    @PreDestroy
    public void clear() {
        observableLongGauge.close(); 
    }
    
    public void setKillProductCount(int count) {
        stock.set(count);
    }

    public String seckillProduct() {
        int currentStock = stock.get();
        if (currentStock <= 0) {
            seckillCounter.add(1, Attributes.of(seckillResult, "failed"));
            return "Flash sale failed. The product is sold out.";
        }
        // 在庫を差し引いてみます。
        if (stock.decrementAndGet() >= 0) {
            seckillCounter.add(1, Attributes.of(seckillResult, "success"));
            return "Flash sale successful. Remaining inventory: " + stock.get();
        } else {
            stock.incrementAndGet(); // ロールバック
            seckillCounter.add(1, Attributes.of(seckillResult, "success"));
            return "Flash sale failed. The product is sold out.";
        }
    }
}

ステップ 2: コンソールでメトリック収集を構成する

コンソールで、カスタムメトリック収集構成 を変更し、前のステップで meter を作成するために使用したパラメーターを追加します。

image.png

ステップ 3: メトリックの表示とアラートの設定

  1. ARMS コンソール[Prometheus モニタリング] > [インスタンスリスト] ページの上部のメニューバーで、アプリケーションがデプロイされているリージョンを選択します。

    タイプが Prometheus for Application Monitoring のインスタンスは、デフォルトのアプリケーションモニタリングインスタンスです。

    2024-10-29_11-56-55

  2. [共有版] をクリックして Grafana ページを開きます。[Explore] をクリックし、前のステップの Prometheus インスタンスをデータソースとして選択します。

    2025-07-31_16-26-27

  3. 次の図に示すように、Prometheus Query Language (PromQL) を使用して、コードで定義したメトリックをクエリできます。Grafana で ダッシュボードをカスタマイズする こともできます。

    image

この時点で、OpenTelemetry SDK を使用して定義したメトリックは、ARMS の Prometheus インスタンスにレポートされ、保存されます。その後、これらのメトリックに対して アラートルールを作成する ことができます。

注意事項

  • ARMS は 15 秒間隔でメトリックをレポートします。

  • Counter メトリックの場合、ARMS は累積値ではなく、各レポートエポック内の増分をレポートします。つまり、ARMS は 15 秒ごとにメトリックの値の増加をレポートします。