🐕

DatadogでCIを可視化する

2021/12/03に公開

概要

  • この記事は Datadog Advent Calendar 2021 5日目の記事です
  • CIのテストがコケる問題の調査の一環で行った対応のメモです

この記事のターゲット

  • Datadogを導入している方
  • これからCIのモニタリングをやっていくぞという方

あらすじ

Railsで書かれたとあるWebサービスがあり、それはCircleCIでビルド〜デプロイを行っています。

ある日、CIのテストが落ちまくってるから見てくれという相談がありました。
失敗していたCIのジョブを見てみたところ、yarn runの箇所で静かにkillされていました。

yarn run {なんかバージョン指定}
$ webpack --config ./config/webpack/production.js
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`

Received "killed" signal

恐らくメモリ不足であろうという事から、暫定対応としてCircleCIのresource_classをmedium+からlargeに変更し、NODE_OPTIONSに下記を設定することで現象を回避できました。

config.yml
   environment:
+     NODE_OPTIONS: --max_old_space_size=4096
-  resource_class: medium+
+  resource_class: large

本題

恐らくで片付けちゃって大丈夫か?ちゃんとトレースできてないけど本当に大丈夫か?と考えてみて、ちゃんとCIのメトリクスも見ていく必要があるよねという事で下記の対応を行いました。

1. DatadogのCircleCI Integration

DatadogはCircleCIのIntegrationを有効にする事で下記のメトリクスを取得することが可能になります。CircleCIのInsightsで見れる情報ですね。

メトリクス名 内容
circleci.completed_build_time.sum (count)Total build time of completed (not canceled) builds (Shown as millisecond)
circleci.completed_build_time.avg (gauge)Average build time of completed (not canceled) builds (Shown as millisecond)
circleci.finished_builds.count (count) Count of all finished builds(Shown as build)
circleci.completed_builds.count (count)Count of all completed (not canceled) builds (Shown as build)

これにより、まずはビルドのジョブ単位での実行時間とビルドの成功状況をDatadogにて可視化することができました。
Datadog Dashboard for CI Metrics
Datadog Dashboard for CI Metrics

ジョブ別の平均実行時間

とあるリポジトリ名(repo_name)のビルド時間をジョブ(job_name)単位で表示しています。

# Datadog Metrics
autosmooth(avg:circleci.completed_build_time.avg{repo_name:xxxxxxx} by {job_name})
ビルドの成功状況

とあるリポジトリ名(repo_name)の実行結果(outcome)単位でカウントしています。

# Datadog Metrics
autosmooth(avg:circleci.finished_builds.count{repo_name:xxxxxxx} by {outcome}.as_count())

2. CIのジョブ → Datadog Logs

CircleCI Integrationで全体を俯瞰することはできるようになりました。
しかし今回問題となったExecutorのメモリ不足と思われるメトリクスを得ることはまだできていません。

もしかしたらCircleCIの仕組みとして良い感じの何かがあるのではと思ってサポートに問い合わせてみたところ、下記の記事を紹介してくれました。

https://support.circleci.com/hc/en-us/articles/360043994872-How-to-record-a-job-s-memory-usage

使っていたExecutorがDockerだったので、下記のようにアレンジにしてジョブ単位のメモリ使用状況を取得してDatadog Logsに送信する処理を追加しました。(API リファレンス > ログ)

  # Jobのmemory使用量を取得 & Datadog Logsに送信
  input_datadog:
    parameters:
      job_status:
        type: enum
        enum: [check_start, check_end]
    steps:
      - run:
          name: 'check memory usage'
          command: |
            max_usage_in_bytes=`cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes`
            curl -X POST "https://http-intake.logs.datadoghq.com/v1/input" \
              -H "Content-Type: text/plain" \
              -H "DD-API-KEY: ${DD_API_KEY}" \
              -d "{\"job_status\":\"<< parameters.job_status >>\",\"branch\":\"${CIRCLE_BRANCH}\",\"PR\":\"${CIRCLE_PULL_REQUEST}\",\"Job\":\"${CIRCLE_STAGE}\",\"ddsource\":\"circleci\",\"service\":\"circleci\",\"memory.max_usage_in_bytes\":\"${max_usage_in_bytes}\"}"
          when: always

これにより、CIのジョブのメモリ使用状況がDatadog Logsで確認できるようになりました。
Memory Usage in Datadog Logs
Memory Usage in Datadog Logs

3. Datadog Logs → カスタムメトリクス

Datadog Logsからカスタムメトリクスを生成することができます。
必要な材料は既に揃っているので、memory_usageをMeasureにしてこんな感じでメトリクスを生成します。

カスタムメトリクスの生成
カスタムメトリクスの生成

これによりジョブの開始前後のメモリ使用状況が可視化され、現在のresource_classで大丈夫なのか、ジョブのメモリ使用量は増加傾向にないかをチェックすることができるようになりました。

Datadog Dashboard
Datadog Dashboard for CI Metrics

ジョブ別のメモリ使用状況

CircleCIのメモリ使用状況(memory_usage)をジョブ(job)単位でカウントしています。

# Datadog Metrics
avg:circleci.memory_usage{*} by {job}

まとめ

  • DatadogのIntegrationを活用してCIのメトリクスも取得していきましょう
  • Integrationで取得できないものはLogsに飛ばしてからカスタムメトリクスにしましょう

余談

というのを実装した後でDatadogがContinuous Integration Visibilityという新機能をリリースしていました🎉(記事執筆時の 2021/12/03 時点ではまだベータ)
今後はそちらを使うのがスマートかと思いますので、使ってみた方は使い勝手をこっそり教えて下さい。
https://docs.datadoghq.com/ja/continuous_integration/

余談2

12/8のCircleCIのリリースによりジョブのCPU使用率とメモリ使用率が確認できるようになりました!
https://circleci.com/changelog/#docker-resource-utilization-graphs

メモリ不足で失敗したジョブの例
メモリ不足で失敗したジョブの例

DatadogのIntegrationでこの値を取得できるのかは確認中ですが、本記事の当初の目的であった「ジョブのエラーがメモリ不足に起因しているかどうか」を切り分けるために活躍してくれそうです。

Discussion