OpenTelemetry(OTel)は、テレメトリーデータを収集およびエクスポートするための標準化されたアプローチを提供し、最新のアプリケーション監視に不可欠なツールとなっています。強力なインテリジェントオブザーバビリティプラットフォームであるNew Relicと組み合わせると、 OpenTelemetryデータの可能性を最大限に活用して、インサイトの取得と最適化を行うことができます。
このブログ記事では、New Relicクエリ言語(NRQL)を使用して、New RelicでOpenTelemetryデータをクエリするプロセスについて説明します。この記事を読み終える頃には、OpenTelemetryデータがNew Relicデータベース(NRDB)にどのように保存されるか、またアプリケーションでその有用性を最大限に高める方法について、しっかりと理解できるようになります。
このブログ記事で使用されているコードは、こちらから入手できます。
OpenTelemetryのデータ型について
クエリプロセスに進む前に、OpenTelemetryデータの基本要素を把握することが重要です。OpenTelemetryはさまざまなメトリクスデータモデルを利用して、多様な種類のテレメトリー情報を取得します。これらには以下が含まれます。
- カウンター:処理されたリクエストの数や処理された例外の合計数など、累積的で減少しない値を表します。
- アップダウンカウンター:アクティブなデータベース接続の数など、時間の経過とともに増加または減少する可能性のある値を追跡します。
- ヒストグラム:カウント、合計、最小、最大などの集計された測定値を提供します。これは、アプリサーバーのレスポンスタイムに役立ちます。
- 監視可能なカウンター:カウンターに似ていますが、コールバックを介した非同期テレメトリーレポートが可能になります。これは、CPU時間などのプロセスメトリクスに最適です。
New Relicを使用したOpenTelemetryデータの保存とクエリ
このブログ記事を事前にお読みになり、OpenTelemetryに関連する3つの異なるメトリクスデータモデルをよく理解しておくことをお勧めします。大まかに言うと、このプロセスには4つのステップがあります。
1. 計装は、OpenTelemetryインストゥルメンテーションコードを使用して作成されます。
2. OpenTelemetry SDKはそれを送信用のOpenTelemetryプロトコル(OTLP)データ形式に変換します。
3. 送信されたデータはデータストア(この場合はNRDB)に保存されます。
4. NRQL使用して、NRDBに保存されているOpenTelemetryデータをクエリします。
以下の表-1は、計装、OTLP、データストア間のデータ型のマッピングを示しています。
原点(コード内) | 送信中(OTLP) | 保存時(New Relic) |
単調な累積合計 | カウント* | |
非単調な累積合計 | ゲージ | |
ヒストグラム | 分布 | |
単調な累積合計 | カウント* |
*注意:以下の環境変数がdeltaに設定されている場合、カウンターおよび監視可能なカウンターデータ型はNew RelicのCountデータ型に変換されます。環境変数が設定されていない場合は、New RelicではCumulativeCountに変換されます。
set OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta
それぞれのデータ型を詳しく調べて、 New Relicでそれらを計装、保存、クエリする方法を探ってみましょう。
前提条件
このブログ記事で説明したデータ型を計装、保存、クエリする前に、以下が必要です。
- お気に入りのIDEを使用して、app.pyという名前のファイルを作成します。
- 次の3つの依存関係をインストールします。
- pip install opentelemetry-api
- pip install opentelemetry-sdk
- pip install opentelemetry-exporter-otlp-proto-http
- 以下の環境変数を追加します。
export OTEL_SERVICE_NAME=MyPythonService
export OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net
export OTEL_EXPORTER_OTLP_HEADERS=api-key=<New Relic Ingest License Key>
export OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=4095
export OTEL_EXPORTER_OTLP_COMPRESSION=gzip
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta
export OTEL_RESOURCE_ATTRIBUTES=service.instance.id=123
- app.pyに次のコードを追加します。
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.otlp.proto.http.metric_exporterimport OTLPMetricExporter
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.metrics import CallbackOptions, Observation
from typing import Iterable
metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter(), export_interval_millis=5000) # 収集サイクルは5秒ごと
provider = MeterProvider(metric_readers=[metric_reader])
# グローバルなデフォルトのメータープロバイダーを設定する
metrics.set_meter_provider(provider)
# グローバルメータープロバイダーからメーターを作成する
meter = metrics.get_meter("my.meter.name")
カウンター
説明:これらは加算される非減少値です。
マッピング:
原点(コード内) | 送信中(OTLP) | 保存時(New Relic) |
カウンター | 単調な累積合計 | カウント |
単調な累積合計の例をいくつか示します。
- 処理されたリクエスト数
- 処理された例外の合計数
- 送信されたネットワークバイト数
ステップ1:OpenTelemetryによるインストゥルメンテーション
Pythonでカウンターを作成するには:このコードスニペットは、mycounter.incrementsという計装を作成します。次に、計装の3つの値をOTLPエンドポイントに送信します。収集サイクルは(前のステップで)5秒に1回と設定されているため、スリープ時間を導入すると、収集サイクルが3回発生します。
my_counter = meter.create_counter("mycounter.increments")
# 5秒の収集サイクルごとに1つの値が送信されるように、10秒間スリープする
my_counter.add(3)
time.sleep(10)
my_counter.add(5)
time.sleep(10)
my_counter.add(10)
ステップ2:NRDBへの保存
New Relicに到達すると、OpenTelemetryデータはNRDBに保存されます。以下の表-2は、カウンターのオリジン値がNew Relicにどのように保存されるかを示しています。この例では、OpenTelemetryの収集サイクルは5秒です。New RelicはOpenTelemetryの累積値を取り込み、両方のデルタ値をNRDBに保存します。
収集サイクル | オリジン値 | OLTP値 | New Relic値 |
1 | 3 | 3 | 3 |
2 | 5 | 8 | 5 |
3 | 10 | 18 | 10 |
注意:デルタ値と累積値をNRDBに保存する場合は、この環境変数をUNSETにしてください。
unset OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
ステップ3:NRQLによるクエリ
次は、NRQLを使用してデータをクエリするという、興味深い部分です。NRQLは、データ分析における柔軟性と精度のために設計された強力なクエリ言語です。
以下は、NRDBにデータがどのように保存されているかを確認するためのクエリです。以下のNRQLを実行します。
SELECT * FROM Metric WHERE entity.name = 'MyPythonService' AND metricName = 'mycounter.increments'SINCE 15 MINUTES AGO

