DatadogでHerokuを監視してみる


はじめに

Herokuのアプリケーションの稼働状況って正直見えづらいと思うので、ちゃんとこちらでコントロールできるように監視してやる必要があると思うんだ。
ということで、Datadogはメトリクス、APM、ログをまとめて見られるということで、Herokuの監視をしてみることにした。

環境

コミュニティのSlack招待ページをGithubのコードからHerokuにデプロイしてあるので、それを監視する。
Github - outsideris/slack-invite-automation

FreeプランのHerokuを使ったので、Dynoは一つ
言語はnode.js

セットアップ

参考にしたサイトは↓
https://docs.datadoghq.com/agent/basic_agent_usage/heroku/?tab=ussite

メトリクス

Datadog AgentをDynoにインストール

まずはAgentをインストールして各種システムメトリクスを取得
Datadog用のBuild Packをインストールすればいいみたい

# Enable Heroku Labs Dyno Metadata
heroku labs:enable runtime-dyno-metadata --app <HEROKU_APP_NAME>

<HEROKU_APP_NAME> はHerokuのアプリケーションの名前

# Add this buildpack and set your Datadog API key
heroku buildpacks:add --index 1 https://github.com/DataDog/heroku-buildpack-datadog.git
heroku config:add DD_API_KEY=<DD_API_KEY>

<DD_API_KEY> はDatadogのAPI Key

# Deploy to Heroku
git push heroku master

これでエージェントのインストール&セットアップ完了

ホスト名変更

Datadogはホスト単位で課金されるがDynoは名前が変わりやすいから、その度にDatadog上では別ホストとしてカウントされて課金が大きく跳ね上がってしまうリスクがあるとのこと
つまり、DynoがDatadogでのホストになるということですね

Heroku dynos are ephemeral-they can move to different host machines whenever new code is deployed, configuration changes are made, or resouce needs/availability changes. This makes Heroku flexible and responsive, but can potentially lead to a high number of reported hosts in Datadog. Datadog bills on a per-host basis, and the buildpack default is to report actual hosts, which can lead to higher than expected costs.

Refer to: https://docs.datadoghq.com/agent/basic_agent_usage/heroku/?tab=ussite#hostname

実際にDatadogではDynoのGUID(?)がホスト名になってるっぽい
Host Map

↓↓ ズームイン ↓↓

ということで、ホスト名を変更することに
今回は DD_DYNO_HOST という環境変数をいじることにする
これを true にすると、Dyno名がホスト名になるので、ホスト名が一意に決まって正しく課金されることになる

heroku config:set DD_DYNO_HOST=true --app <HEROKU_APP_NAME>

Host Map

↓↓ ズームイン ↓↓

モザイクかかっててわかりづらいかもだけど、ホスト名は <Heroku_APP_NAME>.<HEROKU_DYNO_NAME> になってます

システムメトリクスもちゃんととれてる
楽勝ですね

APM

APMでアプリケーションのパフォーマンスを可視化

APMは Application Performance Management の略で、アプリケーションのスループットやパフォーマンス、エラーを関数やメソッド単位でまでトラッキングできるしくみ
APMもDatadogで可視化できるですね

今回はNode.jsなので、Datadogのドキュメントにしたがってコードインスツルメンテーションしてみた
(参考) https://docs.datadoghq.com/tracing/languages/nodejs/

package.jsdd-trace を追記

package.js
{
  "name": "slack-invite-automation",
  "version": "0.3.4",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "^1.18.0",
    "cookie-parser": "^1.4.0",
    "dd-trace": "^0.7.3",
    "debug": "^3.1.0",
    "dotenv": "^5.0.1",
    "express": "^4.13.0",
    "i18n": "^0.8.3",
    "morgan": "^1.6.0",
    "pug": "^2.0.0-rc.4",
    "request": "^2.62.0",
    "serve-favicon": "^2.3.0",
    "sanitize": "^2.1.0"
  }
}

"dependencies" の3番目ね

続いて、モニタリング対象のjsにインスツルメント

routes/index.js
const tracer = require('dd-trace').init();
const express = require('express');
const router = express.Router();
const request = require('request');

const config = require('../config');
const { badge } = require('../lib/badge');

const sanitize = require('sanitize');

router.get('/', function(req, res) {
  res.setLocale(config.locale);
  res.render('index', { community: config.community,
                        tokenRequired: !!config.inviteToken,
                        recaptchaSiteKey: config.recaptchaSiteKey });
});

...

1行目に↓を追加しただけ

onst tracer = require('dd-trace').init();

あとはHerokuにデプロイ

# Add codes
git add .

# Commit
git commit -m "add dd-trace instrumentation"

# Push to Heroku
git push heroku master

しばらく待つと、APMデータが入ったっぽい

あと、Datadogでは env タグごとにトレースを見ることができるらしいが、Herokuの場合デフォルトでは何もセットされていないので、下記CLIで環境変数としてセットしてやる必要がある

heroku config:set DD_TAGS="env:heroku" --app <HEROKU_APP_NAME>

トレースを見る

Datadogでは一つ一つのリクエストを トレース データとして保存してすぐに可視化してくれるらしい
ただ、リクエスト数が多い場合はサンプリングされるそうだ

APMとシステムメトリクスの相関

host をキーにしてシステムメトリクスとの相関も見られるみたい

ログ

ログも見てみよう

Heroku Log Drains でHTTP経由でログをDatadogに送れるらしい
ただ、これはまだベータ(2019年2月現在)だとかゴニョゴニョ...
https://docs.datadoghq.com/agent/basic_agent_usage/heroku/?tab=ussite#heroku-log-collection

heroku drains:add https://http-intake.logs.datadoghq.com/v1/input/<DD_API_KEY>?ddsource=heroku&service=<SERVICE>&host=<HOST> -a <HEROKU_APP_NAME>

上記のエンドポイントでHTTP POSTされるログをDatadogにインデックスされるらしい
各クエリーストリングについて以下解説

  • ddsource: Datadogの source メタタグを付与。 source:heroku が付与されたログを自動的にパースしてくれる。
  • service: Datadogの source メタタグを付与。 APMと相関付けるためのタグ。 なので、APMの service に合わせよう。
  • host: Datadogの source メタタグを付与。 メトリクスやAPMとの相関付けで利用。 ホスト名変更 で設定したホスト名を指定しよう。

メトリクスやAPMはDatadog Agent経由で送信されるけど、ログはLog Drains使って直接Datadogのエンドポイントに送られるので、エージェントで指定したホスト名は反映されないんだ
だから、クエリーストリングで直接指定する必要があるんだね

source:heroku で検索すると、ログがインデックスされているのがわかりますね

ログのパース

自動的にパースされてるから検索・集計しやすくなってるよ

APMとログの相関

servicehost が紐づけられるから、トレースから該当時間のログにドリルダウンするのも簡単

これで設定完了

Herokuでアプリケーション作るたびにこれらの設定を手動で追加するのは少々手間なので、Terraformか何かで自動化したいなあ
それは次回以降の課題ということで

モニタリング

基本的なシステムリシースのダッシュボード、トレース、ログ検索・相関はDatadogのGUIそのままで使えるので、アラートやダッシュボード作りたい
そこまで書くと記事が盛りだくさんすぎてしまうので、それは次回以降にします