# Prometheus クライアントライブラリ vs. OpenTelemetry

LLMS index: [llms.txt](/llms.txt)

---

<?code-excerpt path-base="examples/java/prometheus-compatibility"?>

> [!NOTE]
>
> このページでは Java と Go を扱います。
> 他の言語の例も追加予定です。

このガイドは、[Prometheus クライアントライブラリ](https://prometheus.io/docs/instrumenting/clientlibs/)に慣れている開発者が、OpenTelemetry メトリクス API と SDK における同等のパターンを理解するためのものです。
よく使われるパターンを網羅していますが、すべてを扱っているわけではありません。

## コンセプトの違い {#conceptual-differences}

コードを見る前に、2つのシステム間のいくつかの構造的な違いを理解しておくと役立ちます。
[Prometheus と OpenMetrics の互換性](/docs/specs/otel/compatibility/prometheus_and_openmetrics/)仕様には、2つのシステム間の完全な変換ルールが文書化されています。
このセクションでは、新しい計装コードを書く際にもっとも関連する違いについて説明します。

### レジストリ（MeterProvider） {#registry-meterprovider}

Prometheus では、メトリクスはレジストリに登録されます。デフォルトではグローバルなレジストリです。
コード内のどこでもメトリクスを宣言でき、登録されるとスクレイピング可能になります。
エクスポーター（HTTP サーバーまたは OTLP プッシュ）は、別の独立したステップとしてレジストリに接続されます。

OpenTelemetry では、`MeterProvider` と `Meter` はメトリクス API の一部です。
`MeterProvider` から、ライブラリまたはコンポーネントにスコープされた `Meter` を取得し、その `Meter` から計装を作成します。
それらの計測がどのように処理されるか、つまりどのエクスポーターが受信し、どのように集約され、どのスケジュールで処理されるかは、`MeterProvider` にバインドされた SDK とその設定によって決まります。
これは計装コード自体とは切り離されています（[API と SDK](#otel-api-and-sdk) を参照）。

Prometheus と同様に、OpenTelemetry もグローバルな `MeterProvider`（計装コードからの明示的な配線が不要）と、明示的な `MeterProvider` インスタンス（それをサポートするライブラリに渡すことができる）の両方をサポートしています。

### ラベル名（属性） {#label-names-attributes}

Prometheus では、ラベルの _名前_ をメトリクス作成時に宣言する必要があります。
ラベルの _値_ は、`labelValues(...)` を介して記録時にバインドされます。

OpenTelemetry には、事前のラベル宣言がありません。
属性のキーと値は、`Attributes` を介して計測時にまとめて提供されます。

### 命名規則 {#naming-conventions}

Prometheus は `snake_case` のメトリクス名を使用します。
カウンター名は `_total` で終わります。
慣例として、Prometheus のメトリクス名には、衝突を避けるためにアプリケーションまたはライブラリ名の接頭辞が付けられます（たとえば `smart_home_hvac_on_seconds_total`）。
すべてのメトリクスがフラットなグローバル名前空間を共有するためです。

OpenTelemetry は慣例として[ドット区切りの名前](/docs/specs/semconv/general/naming/)を使用します。
所有権と名前空間は計装スコープ（`Meter` 名、たとえば `smart.home`）で表現されるため、メトリクス名自体に接頭辞は不要です（たとえば `hvac.on`）。
Prometheus にエクスポートする際、エクスポーターは名前を変換します。ドットはアンダースコアに変わり、単位の略語は完全な単語に展開され（たとえば `s` → `seconds`）、カウンターには `_total` 接尾辞が付きます。
`hvac.on` という名前で単位 `s` の OpenTelemetry カウンターは、`hvac_on_seconds_total` としてエクスポートされます。
名前変換ルールの完全なセットについては、[互換性仕様](/docs/specs/otel/compatibility/prometheus_and_openmetrics/)を参照してください。
変換戦略は設定可能です。たとえば、UTF-8 文字を保持したり、単位や型の接尾辞を抑制したりできます。
詳細は [Prometheus エクスポーター](/docs/specs/otel/metrics/sdk_exporters/prometheus/)設定リファレンスを参照してください。

### ステートフル計装とコールバック計装 {#stateful-and-callback-instruments}

両方のシステムは2つの記録モードをサポートしています。

- **Prometheus** は、_ステートフル_ 計装（`Counter`、`Gauge`）と、スクレイプ時にコールバックを呼び出して現在の値を返す関数ベースの計装を区別します。
  前者は自身の累積値を保持します。
  命名はクライアントライブラリによって異なります（Go では `GaugeFunc`/`CounterFunc`、Java では `GaugeWithCallback`/`CounterWithCallback`）。
- **OpenTelemetry** はこれらを _同期_ （counter、histogram など）と _非同期_ （登録されたコールバックで観測される）と呼びます。
  セマンティクスは同じです。

また、Prometheus の `Gauge` は2つの異なる OTel 計装タイプに対応することにも注意してください。非加算的な値（温度など）の `Gauge` と、増減可能な加算的な値（アクティブ接続数など）の `UpDownCounter` です。
詳細は [Gauge](#gauge) を参照してください。

### OTel: API と SDK {#otel-api-and-sdk}

OpenTelemetry は、計装と設定を2層設計で分離しています。**API** パッケージと **SDK** パッケージです。
API はメトリクスの記録に使用されるインターフェイスを定義します。
SDK は実装を提供します。具体的なプロバイダー、エクスポーター、処理パイプラインです。

計装コードは API のみに依存すべきです。
SDK はアプリケーション起動時に一度設定され、コードベースの他の部分に渡される API リファレンスに紐づけられます。
これにより、計装ライブラリコードが特定の SDK バージョンから切り離され、テスト用に no-op 実装に差し替えることが容易になります。

### OTel: 計装スコープ {#otel-instrumentation-scope}

Prometheus のメトリクスはグローバルです。プロセス内のすべてのメトリクスが同じフラットな名前空間を共有し、名前とラベルのみで識別されます。

OpenTelemetry は各計装グループを `Meter` にスコープします。`Meter` は名前とオプションのバージョン（たとえば `smart.home`）で識別されます。
Prometheus にエクスポートする際、スコープ名とバージョンはすべてのメトリクスポイントに `otel_scope_name` と `otel_scope_version` ラベルとして追加されます。
追加のスコープ属性もラベルとして追加され、`otel_scope_[attr name]` と名付けられます。
これらのラベルは自動的に表示されるため、Prometheus から来たユーザーには馴染みがないかもしれません。
エクスポーターの `without_scope_info` オプションで抑制できます。詳細は [Prometheus エクスポーター](/docs/specs/otel/metrics/sdk_exporters/prometheus/)設定リファレンスを参照してください。
スコープ情報の抑制は、各メトリクス名が単一のスコープによって生成される場合にのみ安全です。
2つのスコープが同じ名前のメトリクスを出力する場合、スコープラベルがそれらを区別する唯一の手段です。
これらのラベルがなければ、重複した時系列がオリジンを区別する方法なく生成され、Prometheus で無効な出力となります。

### OTel: 集約テンポラリティ {#otel-aggregation-temporality}

Prometheus のメトリクスは常に累積的です。
OpenTelemetry は累積とデルタの両方のテンポラリティをサポートしますが、Prometheus エクスポーターはすべての計装に累積を強制します。
Prometheus から移行する開発者にとって、これは透過的です。すでに依存している動作が保持されます。

### OTel: リソース属性 {#otel-resource-attributes}

Prometheus は `job` と `instance` ラベルを使用してスクレイプターゲットを識別します。これらは Prometheus サーバーによってスクレイプ時に追加されます。

OpenTelemetry には `Resource` があります。これはプロセスからのすべてのテレメトリーに付与される構造化メタデータで、`service.name` や `service.instance.id` などの属性を持ちます。
Prometheus にエクスポートする際、エクスポーターはリソース属性を `job` と `instance` ラベルにマッピングし、残りの属性は `target_info` メトリクスに公開されます（`target_info` は OpenMetrics 1.0 の規約です。Prometheus から手動で `target_info` を現在出力している場合、OTel での同等の方法はリソース属性を設定することです）。
正確なマッピングルールについては、[互換性仕様](/docs/specs/otel/compatibility/prometheus_and_openmetrics/)を参照してください。
`target_info` メトリクスは `without_target_info` で抑制でき、特定のリソース属性は `with_resource_constant_labels` でメトリクスレベルのラベルに昇格できます。
詳細は [Prometheus エクスポーター](/docs/specs/otel/metrics/sdk_exporters/prometheus/)設定リファレンスを参照してください。

## 初期化 {#initialization}

以下の例では、2つの主要なデプロイパターンを扱います。Prometheus スクレイプエンドポイントの公開と、OTLP エンドポイントへのプッシュです。

### Prometheus スクレイプエンドポイントの公開 {#expose-a-prometheus-scrape-endpoint}

   <ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-00-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-00-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <p>Prometheus</p>
<?code-excerpt "src/main/java/otel/PrometheusScrapeInit.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Counter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.exporter.httpserver.HTTPServer</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">java.io.IOException</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusScrapeInit</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">IOException</span><span class="p">,</span><span class="w"> </span><span class="n">InterruptedException</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// カウンターを作成し、デフォルトの PrometheusRegistry に登録する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Counter</span><span class="w"> </span><span class="n">doorOpens</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Counter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;door_opens_total&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;door&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// HTTP サーバーを起動する。Prometheus は http://localhost:9464/metrics をスクレイプする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">HTTPServer</span><span class="w"> </span><span class="n">server</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HTTPServer</span><span class="p">.</span><span class="na">builder</span><span class="p">().</span><span class="na">port</span><span class="p">(</span><span class="n">9464</span><span class="p">).</span><span class="na">buildAndStart</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">addShutdownHook</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">Thread</span><span class="p">(</span><span class="n">server</span><span class="p">::</span><span class="n">close</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">doorOpens</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;front&#34;</span><span class="p">).</span><span class="na">inc</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Thread</span><span class="p">.</span><span class="na">currentThread</span><span class="p">().</span><span class="na">join</span><span class="p">();</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelScrapeInit.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.LongCounter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.exporter.prometheus.PrometheusHttpServer</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.OpenTelemetrySdk</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.SdkMeterProvider</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelScrapeInit</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// 属性キーと、値が静的な場合は Attributes オブジェクト全体を事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DOOR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;door&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">FRONT_DOOR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DOOR</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;front&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">InterruptedException</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// SDK を設定する: /metrics を提供する Prometheus リーダーを登録する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">OpenTelemetrySdk</span><span class="w"> </span><span class="n">sdk</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">OpenTelemetrySdk</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setMeterProvider</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">SdkMeterProvider</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">.</span><span class="na">registerMetricReader</span><span class="p">(</span><span class="n">PrometheusHttpServer</span><span class="p">.</span><span class="na">builder</span><span class="p">().</span><span class="na">setPort</span><span class="p">(</span><span class="n">9464</span><span class="p">).</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">.</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">addShutdownHook</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">Thread</span><span class="p">(</span><span class="n">sdk</span><span class="p">::</span><span class="n">close</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 計装コードは SDK 型ではなく OpenTelemetry API 型を使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sdk</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// メトリクスは http://localhost:9464/metrics で提供される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">LongCounter</span><span class="w"> </span><span class="n">doorOpens</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">counterBuilder</span><span class="p">(</span><span class="s">&#34;door.opens&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">doorOpens</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">FRONT_DOOR</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Thread</span><span class="p">.</span><span class="na">currentThread</span><span class="p">().</span><span class="na">join</span><span class="p">();</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_scrape_init.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;net/http&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/prometheus/client_golang/prometheus/promhttp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// カウンターを作成し、カスタムレジストリに登録する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewRegistry</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewCounterVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">CounterOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">Name</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;door_opens_total&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">Help</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;door&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">doorOpens</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// Prometheus は http://localhost:9464/metrics をスクレイプする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">http</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span><span class="s">&#34;/metrics&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">promhttp</span><span class="p">.</span><span class="nf">HandlerFor</span><span class="p">(</span><span class="nx">reg</span><span class="p">,</span><span class="w"> </span><span class="nx">promhttp</span><span class="p">.</span><span class="nx">HandlerOpts</span><span class="p">{}))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">go</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nf">ListenAndServe</span><span class="p">(</span><span class="s">&#34;:9464&#34;</span><span class="p">,</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w"> </span><span class="cp">//nolint:errcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;front&#34;</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">select</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_scrape_init.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;net/http&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/prometheus/client_golang/prometheus/promhttp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/exporters/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sdkmetric</span><span class="w"> </span><span class="s">&#34;go.opentelemetry.io/otel/sdk/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ctx</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// SDK を設定する: /metrics を提供する Prometheus リーダーを登録する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">exporter</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">New</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">provider</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">NewMeterProvider</span><span class="p">(</span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">WithReader</span><span class="p">(</span><span class="nx">exporter</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">defer</span><span class="w"> </span><span class="nx">provider</span><span class="p">.</span><span class="nf">Shutdown</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span><span class="w"> </span><span class="cp">//nolint:errcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// メトリクスは http://localhost:9464/metrics で提供される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">http</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span><span class="s">&#34;/metrics&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">promhttp</span><span class="p">.</span><span class="nf">Handler</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">go</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nf">ListenAndServe</span><span class="p">(</span><span class="s">&#34;:9464&#34;</span><span class="p">,</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w"> </span><span class="cp">//nolint:errcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 計装コードは SDK ではなく API を直接使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">meter</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">provider</span><span class="p">.</span><span class="nf">Meter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Int64Counter</span><span class="p">(</span><span class="s">&#34;door.opens&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;door&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;front&#34;</span><span class="p">)))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">select</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>


### OTLP エンドポイントへのメトリクスプッシュ {#push-metrics-to-an-otlp-endpoint}

   <ul class="nav nav-tabs" id="tabs-1" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-01-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-01-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-01-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-01-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-1-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-01-00" role="tabpanel" aria-labelled-by="tabs-01-00-tab" tabindex="1">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusOtlpInit.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Counter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.exporter.opentelemetry.OpenTelemetryExporter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusOtlpInit</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// カウンターを作成し、デフォルトの PrometheusRegistry に登録する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Counter</span><span class="w"> </span><span class="n">doorOpens</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Counter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;door_opens_total&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;door&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// OTLP エクスポーターを起動する。デフォルトの PrometheusRegistry から読み取り、</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 設定されたエンドポイントに一定間隔でメトリクスをプッシュする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">OpenTelemetryExporter</span><span class="w"> </span><span class="n">exporter</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">OpenTelemetryExporter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">protocol</span><span class="p">(</span><span class="s">&#34;http/protobuf&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">endpoint</span><span class="p">(</span><span class="s">&#34;http://localhost:4318&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">intervalSeconds</span><span class="p">(</span><span class="n">60</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">buildAndStart</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">addShutdownHook</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">Thread</span><span class="p">(</span><span class="n">exporter</span><span class="p">::</span><span class="n">close</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">doorOpens</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;front&#34;</span><span class="p">).</span><span class="na">inc</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Thread</span><span class="p">.</span><span class="na">currentThread</span><span class="p">().</span><span class="na">join</span><span class="p">();</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelOtlpInit.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.LongCounter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.OpenTelemetrySdk</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.SdkMeterProvider</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.export.PeriodicMetricReader</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">java.time.Duration</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelOtlpInit</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">InterruptedException</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// SDK を設定する: OTLP/HTTP でメトリクスを一定間隔でエクスポートする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">OpenTelemetrySdk</span><span class="w"> </span><span class="n">sdk</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">OpenTelemetrySdk</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setMeterProvider</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">SdkMeterProvider</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">.</span><span class="na">registerMetricReader</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="n">PeriodicMetricReader</span><span class="p">.</span><span class="na">builder</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="n">OtlpHttpMetricExporter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                    </span><span class="p">.</span><span class="na">setEndpoint</span><span class="p">(</span><span class="s">&#34;http://localhost:4318&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                    </span><span class="p">.</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                            </span><span class="p">.</span><span class="na">setInterval</span><span class="p">(</span><span class="n">Duration</span><span class="p">.</span><span class="na">ofSeconds</span><span class="p">(</span><span class="n">60</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                            </span><span class="p">.</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">.</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">addShutdownHook</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">Thread</span><span class="p">(</span><span class="n">sdk</span><span class="p">::</span><span class="n">close</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 計装コードは SDK 型ではなく OpenTelemetry API 型を使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sdk</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">LongCounter</span><span class="w"> </span><span class="n">doorOpens</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">counterBuilder</span><span class="p">(</span><span class="s">&#34;door.opens&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">doorOpens</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Thread</span><span class="p">.</span><span class="na">currentThread</span><span class="p">().</span><span class="na">join</span><span class="p">();</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-01-01" role="tabpanel" aria-labelled-by="tabs-01-01-tab" tabindex="1">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<p>Prometheus Go クライアントライブラリには OTLP プッシュエクスポーターは含まれていません。</p>
<p>OpenTelemetry</p>
<?code-excerpt "otel_otlp_init.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sdkmetric</span><span class="w"> </span><span class="s">&#34;go.opentelemetry.io/otel/sdk/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ctx</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// SDK を設定する: OTLP/HTTP でメトリクスを一定間隔でエクスポートする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// エンドポイントのデフォルトは localhost:4318 で、</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// OTEL_EXPORTER_OTLP_ENDPOINT 環境変数で設定可能。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">exporter</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">otlpmetrichttp</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">provider</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">NewMeterProvider</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">WithReader</span><span class="p">(</span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">NewPeriodicReader</span><span class="p">(</span><span class="nx">exporter</span><span class="p">)),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">defer</span><span class="w"> </span><span class="nx">provider</span><span class="p">.</span><span class="nf">Shutdown</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span><span class="w"> </span><span class="cp">//nolint:errcheck</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">meter</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">provider</span><span class="p">.</span><span class="nf">Meter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Int64Counter</span><span class="p">(</span><span class="s">&#34;door.opens&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Total number of times a door has been opened&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">doorOpens</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;door&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;front&#34;</span><span class="p">)))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">select</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// 無限にスリープ</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>


## カウンター {#counter}

カウンターは単調増加する値を記録します。
Prometheus の `Counter` は OpenTelemetry の `Counter` 計装に対応します。

- **単位のエンコーディング**: Prometheus はメトリクス名に単位をエンコードします（`hvac_on_seconds_total`）。
  OpenTelemetry は名前（`hvac.on`）と単位（`s`）を分離し、Prometheus エクスポーターが自動的に単位接尾辞を付加します。

### カウンター {#counter-1}

Prometheus の `Counter` には、OpenTelemetry に同等機能がない2つのシリーズ管理機能があります。

- **シリーズの事前初期化**: Prometheus クライアントは、ラベル値の組み合わせを事前に初期化できるため、記録が発生する前にスクレイプ出力に値 0 で表示されます。
  OpenTelemetry にはこの同等機能がなく、データポイントは最初の `add()` 呼び出しで初めて表示されます。
- **事前バインドシリーズ**: Prometheus クライアントは `labelValues()` の結果をキャッシュして、特定のラベル値の組み合わせに事前バインドできます。
  以降の呼び出しは内部のシリーズ検索をスキップして、データポイントに直接アクセスします。
  OpenTelemetry にはこの同等機能がありませんが、[議論中](https://github.com/open-telemetry/opentelemetry-specification/issues/4126)です。

   <ul class="nav nav-tabs" id="tabs-2" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-02-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-02-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-02-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-02-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-2-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-02-00" role="tabpanel" aria-labelled-by="tabs-02-00-tab" tabindex="2">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusCounter.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Counter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusCounter</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">counterUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Counter</span><span class="w"> </span><span class="n">hvacOnTime</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Counter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;hvac_on_seconds_total&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Total time the HVAC system has been running, in seconds&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ラベル値セットに事前バインドする: 以降の呼び出しは内部のシリーズ検索をスキップして、</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// データポイントに直接アクセスする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">var</span><span class="w"> </span><span class="n">upstairs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hvacOnTime</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">var</span><span class="w"> </span><span class="n">downstairs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hvacOnTime</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">upstairs</span><span class="p">.</span><span class="na">inc</span><span class="p">(</span><span class="n">127</span><span class="p">.</span><span class="na">5</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">downstairs</span><span class="p">.</span><span class="na">inc</span><span class="p">(</span><span class="n">3600</span><span class="p">.</span><span class="na">0</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ゾーンを事前初期化して、起動時に /metrics に値 0 で表示されるようにする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">hvacOnTime</span><span class="p">.</span><span class="na">initLabelValues</span><span class="p">(</span><span class="s">&#34;basement&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelCounter.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.DoubleCounter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelCounter</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// 属性キーと、値が静的な場合は Attributes オブジェクト全体を事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ZONE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">counterUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// HVAC の稼働時間は小数値 — ofDoubles() で DoubleCounter を取得する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 事前のラベル宣言なし: 属性は記録時に提供される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">DoubleCounter</span><span class="w"> </span><span class="n">hvacOnTime</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">counterBuilder</span><span class="p">(</span><span class="s">&#34;hvac.on&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Total time the HVAC system has been running&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">ofDoubles</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">hvacOnTime</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">127</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">hvacOnTime</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">3600</span><span class="p">.</span><span class="na">0</span><span class="p">,</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>inc(value)</code> → <code>add(value)</code>。
Prometheus と異なり、OpenTelemetry では明示的な値が必要です。引数なしの <code>inc()</code> ショートハンドはありません。</li>
<li>OpenTelemetry は <code>LongCounter</code>（整数、デフォルト）と <code>DoubleCounter</code>（<code>.ofDoubles()</code> を介して、小数値用）を区別します。
Prometheus は単一の <code>Counter</code> 型を使用します。</li>
<li>ホットパスでの呼び出しごとのアロケーションを避けるため、<code>AttributeKey</code> インスタンス（常に）と <code>Attributes</code> オブジェクト（値が静的な場合）を事前に割り当てます。</li>
</ul>

    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-02-01" role="tabpanel" aria-labelled-by="tabs-02-01-tab" tabindex="2">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_counter.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">hvacOnTime</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewCounterVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">CounterOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;hvac_on_seconds_total&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;Total time the HVAC system has been running, in seconds&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;zone&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusCounterUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">hvacOnTime</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// ラベル値セットに事前バインドする: 以降の呼び出しはシリーズ検索を避ける。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">upstairs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">hvacOnTime</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">downstairs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">hvacOnTime</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">upstairs</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mf">127.5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">downstairs</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mf">3600.0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// シリーズを事前初期化して、/metrics に値 0 で表示されるようにする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">hvacOnTime</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;basement&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_counter.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 値が静的な場合、呼び出しごとのアロケーションを避けるために属性オプションを事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneUpstairsOpts</span><span class="w">   </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">AddOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneDownstairsOpts</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">AddOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelCounterUsage</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 事前のラベル宣言なし: 属性は記録時に提供される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">hvacOnTime</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64Counter</span><span class="p">(</span><span class="s">&#34;hvac.on&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Total time the HVAC system has been running&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">hvacOnTime</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">127.5</span><span class="p">,</span><span class="w"> </span><span class="nx">zoneUpstairsOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">hvacOnTime</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">3600.0</span><span class="p">,</span><span class="w"> </span><span class="nx">zoneDownstairsOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>Add(value)</code> → <code>Add(ctx, value, metric.WithAttributes(...))</code>。
すべての計装呼び出しで、最初の引数に <code>context.Context</code> が必要です。</li>
<li>Go では、<code>meter.Float64Counter</code> と <code>meter.Int64Counter</code> は別々のメソッドです。
Prometheus は単一の <code>Counter</code> 型を使用します。</li>
<li>計装の作成は <code>(Instrument, error)</code> を返し、エラーを処理する必要があります。</li>
</ul>

    </div>
</div>


### コールバック（非同期）カウンター {#callback-async-counter}

コールバックカウンター（OpenTelemetry では非同期カウンター）は、合計値がデバイスやランタイムなどの外部ソースによって管理されている場合に使用します。
自分でインクリメントするのではなく、収集時に値を観測します。

   <ul class="nav nav-tabs" id="tabs-3" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-03-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-03-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-03-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-03-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-03-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-03-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-3-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-03-00" role="tabpanel" aria-labelled-by="tabs-03-00-tab" tabindex="3">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusCounterCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.CounterWithCallback</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusCounterCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">counterCallbackUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 各ゾーンには累積ジュール合計を追跡するスマートエネルギーメーターがある。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// コールバックカウンターを使用して、アプリケーションコードで別途カウンターを</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 管理することなく、スクレイプ時にそれらの値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">CounterWithCallback</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;energy_consumed_joules_total&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Total energy consumed in joules&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">callback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">callback</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelCounterCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelCounterCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ZONE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">counterCallbackUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 各ゾーンには累積ジュール合計を追跡するスマートエネルギーメーターがある。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 非同期カウンターを使用して、アプリケーションコードで別途カウンターを管理する</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ことなく、MetricReader がメトリクスを収集する際にそれらの値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">counterBuilder</span><span class="p">(</span><span class="s">&#34;energy.consumed&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Total energy consumed&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;J&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">ofDoubles</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">buildWithCallback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">measurement</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li>OpenTelemetry は整数と浮動小数点のカウンターを区別します。
<code>.ofDoubles()</code> で浮動小数点バリアントを選択します。
Prometheus の <code>CounterWithCallback</code> は常に浮動小数点値を使用します。</li>
</ul>

    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-03-01" role="tabpanel" aria-labelled-by="tabs-03-01-tab" tabindex="3">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_counter_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">energyCollector</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">desc</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">newEnergyCollector</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="nx">energyCollector</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">energyCollector</span><span class="p">{</span><span class="nx">desc</span><span class="p">:</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewDesc</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;energy_consumed_joules_total&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;Total energy consumed in joules&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;zone&#34;</span><span class="p">},</span><span class="w"> </span><span class="kc">nil</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">energyCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Describe</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">energyCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Collect</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Metric</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">CounterValue</span><span class="p">,</span><span class="w"> </span><span class="nf">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">CounterValue</span><span class="p">,</span><span class="w"> </span><span class="nf">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusCounterCallbackUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 各ゾーンには累積ジュール合計を追跡するスマートエネルギーメーターがある。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// スクレイプ時にそれらの値を報告するために prometheus.Collector を実装する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nf">newEnergyCollector</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_counter_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneUpstairs</span><span class="w">   </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneDownstairs</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelCounterCallbackUsage</span><span class="p">(</span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 各ゾーンには累積ジュール合計を追跡するスマートエネルギーメーターがある。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// メトリクス収集時にそれらの値を報告するために observable カウンターを使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64ObservableCounter</span><span class="p">(</span><span class="s">&#34;energy.consumed&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Total energy consumed&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;J&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithFloat64Callback</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">_</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">o</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Float64Observer</span><span class="p">)</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nf">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">zoneUpstairs</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nf">totalEnergyJoules</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">zoneDownstairs</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">return</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">}))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li>Prometheus の例は <code>prometheus.Collector</code> を <code>Describe</code> と <code>Collect</code> メソッドで実装し、ラベル付きカウンター値を報告します。</li>
<li>OpenTelemetry は <code>Float64ObservableCounter</code> と <code>Int64ObservableCounter</code> を区別します。</li>
</ul>

    </div>
</div>


## ゲージ {#gauge}

ゲージは増減可能な瞬時値を記録します。
Prometheus はすべてのそのような値に単一の `Gauge` 型を使用しますが、OpenTelemetry は適切な計装を選択する際に **加算的** な値と **非加算的** な値を区別します。

- **非加算的** な値は、インスタンス間で意味のある合計を算出できません。たとえば温度です。3つの部屋のセンサーの読み取り値を足しても有用な数値にはなりません。
  これらは OTel の `Gauge` と `ObservableGauge` に対応します。
- **加算的** な値は、インスタンス間で意味のある合計を算出できます。たとえば、サービスインスタンス間で合計した接続デバイス数は有用な合計値になります。
  これらは OTel の `UpDownCounter` と `ObservableUpDownCounter` に対応します。

この区別は、abs、inc と dec、およびコールバックのバリアントを含むすべてのゲージパターンに適用されます。
詳細な説明は[計装選択ガイド](/docs/specs/otel/metrics/supplementary-guidelines/#instrument-selection)を参照してください。

### ゲージ — abs {#gauge--abs}

絶対値として記録される値（設定値やデバイスのセットポイントなど）にはこのパターンを使用します。
Prometheus の `Gauge` は OpenTelemetry の `Gauge` 計装に対応します。

   <ul class="nav nav-tabs" id="tabs-4" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-04-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-04-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-04-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-04-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-4-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-04-00" role="tabpanel" aria-labelled-by="tabs-04-00-tab" tabindex="4">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusGauge.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Gauge</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusGauge</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">gaugeUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Gauge</span><span class="w"> </span><span class="n">thermostatSetpoint</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Gauge</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;thermostat_setpoint_celsius&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Target temperature set on the thermostat&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">thermostatSetpoint</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">).</span><span class="na">set</span><span class="p">(</span><span class="n">22</span><span class="p">.</span><span class="na">5</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">thermostatSetpoint</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">).</span><span class="na">set</span><span class="p">(</span><span class="n">20</span><span class="p">.</span><span class="na">0</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelGauge.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.DoubleGauge</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelGauge</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// 属性キーと、値が静的な場合は Attributes オブジェクト全体を事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ZONE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ZONE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">gaugeUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">DoubleGauge</span><span class="w"> </span><span class="n">thermostatSetpoint</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">gaugeBuilder</span><span class="p">(</span><span class="s">&#34;thermostat.setpoint&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Target temperature set on the thermostat&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;Cel&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">thermostatSetpoint</span><span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="n">22</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">UPSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">thermostatSetpoint</span><span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="n">20</span><span class="p">.</span><span class="na">0</span><span class="p">,</span><span class="w"> </span><span class="n">DOWNSTAIRS</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>set(value)</code> → <code>set(value, attributes)</code>。
メソッド名は同じです。</li>
<li>OpenTelemetry は <code>LongGauge</code>（整数、<code>.ofLongs()</code> を介して）と <code>DoubleGauge</code>（デフォルト）を区別します。
Prometheus は単一の <code>Gauge</code> 型を使用します。</li>
<li>ホットパスでの呼び出しごとのアロケーションを避けるため、<code>AttributeKey</code> インスタンス（常に）と <code>Attributes</code> オブジェクト（値が静的な場合）を事前に割り当てます。</li>
</ul>

    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-04-01" role="tabpanel" aria-labelled-by="tabs-04-01-tab" tabindex="4">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_gauge.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">thermostatSetpoint</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewGaugeVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;thermostat_setpoint_celsius&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;Target temperature set on the thermostat&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;zone&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusGaugeUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">thermostatSetpoint</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">thermostatSetpoint</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;upstairs&#34;</span><span class="p">).</span><span class="nf">Set</span><span class="p">(</span><span class="mf">22.5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">thermostatSetpoint</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;downstairs&#34;</span><span class="p">).</span><span class="nf">Set</span><span class="p">(</span><span class="mf">20.0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_gauge.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 値が静的な場合、呼び出しごとのアロケーションを避けるために属性オプションを事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneUpstairsGaugeOpts</span><span class="w">   </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;upstairs&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">zoneDownstairsGaugeOpts</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;zone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;downstairs&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelGaugeUsage</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">thermostatSetpoint</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64Gauge</span><span class="p">(</span><span class="s">&#34;thermostat.setpoint&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Target temperature set on the thermostat&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;Cel&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">thermostatSetpoint</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">22.5</span><span class="p">,</span><span class="w"> </span><span class="nx">zoneUpstairsGaugeOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">thermostatSetpoint</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">20.0</span><span class="p">,</span><span class="w"> </span><span class="nx">zoneDownstairsGaugeOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>Set(value)</code> → <code>Record(ctx, value, metric.WithAttributes(...))</code>。</li>
<li>Go では、<code>meter.Float64Gauge</code> と <code>meter.Int64Gauge</code> は別々のメソッドです。
Prometheus は単一の <code>Gauge</code> 型を使用します。</li>
</ul>

    </div>
</div>


### コールバックゲージ — abs {#callback-gauge--abs}

コールバックゲージ（OpenTelemetry では非同期ゲージ）は、センサーの読み取り値のような非加算的な値が外部で管理されている場合に、自分で追跡するのではなく収集時に観測するために使用します。

   <ul class="nav nav-tabs" id="tabs-5" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-05-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-05-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-05-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-05-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-5-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-05-00" role="tabpanel" aria-labelled-by="tabs-05-00-tab" tabindex="5">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusGaugeCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.GaugeWithCallback</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusGaugeCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">gaugeCallbackUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 温度センサーはファームウェア内で自身の読み取り値を管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// コールバックゲージを使用して、アプリケーションコードで別途ゲージを</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 管理することなく、スクレイプ時にそれらの値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">GaugeWithCallback</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;room_temperature_celsius&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Current temperature in the room&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;room&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">callback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">callback</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">livingRoomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="s">&#34;living_room&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">bedroomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="s">&#34;bedroom&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelGaugeCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelGaugeCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ROOM</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;room&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">LIVING_ROOM</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ROOM</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;living_room&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">BEDROOM</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">ROOM</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;bedroom&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">gaugeCallbackUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 温度センサーはファームウェア内で自身の読み取り値を管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 非同期ゲージを使用して、アプリケーションコードで別途ゲージを管理することなく、</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// MetricReader がメトリクスを収集する際にそれらの値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">gaugeBuilder</span><span class="p">(</span><span class="s">&#34;room.temperature&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Current temperature in the room&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;Cel&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">buildWithCallback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">measurement</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">livingRoomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="n">LIVING_ROOM</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">bedroomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="n">BEDROOM</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-05-01" role="tabpanel" aria-labelled-by="tabs-05-01-tab" tabindex="5">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_gauge_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">temperatureCollector</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">desc</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">newTemperatureCollector</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="nx">temperatureCollector</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">temperatureCollector</span><span class="p">{</span><span class="nx">desc</span><span class="p">:</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewDesc</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;room_temperature_celsius&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;Current temperature in the room&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;room&#34;</span><span class="p">},</span><span class="w"> </span><span class="kc">nil</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">temperatureCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Describe</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">temperatureCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Collect</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Metric</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeValue</span><span class="p">,</span><span class="w"> </span><span class="nf">livingRoomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="s">&#34;living_room&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeValue</span><span class="p">,</span><span class="w"> </span><span class="nf">bedroomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="s">&#34;bedroom&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusGaugeCallbackUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 温度センサーはファームウェア内で自身の読み取り値を管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// スクレイプ時にそれらの値を報告するために prometheus.Collector を実装する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nf">newTemperatureCollector</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_gauge_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">roomLivingRoom</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;room&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;living_room&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">roomBedroom</span><span class="w">    </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;room&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;bedroom&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelGaugeCallbackUsage</span><span class="p">(</span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 温度センサーはファームウェア内で自身の読み取り値を管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// メトリクス収集時にそれらの値を報告するために observable ゲージを使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64ObservableGauge</span><span class="p">(</span><span class="s">&#34;room.temperature&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Current temperature in the room&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;Cel&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithFloat64Callback</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">_</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">o</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Float64Observer</span><span class="p">)</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nf">livingRoomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">roomLivingRoom</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nf">bedroomTemperatureCelsius</span><span class="p">(),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">roomBedroom</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">return</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">}))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li>Prometheus の例は <code>prometheus.Collector</code> を <code>Describe</code> と <code>Collect</code> メソッドで実装し、ラベル付きゲージ値を報告します。</li>
</ul>

    </div>
</div>


### ゲージ — inc と dec {#gauge--inc-and-dec}

Prometheus の `Gauge` は、接続デバイス数やアクティブセッション数のように徐々に変化する値のインクリメントとデクリメントをサポートします。
OpenTelemetry の `Gauge` は絶対値のみを記録するため、このパターンは OpenTelemetry の `UpDownCounter` 計装に対応します。

   <ul class="nav nav-tabs" id="tabs-6" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-06-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-06-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-06-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-06-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-06-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-06-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-6-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-06-00" role="tabpanel" aria-labelled-by="tabs-06-00-tab" tabindex="6">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusUpDownCounter.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Gauge</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusUpDownCounter</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">upDownCounterUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Prometheus は増減可能な値に Gauge を使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Gauge</span><span class="w"> </span><span class="n">devicesConnected</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Gauge</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;devices_connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// デバイス接続時にインクリメント、切断時にデクリメントする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="na">inc</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="na">inc</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="na">inc</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="na">dec</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelUpDownCounter.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.LongUpDownCounter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelUpDownCounter</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// 属性キーと、値が静的な場合は Attributes オブジェクト全体を事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DEVICE_TYPE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">LOCK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">upDownCounterUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">LongUpDownCounter</span><span class="w"> </span><span class="n">devicesConnected</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">upDownCounterBuilder</span><span class="p">(</span><span class="s">&#34;devices.connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// add() は正の値と負の値の両方を受け付ける。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">LOCK</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">devicesConnected</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="o">-</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">LOCK</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>inc()</code> / <code>dec()</code> → <code>add(1)</code> / <code>add(-1)</code>。
<code>add()</code> は正の値と負の値の両方を受け付けます。</li>
<li>Prometheus の型は <code>Gauge</code>、OpenTelemetry の型は <code>LongUpDownCounter</code>（または <code>.ofDoubles()</code> を介した <code>DoubleUpDownCounter</code>）です。</li>
</ul>

    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-06-01" role="tabpanel" aria-labelled-by="tabs-06-01-tab" tabindex="6">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_up_down_counter.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Prometheus は増減可能な値に Gauge を使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">devicesConnected</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewGaugeVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;devices_connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;device_type&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusUpDownCounterUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">devicesConnected</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// デバイス接続時にインクリメント、切断時にデクリメントする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="nf">Dec</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_up_down_counter.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 値が静的な場合、呼び出しごとのアロケーションを避けるために属性オプションを事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceThermostatAddOpts</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">AddOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceLockAddOpts</span><span class="w">       </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">AddOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelUpDownCounterUsage</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Int64UpDownCounter</span><span class="p">(</span><span class="s">&#34;devices.connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// Add() は正の値と負の値の両方を受け付ける。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceThermostatAddOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceThermostatAddOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceLockAddOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">devicesConnected</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceLockAddOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>Inc()</code> / <code>Dec()</code> → <code>Add(ctx, 1, ...)</code> / <code>Add(ctx, -1, ...)</code>。
<code>Add()</code> は正の値と負の値の両方を受け付けます。</li>
<li>Prometheus の型は <code>Gauge</code>、OpenTelemetry の型は <code>Int64UpDownCounter</code>（または <code>meter.Float64UpDownCounter</code> を介した <code>Float64UpDownCounter</code>）です。</li>
</ul>

    </div>
</div>


### コールバックゲージ — inc と dec {#callback-gauge--inc-and-dec}

コールバックゲージ（OpenTelemetry では非同期 UpDownCounter）は、通常 `inc()`/`dec()` で追跡されるような加算的なカウントが、デバイスマネージャーやコネクションプールなどの外部で管理されている場合に、収集時に観測するために使用します。

   <ul class="nav nav-tabs" id="tabs-7" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-07-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-07-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-07-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-07-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-07-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-07-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-7-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-07-00" role="tabpanel" aria-labelled-by="tabs-07-00-tab" tabindex="7">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusUpDownCounterCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.GaugeWithCallback</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusUpDownCounterCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">upDownCounterCallbackUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// デバイスマネージャーが接続デバイスのカウントを管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// コールバックゲージを使用して、スクレイプ時にその値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">GaugeWithCallback</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;devices_connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">callback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">callback</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">callback</span><span class="p">.</span><span class="na">call</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">),</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelUpDownCounterCallback.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelUpDownCounterCallback</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DEVICE_TYPE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">LOCK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">upDownCounterCallbackUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// デバイスマネージャーが接続デバイスのカウントを管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 非同期 UpDownCounter を使用して、MetricReader がメトリクスを収集する際に</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// その値を報告する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">upDownCounterBuilder</span><span class="p">(</span><span class="s">&#34;devices.connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">buildWithCallback</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">measurement</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="n">measurement</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">SmartHomeDevices</span><span class="p">.</span><span class="na">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">LOCK</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-07-01" role="tabpanel" aria-labelled-by="tabs-07-01-tab" tabindex="7">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_up_down_counter_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">deviceCountCollector</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">desc</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">newDeviceCountCollector</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="nx">deviceCountCollector</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">deviceCountCollector</span><span class="p">{</span><span class="nx">desc</span><span class="p">:</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewDesc</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;devices_connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;device_type&#34;</span><span class="p">},</span><span class="w"> </span><span class="kc">nil</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">deviceCountCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Describe</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Desc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="nx">deviceCountCollector</span><span class="p">)</span><span class="w"> </span><span class="nf">Collect</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Metric</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeValue</span><span class="p">,</span><span class="w"> </span><span class="nb">float64</span><span class="p">(</span><span class="nf">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">)),</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">MustNewConstMetric</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">desc</span><span class="p">,</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">GaugeValue</span><span class="p">,</span><span class="w"> </span><span class="nb">float64</span><span class="p">(</span><span class="nf">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">)),</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusUpDownCounterCallbackUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// デバイスマネージャーが接続デバイスのカウントを管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// スクレイプ時にそれらの値を報告するために prometheus.Collector を実装する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nf">newDeviceCountCollector</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_up_down_counter_callback.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceThermostat</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceLock</span><span class="w">       </span><span class="p">=</span><span class="w"> </span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelUpDownCounterCallbackUsage</span><span class="p">(</span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// デバイスマネージャーが接続デバイスのカウントを管理している。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// メトリクス収集時にその値を報告するために observable UpDownCounter を使用する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Int64ObservableUpDownCounter</span><span class="p">(</span><span class="s">&#34;devices.connected&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Number of smart home devices currently connected&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithInt64Callback</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">_</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">o</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Int64Observer</span><span class="p">)</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nb">int64</span><span class="p">(</span><span class="nf">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">)),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">deviceThermostat</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">o</span><span class="p">.</span><span class="nf">Observe</span><span class="p">(</span><span class="nb">int64</span><span class="p">(</span><span class="nf">connectedDeviceCount</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">)),</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">deviceLock</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">return</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">}))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li>Prometheus の例は <code>prometheus.Collector</code> を <code>Describe</code> と <code>Collect</code> メソッドで実装し、ラベル付きゲージ値を報告します。</li>
<li><code>Int64ObservableUpDownCounter</code> は <code>metric.WithInt64Callback</code> を使用します。</li>
</ul>

    </div>
</div>


## ヒストグラム {#histogram}

ヒストグラムは一連の計測の分布を記録し、観測のカウント、合計、および設定可能なバケット境界内に収まる数を追跡します。

Prometheus と OpenTelemetry の両方が、クラシック（明示的バケット）ヒストグラムとネイティブ（base2 指数）ヒストグラムをサポートしています。
Prometheus にはさらに `Summary` 型がありますが、OTel には直接的な同等物がありません。以下の [Summary](#summary) を参照してください。

Prometheus の `Histogram` は OpenTelemetry の `Histogram` 計装に対応します。

### クラシック（明示的）ヒストグラム {#classic-explicit-histogram}

両方のシステムがクラシックヒストグラムをサポートしており、固定されたバケット境界が観測を離散的な範囲に分割します。

- **バケット設定**: Prometheus は作成時に計装自体にバケット境界を宣言します。
  OpenTelemetry では、バケット境界は計装にヒントとして設定されますが、SDK レベルで設定されたビューによってオーバーライドまたは置換できます。
  この分離により、計装コードが収集設定から独立したままになります。
  境界が指定されず、ビューも設定されていない場合、SDK はミリ秒スケールのレイテンシ用に設計されたデフォルトセット（`[0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000]`）を使用しますが、秒スケールの計測には適していない可能性があります。
  既存のヒストグラムを移行する際は、常に境界を提供するかビューを設定してください。

   <ul class="nav nav-tabs" id="tabs-8" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-08-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-08-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-08-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-08-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-08-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-08-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-8-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-08-00" role="tabpanel" aria-labelled-by="tabs-08-00-tab" tabindex="8">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusHistogram.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Histogram</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusHistogram</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">histogramUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Histogram</span><span class="w"> </span><span class="n">deviceCommandDuration</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Histogram</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">classicUpperBounds</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">1</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">25</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">1</span><span class="p">.</span><span class="na">0</span><span class="p">,</span><span class="w"> </span><span class="n">2</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">5</span><span class="p">.</span><span class="na">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">35</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">85</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelHistogram.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.DoubleHistogram</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.List</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelHistogram</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// 属性キーと、値が静的な場合は Attributes オブジェクト全体を事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DEVICE_TYPE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">LOCK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">histogramUsage</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// setExplicitBucketBoundariesAdvice() は SDK へのヒントとしてデフォルトの境界を設定する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// SDK レベルで設定されたビューはこのアドバイスよりも優先される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">DoubleHistogram</span><span class="w"> </span><span class="n">deviceCommandDuration</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">histogramBuilder</span><span class="p">(</span><span class="s">&#34;device.command.duration&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setExplicitBucketBoundariesAdvice</span><span class="p">(</span><span class="n">List</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">1</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">25</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">1</span><span class="p">.</span><span class="na">0</span><span class="p">,</span><span class="w"> </span><span class="n">2</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">5</span><span class="p">.</span><span class="na">0</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">35</span><span class="p">,</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">85</span><span class="p">,</span><span class="w"> </span><span class="n">LOCK</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>observe(value)</code> → <code>record(value, attributes)</code>。</li>
<li>OpenTelemetry は <code>LongHistogram</code>（整数、<code>.ofLongs()</code> を介して）と <code>DoubleHistogram</code>（デフォルト）を区別します。
Prometheus は単一の <code>Histogram</code> 型を使用します。</li>
<li>ホットパスでの呼び出しごとのアロケーションを避けるため、<code>AttributeKey</code> インスタンス（常に）と <code>Attributes</code> オブジェクト（値が静的な場合）を事前に割り当てます。</li>
<li>SDK のビューは <code>setExplicitBucketBoundariesAdvice()</code> で設定された境界をオーバーライドでき、属性フィルタリング、最小/最大値の記録、計装のリネームなど、ヒストグラム収集の他の側面も設定できます。</li>
</ul>

    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-08-01" role="tabpanel" aria-labelled-by="tabs-08-01-tab" tabindex="8">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_histogram.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">deviceCommandDuration</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewHistogramVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">HistogramOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w">    </span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w">    </span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Buckets</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="kt">float64</span><span class="p">{</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.25</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="mf">2.5</span><span class="p">,</span><span class="w"> </span><span class="mf">5.0</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;device_type&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">prometheusHistogramUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">deviceCommandDuration</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.35</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.85</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_histogram.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 値が静的な場合、呼び出しごとのアロケーションを避けるために属性オプションを事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceThermostatOpts</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceLockOpts</span><span class="w">       </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">otelHistogramUsage</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// WithExplicitBucketBoundaries は SDK へのヒントとしてデフォルトの境界を設定する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// SDK レベルで設定されたビューはこのヒントよりも優先される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64Histogram</span><span class="p">(</span><span class="s">&#34;device.command.duration&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithExplicitBucketBoundaries</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.25</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="mf">2.5</span><span class="p">,</span><span class="w"> </span><span class="mf">5.0</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">0.35</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceThermostatOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">0.85</span><span class="p">,</span><span class="w"> </span><span class="nx">deviceLockOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li><code>Observe(value)</code> → <code>Record(ctx, value, metric.WithAttributes(...))</code>。</li>
<li>Go では、<code>metric.WithExplicitBucketBoundaries(...)</code> は可変長引数です（スライスではありません）。
Prometheus は <code>HistogramOpts</code> の <code>Buckets</code> フィールドを使用します。</li>
<li>SDK のビューは <code>WithExplicitBucketBoundaries()</code> で設定された境界をオーバーライドでき、属性フィルタリング、最小/最大値の記録、計装のリネームなど、ヒストグラム収集の他の側面も設定できます。</li>
</ul>

    </div>
</div>


### ネイティブ（base2 指数）ヒストグラム {#native-base2-exponential-histogram}

両方のシステムがネイティブ（base2 指数）ヒストグラムをサポートしており、手動設定なしで観測範囲をカバーするようにバケット境界を自動調整します。

- **フォーマット選択**: Prometheus の計装は、クラシックフォーマットのみ、ネイティブフォーマットのみ、または両方を同時に出力できます。これにより、計装の変更なしで段階的な移行が可能です。
  OpenTelemetry では、フォーマット選択は計装コードの外部で、エクスポーターまたはビューを介して設定されるため、計装コードはどちらの場合も変更不要です。
- **計装コード**: OpenTelemetry の計装コードは、クラシックヒストグラムとネイティブヒストグラムで同一です。
  同じ `record()` 呼び出しが、SDK の設定に応じてどちらのフォーマットも生成します。

   <ul class="nav nav-tabs" id="tabs-9" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-09-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-09-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-09-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-09-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-09-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-09-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-9-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-09-00" role="tabpanel" aria-labelled-by="tabs-09-00-tab" tabindex="9">
        <p>Prometheus</p>
<p>Prometheus では、ヒストグラムフォーマットは計装作成時に制御されます。
以下の例では <code>.nativeOnly()</code> を使用してネイティブフォーマットに限定しています。これを省略すると、クラシックとネイティブの両方のフォーマットが同時に出力されます。</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusHistogramNative.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Histogram</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusHistogramNative</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">nativeHistogramUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Histogram</span><span class="w"> </span><span class="n">deviceCommandDuration</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Histogram</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">nativeOnly</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">35</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">85</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-09-01" role="tabpanel" aria-labelled-by="tabs-09-01-tab" tabindex="9">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<p>Prometheus では、<code>NativeHistogramBucketFactor</code> を設定するとクラシックバケット設定と並行してネイティブヒストグラムが有効になり、両方のフォーマットが同時に報告されます。</p>
<?code-excerpt "prometheus_histogram_native.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">nativeDeviceCommandDuration</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewHistogramVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">HistogramOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w">                        </span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w">                        </span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">NativeHistogramBucketFactor</span><span class="p">:</span><span class="w"> </span><span class="mf">1.1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;device_type&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">nativeHistogramUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">nativeDeviceCommandDuration</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">nativeDeviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.35</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">nativeDeviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.85</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>主な違い:</p>
<ul>
<li>Go でネイティブヒストグラムを有効にするには、<code>NativeHistogramBucketFactor</code> を 1.0 より大きい値に設定する必要があります。必須パラメーターです。
0（ゼロ値）に設定するとネイティブヒストグラムは完全に無効になります。
この値は連続するバケット境界間の最大比率を制御します。値が小さいほど解像度が高くなりますが、バケット数が増えます。
よく使われる値 <code>1.1</code> と同等のバケット密度に近似するには、<code>AggregationBase2ExponentialHistogram</code> で <code>MaxScale: 3</code> を設定します。</li>
</ul>

    </div>
</div>


OpenTelemetry では、計装コードはクラシックヒストグラムの場合と同一です。
base2 指数フォーマットは、計装レイヤーの外部で別途設定されます。

推奨されるアプローチは、メトリクスエクスポーターで設定することです。
これにより、計装コードに手を加えることなく、そのエクスポーターを通じてエクスポートされるすべてのヒストグラムに適用されます。

   <ul class="nav nav-tabs" id="tabs-10" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-10-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-10-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-10-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-10-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-10-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-10-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-10-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-10-00" role="tabpanel" aria-labelled-by="tabs-10-00-tab" tabindex="10">
        <?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/OtelHistogramExponentialExporter.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.Aggregation</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.InstrumentType</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelHistogramExponentialExporter</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">static</span><span class="w"> </span><span class="n">OtlpHttpMetricExporter</span><span class="w"> </span><span class="nf">createExporter</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// すべてのヒストグラム計装に指数ヒストグラムを使用するようにエクスポーターを設定する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// これが推奨アプローチ — 計装コードを変更せずにグローバルに適用される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">OtlpHttpMetricExporter</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setEndpoint</span><span class="p">(</span><span class="s">&#34;http://localhost:4318&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">setDefaultAggregationSelector</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">DefaultAggregationSelector</span><span class="p">.</span><span class="na">getDefault</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">with</span><span class="p">(</span><span class="n">InstrumentType</span><span class="p">.</span><span class="na">HISTOGRAM</span><span class="p">,</span><span class="w"> </span><span class="n">Aggregation</span><span class="p">.</span><span class="na">base2ExponentialBucketHistogram</span><span class="p">()))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-10-01" role="tabpanel" aria-labelled-by="tabs-10-01-tab" tabindex="10">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<?code-excerpt "otel_histogram_exponential_exporter.go" region="createExponentialExporter"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sdkmetric</span><span class="w"> </span><span class="s">&#34;go.opentelemetry.io/otel/sdk/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">createExponentialExporter</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="nx">otlpmetrichttp</span><span class="p">.</span><span class="nx">Exporter</span><span class="p">,</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// すべてのヒストグラム計装に指数ヒストグラムを使用するようにエクスポーターを設定する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// これが推奨アプローチ — 計装コードを変更せずにグローバルに適用される。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="nx">otlpmetrichttp</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">otlpmetrichttp</span><span class="p">.</span><span class="nf">WithAggregationSelector</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">ik</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">InstrumentKind</span><span class="p">)</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">Aggregation</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">if</span><span class="w"> </span><span class="nx">ik</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">InstrumentKindHistogram</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="k">return</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">AggregationBase2ExponentialHistogram</span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">return</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">DefaultAggregationSelector</span><span class="p">(</span><span class="nx">ik</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">}),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>


よりきめ細かい制御が必要な場合、たとえば特定の計装に base2 指数ヒストグラムを使用し、他は明示的バケットを維持する場合は、ビューを設定します。

   <ul class="nav nav-tabs" id="tabs-11" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-11-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-11-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-11-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-11-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-11-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-11-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-11-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-11-00" role="tabpanel" aria-labelled-by="tabs-11-00-tab" tabindex="11">
        <?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/OtelHistogramExponentialView.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.Aggregation</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.InstrumentSelector</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.SdkMeterProvider</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.sdk.metrics.View</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelHistogramExponentialView</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">static</span><span class="w"> </span><span class="n">SdkMeterProvider</span><span class="w"> </span><span class="nf">createMeterProvider</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 計装ごとの制御にビューを使用する — 特定の計装を名前で選択して</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 指数ヒストグラムを使用し、他は明示的バケットを維持する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">SdkMeterProvider</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">registerView</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">InstrumentSelector</span><span class="p">.</span><span class="na">builder</span><span class="p">().</span><span class="na">setName</span><span class="p">(</span><span class="s">&#34;device.command.duration&#34;</span><span class="p">).</span><span class="na">build</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">View</span><span class="p">.</span><span class="na">builder</span><span class="p">().</span><span class="na">setAggregation</span><span class="p">(</span><span class="n">Aggregation</span><span class="p">.</span><span class="na">base2ExponentialBucketHistogram</span><span class="p">()).</span><span class="na">build</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-11-01" role="tabpanel" aria-labelled-by="tabs-11-01-tab" tabindex="11">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<?code-excerpt "otel_histogram_exponential.go" region="createExponentialView"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">createExponentialView</span><span class="p">()</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">View</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 計装ごとの制御にビューを使用する — 特定の計装を名前で選択して</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 指数ヒストグラムを使用し、他は明示的バケットを維持する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nf">NewView</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">Instrument</span><span class="p">{</span><span class="nx">Name</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;device.command.duration&#34;</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">Stream</span><span class="p">{</span><span class="nx">Aggregation</span><span class="p">:</span><span class="w"> </span><span class="nx">sdkmetric</span><span class="p">.</span><span class="nx">AggregationBase2ExponentialHistogram</span><span class="p">{}!},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>


### Summary {#summary}

Prometheus の `Summary` は、スクレイプ時にクライアント側でクォンタイルを計算し、ラベル付き時系列として公開します（たとえば `{quantile="0.95"}`）。
OpenTelemetry には直接的な同等物がありません。

クォンタイル推定には、**base2 指数ヒストグラム** が推奨される代替手段です。
観測範囲をカバーするようにバケット境界を自動調整し、PromQL の `histogram_quantile()` がクエリ時に限定的な誤差でクォンタイルを計算できます。
`Summary` と異なり、結果はインスタンス間で集約可能です。
[ネイティブ（base2 指数）ヒストグラム](#native-base2-exponential-histogram)を参照してください。

カウントと合計のみが必要でクォンタイルが不要な場合、明示的バケット境界のないヒストグラムがこれらの統計値を最小限のオーバーヘッドでキャプチャします。
以下の例はこのシンプルなアプローチを示しています。

   <ul class="nav nav-tabs" id="tabs-12" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-12-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-12-00" role="tab"
          data-td-tp-persist="java" aria-controls="tabs-12-00" aria-selected="true">
        Java
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-12-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-12-01" role="tab"
          data-td-tp-persist="go" aria-controls="tabs-12-01" aria-selected="false">
        Go
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-12-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-12-00" role="tabpanel" aria-labelled-by="tabs-12-00-tab" tabindex="12">
        <p>Prometheus</p>
<?code-excerpt path-base="examples/java/prometheus-compatibility"?>
<?code-excerpt "src/main/java/otel/PrometheusSummary.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.prometheus.metrics.core.metrics.Summary</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PrometheusSummary</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">summaryUsage</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Summary</span><span class="w"> </span><span class="n">deviceCommandDuration</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Summary</span><span class="p">.</span><span class="na">builder</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">name</span><span class="p">(</span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">help</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">labelNames</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">quantile</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">5</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">05</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">quantile</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">95</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">01</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">quantile</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">99</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">001</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">register</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">35</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">labelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="na">observe</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">85</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "src/main/java/otel/OtelHistogramAsSummary.java"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nn">otel</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.OpenTelemetry</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.AttributeKey</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.common.Attributes</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.DoubleHistogram</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">io.opentelemetry.api.metrics.Meter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.List</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">OtelHistogramAsSummary</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">AttributeKey</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DEVICE_TYPE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AttributeKey</span><span class="p">.</span><span class="na">stringKey</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Attributes</span><span class="w"> </span><span class="n">LOCK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Attributes</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">DEVICE_TYPE</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">summaryReplacement</span><span class="p">(</span><span class="n">OpenTelemetry</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Meter</span><span class="w"> </span><span class="n">meter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">openTelemetry</span><span class="p">.</span><span class="na">getMeter</span><span class="p">(</span><span class="s">&#34;smart.home&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 明示的バケット境界なし: カウントと合計をキャプチャする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ほとんどの Summary ユースケースの良い代替となる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// クォンタイル推定には、しきい値を挟む境界を追加する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">DoubleHistogram</span><span class="w"> </span><span class="n">deviceCommandDuration</span><span class="w"> </span><span class="o">=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">meter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">histogramBuilder</span><span class="p">(</span><span class="s">&#34;device.command.duration&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setDescription</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">setExplicitBucketBoundariesAdvice</span><span class="p">(</span><span class="n">List</span><span class="p">.</span><span class="na">of</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">35</span><span class="p">,</span><span class="w"> </span><span class="n">THERMOSTAT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">deviceCommandDuration</span><span class="p">.</span><span class="na">record</span><span class="p">(</span><span class="n">0</span><span class="p">.</span><span class="na">85</span><span class="p">,</span><span class="w"> </span><span class="n">LOCK</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-12-01" role="tabpanel" aria-labelled-by="tabs-12-01-tab" tabindex="12">
        <?code-excerpt path-base="examples/go/prometheus-compatibility"?>
<p>Prometheus</p>
<?code-excerpt "prometheus_summary.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;github.com/prometheus/client_golang/prometheus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">summaryDeviceCommandDuration</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">prometheus</span><span class="p">.</span><span class="nf">NewSummaryVec</span><span class="p">(</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">SummaryOpts</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Name</span><span class="p">:</span><span class="w">       </span><span class="s">&#34;device_command_duration_seconds&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Help</span><span class="p">:</span><span class="w">       </span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">Objectives</span><span class="p">:</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">float64</span><span class="p">]</span><span class="kt">float64</span><span class="p">{</span><span class="mf">0.5</span><span class="p">:</span><span class="w"> </span><span class="mf">0.05</span><span class="p">,</span><span class="w"> </span><span class="mf">0.95</span><span class="p">:</span><span class="w"> </span><span class="mf">0.01</span><span class="p">,</span><span class="w"> </span><span class="mf">0.99</span><span class="p">:</span><span class="w"> </span><span class="mf">0.001</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">},</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;device_type&#34;</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">summaryUsage</span><span class="p">(</span><span class="nx">reg</span><span class="w"> </span><span class="o">*</span><span class="nx">prometheus</span><span class="p">.</span><span class="nx">Registry</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">reg</span><span class="p">.</span><span class="nf">MustRegister</span><span class="p">(</span><span class="nx">summaryDeviceCommandDuration</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">summaryDeviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;thermostat&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.35</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">summaryDeviceCommandDuration</span><span class="p">.</span><span class="nf">WithLabelValues</span><span class="p">(</span><span class="s">&#34;lock&#34;</span><span class="p">).</span><span class="nf">Observe</span><span class="p">(</span><span class="mf">0.85</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>OpenTelemetry</p>
<?code-excerpt "otel_histogram_as_summary.go"?>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;context&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/attribute&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;go.opentelemetry.io/otel/metric&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 値が静的な場合、呼び出しごとのアロケーションを避けるために属性オプションを事前に割り当てる。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">summaryThermostatOpts</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;thermostat&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">summaryLockOpts</span><span class="w">       </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="nx">metric</span><span class="p">.</span><span class="nx">RecordOption</span><span class="p">{</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithAttributes</span><span class="p">(</span><span class="nx">attribute</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;device_type&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;lock&#34;</span><span class="p">))}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">summaryReplacement</span><span class="p">(</span><span class="nx">ctx</span><span class="w"> </span><span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w"> </span><span class="nx">meter</span><span class="w"> </span><span class="nx">metric</span><span class="p">.</span><span class="nx">Meter</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// 明示的バケット境界なし: カウントと合計のみをキャプチャする。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="c1">// クォンタイル推定には、代わりに base2 指数ヒストグラムを推奨する。</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">meter</span><span class="p">.</span><span class="nf">Float64Histogram</span><span class="p">(</span><span class="s">&#34;device.command.duration&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithDescription</span><span class="p">(</span><span class="s">&#34;Time to receive acknowledgment from a smart home device&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithUnit</span><span class="p">(</span><span class="s">&#34;s&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">metric</span><span class="p">.</span><span class="nf">WithExplicitBucketBoundaries</span><span class="p">())</span><span class="w"> </span><span class="c1">// 境界なし</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">0.35</span><span class="p">,</span><span class="w"> </span><span class="nx">summaryThermostatOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">deviceCommandDuration</span><span class="p">.</span><span class="nf">Record</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mf">0.85</span><span class="p">,</span><span class="w"> </span><span class="nx">summaryLockOpts</span><span class="o">...</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
    </div>
</div>