上記のスクリーンショットは、データ型がCountに設定されていることを示しています。
特定の期間のmycounter.increments
メトリクス値の合計を表示するには、次のコマンドを実行します。
SELECT sum(mycounter.increments)
FROM Metric
WHERE metricName = 'mycounter.increments'
SINCE 15 minutes ago UNTIL now

より高度なインサイトの場合は、 NRQLのTIMESERIES関数を使用して、変化率を時系列に分析できます。
SELECT rate(sum(mycounter.increments), 1 minute) FROM Metric WHERE entity.name = 'MyPythonService' AND metricName = `mycounter.increments`SINCE 15 MINUTES AGO TIMESERIES
このクエリにより、時系列のメトリクスの変化率が提供され、傾向分析とパフォーマンス監視が可能になります。

アップダウンカウンター
説明:時間の経過とともに上昇または下降する可能性がある値。
マッピング:
原点(コード内) | 送信中(OTLP) | 保存時(New Relic) |
アップダウンカウンター | 非単調な累積合計 | ゲージ |
以下はアップダウンカウンターの例です。
- データベース接続数
- キャッシュのサイズ
ステップ1:OpenTelemetryによるインストゥルメンテーション
Pythonでアップダウンカウンターを作成するには:
# アップダウンカウンターの計装を作成する
my_updown_counter = meter.create_up_down_counter("my_updown_counter")
# 5秒の収集サイクルごとに1つの値が確保されるように、10秒間スリープする
my_updown_counter.add(3)
time.sleep(10)
my_updown_counter.add(-1)
time.sleep(10)
my_updown_counter.add(10)
ステップ2:NRDBへの保存
以下の表-3 は、OpenTelemetryデータ型がNew Relicのゲージデータ型にどのようにマッピングされるかを示しています。収集サイクル期間は5秒に設定されています。
収集サイクル | オリジン値 | OTLP値 | New Relic値 |
1 | 3 | 3 | 3 |
2 | -1 | 2 | 2 |
3 | 10 | 12 | 12 |
ステップ3:NRQLによるクエリ
NRQLを使用してすべての myupdowncounterメトリクス値を表示するには(データ型がゲージであることに留意):
SELECT * FROM Metric WHERE entity.name = 'MyPythonService' AND metricName = 'myupdowncounter' SINCE 15 MINUTES AGO

特定の期間のmyupdowncountermetriks値の最新値を表示するには、最新キーワードを使用します。上記のスクリーンショットに示すように、同様にキーワード合計、最小、最大を使用することもできます。
SELECT latest(myupdowncounter) FROM Metric WHERE entity.name = 'MyPythonService' AND metricName = 'myupdowncounter' SINCE 15 MINUTES AGO

