Posted at

DatadogでHerokuを監視してみる


はじめに

Herokuのアプリケーションの稼働状況って正直見えづらいと思うので、ちゃんとこちらでコントロールできるように監視してやる必要があると思うんだ。

ということで、Datadogはメトリクス、APM、ログをまとめて見られるということで、Herokuの監視をしてみることにした。


環境

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

Github - outsideris/slack-invite-automation

join-page.jpg

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

Image 2019-02-03 at 9.14.14 PM.png

↓↓ ズームイン ↓↓

Image 2019-02-03 at 9.17.29 PM.png

ということで、ホスト名を変更することに

今回は DD_DYNO_HOST という環境変数をいじることにする

これを true にすると、Dyno名がホスト名になるので、ホスト名が一意に決まって正しく課金されることになる

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

Host Map

Image 2019-02-03 at 9.37.03 PM.png

↓↓ ズームイン ↓↓

Image 2019-02-03 at 9.59.36 PM.png

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

システムメトリクスもちゃんととれてる

楽勝ですね

Image 2019-02-03 at 10.02.03 PM.png


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データが入ったっぽい

Image 2019-02-03 at 10.16.42 PM.png

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

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


トレースを見る

Datadogでは一つ一つのリクエストを トレース データとして保存してすぐに可視化してくれるらしい

ただ、リクエスト数が多い場合はサンプリングされるそうだ

Image 2019-02-03 at 10.18.35 PM.png


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

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

Image 2019-02-03 at 10.45.17 PM.png


ログ


ログも見てみよう

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 で検索すると、ログがインデックスされているのがわかりますね


ログのパース

Image 2019-02-03 at 10.34.12 PM.png

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

Image 2019-02-03 at 10.36.47 PM.png


APMとログの相関

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

Image 2019-02-03 at 10.42.36 PM.png


これで設定完了

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

それは次回以降の課題ということで


モニタリング

基本的なシステムリシースのダッシュボード、トレース、ログ検索・相関はDatadogのGUIそのままで使えるので、アラートやダッシュボード作りたい

そこまで書くと記事が盛りだくさんすぎてしまうので、それは次回以降にします