Datadog APM を触ってみるぞ
はじめに
この記事は Datadog に入門してみたいと思った筆者が、Datadog APM を触ってみた記録です。入門するにあたって、CloudRun で動いてる Rails のアプリケーションのログやトレースを Datadog に送ったり、ログとトレースの紐付けを試してみたりしました。基本的には Datadog のドキュメントを読んで試してみただけですが、自分の理解のためにもまとめておきます。
対象読者
- Datadog に入門したい人
- CloudRun で動いてる Rails のアプリケーションのログやトレースを Datadog に送りたい人
- ドキュメントを軽く読んでみたけど、ひとまず動くものを用意してみたい人
Table of Contents
- Datadog のアカウントを作る
- Rails で構造化ログを出力する
- Cloud ロギングのログを Datadog に送る
- トレースを Datadog に送る
- ログとトレースを紐付ける
1. Datadog のアカウントを作る
トライアルで 14 日間は無料で使えるようです。Datadog のサイトにアクセスして、アカウントを作ります。
料金
2. Rails で構造化ログを出力する
Datadog にログを送る前に、Rails のログを構造化して出力したいです。構造化すると、Datadog でログを見るときに、フィルタリングやグルーピングがしやすくなります。Rails で構造化ログを出力するには、lograge
という gem を使います。
参考にした記事
また、ログの構造化が足りてない場合、Datadog にはパイプラインという機能があるので、受け取ったログをパイブライン上でパースして変換することもできます。
半構造化されたテキストから意味のある情報や属性を抽出し、ファセットとして再利用することができます
3. Cloud ロギングのログを Datadog に送る
GCP のログを Datadog に送ります。Datadog の ドキュメントを参考に、以下の4つのステップがうまくできたら、GCP のログを Datadog に送ることができます。
- Google Cloud Platform インテグレーションをまだセットアップしていない場合は、最初にセットアップします。
- 新しい Cloud Pub/Sub を作成します。
- ログを Datadog へ転送する Pub/Sub をセットアップします。
- Google Cloud から Pub/Sub へのログのエクスポートを構成します。
ドキュメント
注意点として、Datadog と GCP を連携する際に使う GCP のサービスアカウントの権限の設定を間違えると、Cloud ロギングのログを Datadog に送ることができません。Datadog のドキュメントにも書いてあるので、注意してください。(Compute 閲覧者、モニタリング閲覧者、Cloud Asset 閲覧者の権限が必要です。)
役割に Compute 閲覧者、モニタリング閲覧者、Cloud Asset 閲覧者を追加し、Done をクリックします。
無事に送りつけることに成功したら、Datadog のログの画面にログが表示されます。
GCP 側の Pub/Sub の画面は以下のようになっています。以下は問題なくログを転送してる場合の画像ですが、権限が足りず失敗してる場合は push リクエストで、url_4xx_error_403
などのエラーが出ます。
4. トレースを Datadog に送る
トレースを Datadog に送るためには、Datadog Agent のセットアップとアプリケーションをインスツルメントが必要です。データの流れは、Rails -> Datadog Agent -> Datadog という感じです。
4.1 Datadog Agent のセットアップ
Datadog Agent のセットアップは、先日パブリックプレビューで公開された CloudRun のサイドカーデプロイを使って試してみます。
以下の記事が参考になりました。
サイドカーデプロイでは、マルチコンテナ構成が可能になり、Rails のコンテナと Datadog Agent のコンテナををサイドカーとしてデプロイすることができます。
引用元: https://cloud.google.com/run/docs/deploying?hl=en#sidecars
サイドカーを含む Cloud Run のデプロイには、YAML ファイルを作成して、以下のコマンドを実行します。YAML に定義してる Datadog Agent の API KEY や Rails の環境変数は適宜変更してください。
$ gcloud run services replace multicontainers-dda.yaml --region asia-northeast1
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
run.googleapis.com/launch-stage: BETA
run.googleapis.com/ingress: all
name: rails-app # CloudRunのサービス名
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/minScale: "0"
run.googleapis.com/cpu-throttling: "false"
run.googleapis.com/execution-environment: gen2
spec:
containers:
- image: gcr.io/datadoghq/agent:latest
resources:
limits:
cpu: 1000m
memory: 512Mi
env:
- name: DD_API_KEY
value: "API KEY" # API KEY を入れる
- name: DD_SITE
value: "ap1.datadoghq.com"
- name: DD_HOSTNAME
value: "hostname"
- name: DD_APM_ENABLED
value: "true"
- name: DD_APM_NON_LOCAL_TRAFFIC
value: "true"
- name: DD_LOGS_ENABLED
value: "true"
- name: DD_ENV
value: "production" # 環境名を入れる
- name: DD_SERVICE
value: "sample_rails" # サービス名を入れる
- name: DD_VERSION # バージョンを入れる
value: "1.0.0"
- image: asia-northeast1-docker.pkg.dev/[project_id]/myrepo/rails:latest # ここに Rails のイメージを入れる
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
value: [DATABASE_URL] # ここにデータベースの URL を入れる
- name: SECRET_KEY_BASE
value: "SECRET_KEY_BASE" # ここにシークレットキーを入れる
- name: RAILS_LOG_TO_STDOUT
value: "true"
- name: DD_TRACE_AGENT_URL
value: "http://localhost:8126"
YAML の Reference
4.2 アプリケーションの instrument
Rails アプリケーションを instrument するために、Datadog のトレースライブラリをインストールします。詳しくは以下のドキュメントを参照してください。
ライブラリの追加のために、Gemfile に以下の行を追加します。
gem 'ddtrace', require: 'ddtrace/auto_instrument'
gem 'opentracing'
$ bundle install
Datadog のコンフィグ作成します。
if Rails.env.production?
require 'opentracing'
require 'datadog/opentracer'
require 'ddtrace'
# Activate the Datadog tracer for OpenTracing
OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new
Datadog.configure do |c|
c.env = 'production'
c.service = 'sample_rails'
end
end
ここまでやった後に Rails のアプリケーションをデプロイし、アクセスしてみると、Datadog の APM にトレースが表示されていることが確認できました。
5. ログとトレースを紐付ける
最後にログとトレースを紐付けをします。ログの構造によっては、特に何もしなくても自動的に紐付けができますが、今回は少し設定が必要でした。
紐付けができてない場合は、以下のように No logs found となります。
トラブルシューティングのドキュメントを確認したところ、トレース ID を含むログ属性の名前が dd.trace_id
になっている必要があるが、今回のログの構造だと data.jsonPayload.dd.trace_id
になっていて、ログとトレースが紐付けられていなかったようでした。そのため、No logs found となっていたようです。
Trace ID のマッピングの設定に data.jsonPayload.dd.trace_id
を追加すると正しく動作するようになりました。
トレースとログが紐づいたことが確認できました。
おわりに
今回は シンプルに Rails アプリケーションを対象に基本的な機能を把握できたので、次回は複数のアプリケーションをデプロイしている場合に、それぞれのアプリケーションのトレースを紐付けるなどを試してみたいです。
参考
Discussion