Telemetry API がリリースされたので OTLP で Google Cloud にスパンを送ってみた
こんにちは!クラウドエースの kazz です。
先日、Google Cloud の Telemetry API がリリースされました。これは、Google Cloud が標準的な OTLP/HTTP および OTLP/gRPC のリクエストを受け付ける公式エンドポイントを提供するものです。
これにより、Google Cloud 専用の Exporter を使わずに、標準的な OTLP Exporter を利用してスパンを Cloud Trace に送信できるようになりました。
この記事では、Telemetry API の紹介と、OpenTelemetry Collector を利用して、新しく登場した Telemetry API にスパンを送信する手順を解説します。
Telemetry API の特徴
1. 標準 OTLP/HTTP および OTLP/gRPC をサポート
OpenTelemetry の標準プロトコルである OTLP (OpenTelemetry Protocol) を直接受け付けます。これにより、特定のクラウドベンダーに依存しない、標準的な OpenTelemetry の設定を利用できます。
-
gRPC エンドポイント:
telemetry.googleapis.com:443
-
HTTP/S エンドポイント:
https://telemetry.googleapis.com/v1/traces
2. OTLP 形式でのデータ保存
送信されたトレースデータは、Google Cloud 内部で独自の形式に変換されることなく、OTLP 形式のまま保存されます。これにより、データの完全性が保たれやすくなります。
3. 緩和された制限 (Quotas)
Telemetry API 専用の制限が適用されます。多くの場合、属性キーや値の文字列長、スパンごとの属性数などの上限が Cloud Trace API と比較して大幅に緩和されており、より柔軟にスパンを送信することが可能となりました。
詳細: Cloud Trace Quotas - Telemetry API limits
4. Google Cloud Exporter への依存が不要に
OTLP Exporter を使用できるため、Google Cloud 専用の Exporter が必要なくなります。
5. トレースデータのみをサポート
現時点 (2025年4月) では、Telemetry API はトレースデータのみを受け入れます。このエンドポイントを使用して、指標やログデータを Google Cloud プロジェクトに送信することはできません。
トレースデータの確認
送信されたトレースデータは、Google Cloud Console の Trace Explorer で確認できます。
これは、従来の Cloud Trace API と同じですね。
ただし、現在 Telemetry API で書き込まれたスパンは、従来の Trace Explorer ページ(粒がいっぱいのやつ)では表示できないので注意しましょう。
Telemetry API にスパンを送る方法
Telemetry API にスパンを送る方法としては、主に以下の2つのパターンが考えられます。
-
OpenTelemetry Collector を経由するパターン
- アプリケーションは OTLP を話す OpenTelemetry Collector にデータを送信します。
- OpenTelemetry Collector はデータのバッチ処理、リトライ、リソース属性の付与、認証などを担当し、一元的に Telemetry API へデータを転送します。
-
アプリケーションから直接送信するパターン
- アプリケーションに組み込まれた OpenTelemetry SDK が、OTLP Exporter を使用して Telemetry API へ直接データを送信します。
今回は OpenTelemetry Collector を経由するパターンで試してみます。
手順
Cloud Run に OpenTelemetry Collector をデプロイして、OTLP/gRPC で Telemetry API にスパンを送信する手順を解説します。
前提
- プロジェクトで以下の API が有効化されていること
- artifactregistry.googleapis.com (Artifact Registry API)
- run.googleapis.com (Cloud Run Admin API)
- telemetry.googleapis.com (Telemetry API)
{GOOGLE_CLOUD_PROJECT} は、ご自身の Google Cloud プロジェクトの ID に置き換えてください。
1. OpenTelemetry Collector の設定
まずは、アプリケーションから送られてくるトレースデータを受け取り、加工して Telemetry API に転送する OpenTelemetry Collector の設定ファイルを作成します。
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
processors:
batch: {}
resourcedetection:
detectors: [gcp]
override: false
resource:
attributes:
- key: gcp.project_id
value: "${GOOGLE_CLOUD_PROJECT}"
action: upsert
exporters:
otlp:
endpoint: "telemetry.googleapis.com:443"
auth:
authenticator: googleclientauth
extensions:
googleclientauth:
service:
extensions: [googleclientauth]
pipelines:
traces:
receivers: [otlp]
processors: [resourcedetection, resource, batch]
exporters: [otlp]
ポイント
-
processors.resource: gcp.project_id
は Telemetry API でトレースを正しいプロジェクトに関連付けるために設定します。 -
exporters.otlp.endpoint:
に Telemetry API の gRPC エンドポイントtelemetry.googleapis.com:443
を指定します。 -
extensions: googleclientauth
を定義することで、認証が有効になります。これにより、OpenTelemetry Collector がサービスアカウントの認証情報を使って Telemetry API に接続することができるようになります。
2. 権限設定
OpenTelemetry Collector が Telemetry API にトレースデータを書き込むための権限 roles/telemetry.tracesWriter
を持つサービスアカウントを用意します。
gcloud iam service-accounts create otel-collector
gcloud projects add-iam-policy-binding {GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:otel-collector@{GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/telemetry.tracesWriter"
3. OpenTelemetry Collector のビルドとデプロイ
イメージを保存するための Artifact Registry リポジトリを作成します。
gcloud artifacts repositories create otel --repository-format=docker --location=asia-northeast1
config.yaml を使用する OpenTelemetry Collector の Docker イメージを作成します。
# OpenTelemetry Collector Contrib イメージを使用 (多くのプラグインが含まれる)
# 本番環境では、必要なプラグインだけを含むカスタムイメージの作成を推奨 (OTel Collector Builder を使用)
FROM otel/opentelemetry-collector-contrib:latest
COPY config.yaml /etc/otelcol-contrib/config.yaml
EXPOSE 4317
CMD ["--config=/etc/otelcol-contrib/config.yaml"]
Docker イメージをビルドし、先ほど作成した Artifact Registry リポジトリにプッシュします。
docker build -t asia-northeast1-docker.pkg.dev/{GOOGLE_CLOUD_PROJECT}/otel/otel-collector:latest .
docker push asia-northeast1-docker.pkg.dev/{GOOGLE_CLOUD_PROJECT}/otel/otel-collector:latest
作成したイメージとサービスアカウントを使用して、Cloud Run サービスとして OpenTelemetry Collector をデプロイするための yaml ファイルを作成します。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: otel-collector
labels:
cloud.googleapis.com/location: asia-northeast1
spec:
template:
metadata:
spec:
serviceAccountName: otel-collector@{GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
containers:
- image: asia-northeast1-docker.pkg.dev/{GOOGLE_CLOUD_PROJECT}/otel/otel-collector:latest
ports:
- name: http1
containerPort: 4317
env:
resources:
limits:
memory: 1Gi
cpu: 1
サービスをデプロイします。
gcloud run replace services service.yaml
後述のサンプルアプリケーションからローカル環境経由でスパンを送信するため、デモ目的で一時的に未認証の呼び出しを許可します。
本番環境では、OpenTelemetry Collector にスパンを送信するための適切なネットワーク構成と認証・権限管理を実装するようにしてください。
gcloud run services add-iam-policy-binding otel-collector \
--role="roles/run.invoker" \
--member="allUsers" \
--region=asia-northeast1
デプロイが完了すると、Cloud Run サービスの URL が表示されます。これがアプリケーションからスパンを送る際のエンドポイントになります。
これで、Telemetry API にスパンを送るための OpenTelemetry Collector が用意できました。
4. サンプルアプリケーションからのスパン送信
それでは、OpenTelemetry Collector にスパンを送ってみます。
今回は Gemini に作成してもらった、スパンを送信するだけのサンプルアプリケーションを使用します。
import time
import logging
import argparse
from contextlib import contextmanager
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@contextmanager
def configure_tracer_provider(endpoint: str):
resource = Resource.create({SERVICE_NAME: "demo"})
exporter = OTLPSpanExporter(endpoint=endpoint, insecure=True)
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
try:
yield provider
finally:
logger.info("Shutting down tracer provider...")
provider.shutdown()
logger.info("Tracer provider shut down.")
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--endpoint',
type=str,
default="http://localhost:4317",
)
args = parser.parse_args()
with configure_tracer_provider(endpoint=args.endpoint) as provider:
tracer = trace.get_tracer("my.instrumentation.library.python")
logger.info("Starting to send spans...")
counter = 0
try:
while True:
with tracer.start_as_current_span("send-loop-iteration") as span:
span.set_attribute("loop.counter", counter)
time.sleep(0.1)
logger.info(f"Sent span {counter}")
counter += 1
time.sleep(1.0)
except KeyboardInterrupt:
logger.info("KeyboardInterrupt received. Initiating shutdown...")
if __name__ == "__main__":
main()
この Python アプリを実行して、デプロイした OpenTelemetry Collector にスパンを送信します。
python sample-app.py --endpoint {OpenTelemetry Collector をデプロイした Cloud Run サービスの URL}
それでは、Trace Explorer でスパンを確認してみます。
無事に OTLP/gRPC で送信したスパンを確認できました!
おわりに
Telemetry API の登場で、Google Cloud におけるトレース実装がより容易になりました。
ぜひ試してみてください!
Discussion