COLOPL Tech Blog

コロプラのエンジニアブログです

dd-trace-phpとOpenTelemetry Collectorを使ってDatadogにトレースを送る際のハマりポイントと解決方法

こんにちは、LCE(Launch Coordination Engineering)チームとして新作ゲーム開発の支援を行っている駒崎(@dkkoma)です。

コロプラではLaravelアプリケーションの計装にDatadog製のトレーシングライブラリであるdd-trace-phpを利用しています。

今回、新作ゲーム開発プロジェクトのCloudRun環境においてDatadogにトレース情報を送る経路を構築する中でいくつかハマりどころがあったため、その内容と解決方法を解説したいと思い、こちらの記事を書くことにしました。

構成

アプリケーションからDatadogまでの経路はLaravel(dd-trace-php) -> OpenTelemetry Collector(datadogreceiver + otlpexporter) -> Datadog Agent -> Datadogというパターンで構築しています。Datadog AgentがOTLP Receiverを実装しているのとCloudRunのサービス間認証を利用する都合で、OpenTelemetry CollectorからDatadog AgentへはOTLPで送信しています。Datadogに送信する手前でDatadog Agentを使っているのはレアサンプラーやエラーサンプラーなどの機能を使いたいためです。

ハマりポイント1: Spanの名前が期待通り送られない

Datadog上で見えるSpan名が以下のようになってしまっていました。間にOpenTelemetry Collectorを挟まなければクラス名やSQLが表示されるのですが、これではどのSpanが何なのか識別がとても難しいです。

調査の結果、この問題はOpenTelemetry Collectorのtransform processorを使用することで解決できることが分かりました。具体的には、operation.namespan.nameに適切な値を設定することで、Datadogが意図しているであろう形式でSpan情報を保持することが可能になります。

  transform:
    error_mode: ignore
    trace_statements:
      - context: span
        statements:
          # ↓の2つの設定で span.kind, span.name がdatadog agent経由と同じになるっぽい
          # 元々は name に laravel.event.handle
          # dd.span.Resource に bootstrapping: Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables などが入ってる
          - set(attributes["operation.name"], name)
          - set(name, attributes["dd.span.Resource"])

ハマりポイント2: エラーメッセージがステータスコードになる

以下のように例外のメッセージが勝手にステータスコードだけになってしまいます。本来ならエラーメッセージと例外の発生箇所がわかるようになっているはずです。

この問題もハマりポイント1と同じく、OpenTelemetry Collectorのtransform processorを使用して対処することができます。具体的には、error.msgフィールドに元のerror.messageの値を保持するよう設定することで、エラーの詳細情報を維持したままDatadogへトレース情報を送信することが可能になりました。

      - context: span
        statements:
          # error.msg にメッセージをいれておかないと変に置換されてしまう
          # exception.message にいれてもよさそうなのだが span.name が exception じゃないからか出来なかった
          # see: https://github.com/DataDog/datadog-agent/blob/a9eac7672a6cf91bec6da77c18313c6f3db4c22d/pkg/trace/api/otlp.go#L619
          - set(attributes["error.msg"], attributes["error.message"])

調査中にわかったこととしては、エラーメッセージをHTTPステータスコードに変換してしまう処理はdatadog-agent用ライブラリ内にあったのですが、opentelemetry-collector-contribのdatadogexporterでもDatadog/datadog-agentのパッケージが使われているために、このようなことになっているようでした。ただ、transform.goを見る限り、exception.messageに入れておけばDatadog用に変換してくれるロジックが実装されているようには見えたのですが、transform processerを使って設定してもダメだったのでdd-trace-phpで作ったSpanを変換することは想定していなさそうです。

所感

そもそも、Datadogの計装ライブラリ(dd-trace-somelang) -> OpenTelemetry Collector -> Datadog Agent -> Datadogというパターンで構成しているケースが探してもあまりなかったので、OpenTelemetry Collectorを使うなら計装ライブラリもOpenTelemetryを使うべしということだったのかもしれません。今回はアプリケーション側をあまり変更したくなかったのでこの構成でやった結果、なかなかハマってしまいました。



ColoplTechについて

コロプラでは、勉強会やブログを通じてエンジニアの方々に役立つ技術や取り組みを幅広く発信していきます。
connpassおよびXで情報発信していますので、是非メンバー登録とフォローをよろしくお願いいたします。

colopl.connpass.com

x.com

 

また、コロプラではゲームや基盤開発のバックエンド・インフラエンジニアを積極採用中です!
興味を持っていただいた方はぜひお気軽にご連絡ください。