ヒストグラム
説明:カウント、合計、最小、最大などの複数の集計された測定値を提供する1つのメトリクス。
マッピング:
原点(コード内) | 送信中(OTLP) | 保存時(New Relic) |
ヒストグラム | ヒストグラム | 分布 |
ヒストグラムの例を次に示します。
- アプリサーバーのレスポンスタイム
ステップ1:OpenTelemetryによるインストゥルメンテーション
重要:ヒストグラムにはこの環境変数を設定する必要があります。
set OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta
Pythonでヒストグラムを作成するには:
# ヒストグラム計装を作成する
my_histogram = meter.create_histogram("myhistogram")
# ヒストグラムの値を記録するこれにより、9 つの値/カウントを持つヒストグラムが作成されます。
for i in range(1, 10):
latency = random.randint(1,1000)
my_histogram.record(latency,attributes={"attr1": "value1"})
ステップ2:NRQLによるクエリ
NRQLを使用してすべてのヒストグラムメトリクス値を表示するには:
SELECT * FROM Metric WHERE metricName = 'myhistogram' SINCE 5 minutes AGO

NRQL使用してヒストグラムメトリクス値の合計のみを表示するには(この場合、グラフタイプはJSONに設定済み):
SELECT sum(myhistogram) FROM Metric WHERE metricName = 'myhistogram' SINCE 5 minutes AGO

監視可能なカウンター
説明:非同期の加算非減少値。
マッピング:
原点(コード内) | 送信中(OTLP) | 保存時(New Relic) |
監視可能なカウンター | 単調な累積合計 | カウント |
以下に、監視可能なカウンターの例をいくつか示します。
- プロセスあたりのページフォールト数
- スレッドあたりのCPU時間
ステップ1:OpenTelemetryによるインストゥルメンテーション
Pythonで監視可能なカウンターを作成するには:
# コールバック関数を登録する
def pf_callback(options: CallbackOptions) -> Iterable[Observation]:
# 登録されるとコールバック関数が自動的に呼び出される
# 収集サイクルごと(5秒ごと)
return [Observation(random.randint(1,100), {"pid": 1}),
Observation(random.randint(1,100),{"pid": 2}),
Observation(random.randint(1,100),{"pid": 3})]
# 監視可能なカウンターを作成する(非同期)
def createObservableCounter(meter):
meter.create_observable_counter(name="myobservablecounter",description="process page faults", callbacks = [pf_callback])
time.sleep(20)
ステップ2:NRDBへの保存
以下の表-4は、監視可能なカウンターのオリジン値がNew Relicにどのように保存されるかを示しています。この例では、OpenTelemetryの収集サイクルは5秒です。
収集サイクル | PID | オリジン値 | OTLP値 | New Relic値 |
1 | 1 | 56 | 56 | 56 |
1 | 2 | 76 | 76 | 76 |
1 | 3 | 12 | 12 | 12 |
2 | 1 | 74 | 130 | 74 |
2 | 2 | 42 | 118 | 42 |
2 | 3 | 51 | 63 | 51 |
注: NRDBに保存するデルタ値と累積値のみを保存する場合は、この環境変数をUNSETにします。
unset OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
このデータがNRDBにどのように保存されるかを見てみましょう。
SELECT myobservablecounter, pid, *
FROM Metric
WHERE metricName = 'myobservablecounter'
SINCE 5 minutes ago UNTIL now

ステップ3:NRQLによるクエリ
特定の期間のmyobservablecounter
メトリクス値の合計を表示するには、次のコマンドを実行します。
SELECT sum(myobservablecounter)
FROM Metric
WHERE metricName = 'myobservablecounter'
SINCE 15 minutes ago UNTIL now

myobservablecounterメトリクス値の変化率をTIMESERIESとして表示するには、次のようにします。
SELECT rate(sum(myobservablecounter), 1 minute) FROM Metric WHERE entity.name = 'MyPythonService' AND metricName = 'myobservablecounter' SINCE 15 MINUTES AGO TIMESERIES

監視可能なヒストグラムや監視可能なゲージなどの追加のメトリクスタイプも、上記と同様のアプローチを使用してNew Relicに送信できることに注意してください。詳細については、次のリソースをご覧ください。
まとめ
このステップバイステップガイドに従うことで、New RelicでOpenTelemetryデータを効果的にクエリできます。NRQLによるクエリ性能を使いこなして、貴重なインサイトの獲得、システムの最適化を行い、アプリケーションのオブザーバビリティを高めます。
次のステップ
今すぐNew Relicにサインアップして、OpenTelemetryとNew Relicの可能性を最大限に引き出し、アプリケーション監視をまったく新しいレベルに引き上げましょう。
本ブログに掲載されている見解は著者に所属するものであり、必ずしも New Relic 株式会社の公式見解であるわけではありません。また、本ブログには、外部サイトにアクセスするリンクが含まれる場合があります。それらリンク先の内容について、New Relic がいかなる保証も提供することはありません。