Edited at

初めてのDatadogとすぐに始められるサンプルコードを添えて


概要

Datadogのトライアルで試した各種設定方法をメモとして残したいと思います

なお、以下の各種設定をすぐに試せるように後述のソース(cloud-config)を用意したので、EC2のuser-dataにペーストすればすぐに試せるようになっています。起動するインスタンスを複数台にすることでコンテナ群として監視できるようになるので、是非お試しください


前提条件

以下の内容はAWSのリソースを監視する各種設定になります


サンプルソース

サンプルソースでは以下のDatadog設定やサンプルアプリが含まれている


  • APMを試すためのDockerコンテナで作られたNode.jsアプリ(WEB、APP、DBの3層構成)

  • dockerコンテナの監視を有効

  • ec2タグを取得するを有効

  • ログファイルの取得を有効(nginxのアクセスログ収集)

  • プロセスの取得を有効

  • APMの有効

※使用する前にコード内の<datadog api key>をご自身のAPI KEYに差し替えてください


cloud-config.yml#cloud-config

repo_update: true

repo_upgrade: all

write_files:
# Sample APP Docker compose file
- path: /var/docker/docker-compose.yml
permissions: 0644
owner: root:root
content: |
version: "3.7"
services:
web:
image: nginx:latest
container_name: web-container
ports:
- "80:80"
labels:
qiita.comefigo.service: "web"
volumes:
- ./web/default.conf:/etc/nginx/conf.d/default.conf
- ./web/log:/var/log/nginx
depends_on:
- app
app:
build:
context: ./app
dockerfile: Dockerfile
image: app
container_name: app-container
labels:
qiita.comefigo.service: "app"
depends_on:
- db
db:
image: redis:4
container_name: db-container
labels:
qiita.comefigo.service: "db"
# Sample APP app.js
- path: /var/docker/app/app.js
permissions: 0644
owner: root:root
content: |
const tracer = require("dd-trace").init();
const http = require("http");
const redis = require("redis");
const async = require("async");

const redisClient = redis.createClient({
host: "db",
port: 6379
});
redisClient.on("error", function(err) {
console.log("error");
console.log(err);
});

// サンプルデータの投入
redisClient.set("data1", "hello world 1");
redisClient.set("data2", "hello world 2");

const handleRequest = function(request, response) {
let resp = "";
async.parallel(
[
function(callback) {
redisClient.get("data1", function(error, value) {
callback(null, value);
});
},
function(callback) {
redisClient.get("data2", function(error, value) {
callback(null, value);
});
}
],
function(err, results) {
for (let i = 0; i < results.length; i++) {
resp += "<ul> " + results[i] + " </ul>";
}
response.writeHead(200);
return response.end("<h1>redis value:</h1><br/>" + resp);
}
);
};

const www = http.createServer(handleRequest);
www.listen(3000);
# Sample APP package.json
- path: /var/docker/app/package.json
permissions: 0644
owner: root:root
content: |
{
"name": "datadog-trial-app",
"version": "1.0.0",
"description": "A simple Node.js app for Datadog trial",
"main": "app.js",
"dependencies": {
"async": "^2.6.2",
"dd-trace": "^0.10.2",
"redis": "^2.8.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Datadog",
"APM"
],
"author": "comefigo",
"license": "ISC"
}
# Sample APP Dockerfile
- path: /var/docker/app/Dockerfile
permissions: 0644
owner: root:root
content: |
FROM node:8
ADD ./package.json /app/package.json
WORKDIR /app
RUN npm install
ADD ./app.js /app/app.js
CMD node ./app.js
- path: /var/docker/web/default.conf
permissions: 0644
owner: root:root
content: |
server {
listen 80;
server_name localhost;

access_log /var/log/nginx/host.access.log main;

location / {
proxy_pass http://app:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# datadog config for monitoring docker containers
- path: /tmp/docker.yaml
permissions: 0644
owner: root:root
content: |
init_config:

# docker socket経由でDockerの監視
instances:
- url: "unix://var/run/docker.sock"
collect_events: true
new_tag_names: true
collect_container_size: true
collect_exit_codes: true
# datadog config for monitoring nginx log
- path: /tmp/nginx.yaml
permissions: 0644
owner: root:root
content: |
logs:
- type: file
service: sample_service
path: /var/docker/web/log/host.access.log
source: nginx
sourcecategory: http_web_access
# datadog config
- path: /tmp/datadog.yaml
permissions: 0644
owner: root:root
content: |
api_key: <datadog api key>
tags:
- env:prd
- role:app
- tenant:datadog-app

# EC2のタグを利用する
# ただし、Nameタグは利用されない
collect_ec2_tags: true

# ログ収集を有効
# 各種ログの設定は別途必要
logs_enabled: true

# container labelを別名のタグ名に変換
docker_labels_as_tags:
qiita.comefigo.service: service

# プロセスの監視
process_config:
enabled: "true"

# APM
apm_config:
enabled: true

runcmd:
- [
sh,
-c,
'DD_API_KEY=<datadog api key> bash -c "$(curl -L https://raw.githubusercontent.com/DataDog/datadog-agent/master/cmd/agent/install_script.sh)"',
]
- sudo systemctl start datadog-agent
- sudo systemctl enable datadog-agent
- [sh, -c, "amazon-linux-extras install -y docker"]
- sudo systemctl start docker
- sudo systemctl enable docker
- [sh, -c, "usermod -aG docker ec2-user"]
- [sh, -c, "usermod -aG docker dd-agent"]
- [
sh,
-c,
'curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose',
]
- [sh, -c, "chmod +x /usr/local/bin/docker-compose"]
- [sh, -c, "mkdir -p /var/docker/web/log"]
- sudo chown ec2-user:ec2-user -R /var/docker
- [sh, -c, "docker-compose -f /var/docker/docker-compose.yml up -d"]
- sudo mv /tmp/docker.yaml /etc/datadog-agent/conf.d/docker.d/docker.yaml
- sudo chown dd-agent:dd-agent /etc/datadog-agent/conf.d/docker.d/docker.yaml
- sudo mv /tmp/nginx.yaml /etc/datadog-agent/conf.d/nginx.d/nginx.yaml
- sudo chown dd-agent:dd-agent /etc/datadog-agent/conf.d/nginx.d/nginx.yaml
- sudo mv /tmp/datadog.yaml /etc/datadog-agent/datadog.yaml
- sudo chown dd-agent:dd-agent /etc/datadog-agent/datadog.yaml
- sudo systemctl restart datadog-agent



大きな流れ


  1. Agentの導入

  2. 設定ファイルの作成

  3. ダッシュボードの作成

  4. アラート(Monitors)の作成


始める前に得ていた情報

以下では営業担当者との情報交換で得た情報になります


料金関連

基本的に料金プラン通りの価格である

500ホスト/月以上を扱う場合はサポートに相談

料金に関する質問などをQA形式


Q. 開発用のホスト(すぐ破棄や停止するホスト)やオートスケールした分のホストは課金対象になるのか?

ホストにタグ付けすることで課金対象の範囲を絞り込むことができるので、

そういった用途のホストはその対象外のタグにすることで課金除外することはできる


Q. 利用時間が1月未満の課金ホストの扱いはどうなるのか?

時間単位の課金もあるので、必要に応じて時間課金($0.03/h)を利用することも可能

例えば、年払いで一定数のホスト分を予め支払い、一時利用で超過したホスト分を時間単位で追加課金することも可能

参考:課金に関するFAQ


Q. 課金対象数の算出方法は?

1か月の間で課金対象のホスト数の最大値が課金対象となる

一時利用で立ち上げたホストも課金対象となるので要注意!


Q. 年払いと月払いを混合できるか?

混合はできない

2契約にするならできなくもない


各種設定


エージェントの導入

導入方法は非常に簡単

「Integrations」-「Agent」でプラットフォームにあった導入方法で簡単に導入することができる


Slack

若干癖がある設定・・・


  1. Datadogの「Integration」から「Slack」をインストール

  2. SlackのAppで「Datadog」をインストールし、「Webhook URL」をコピー

  3. DatadogのSlack設定で「Slack Account Name」に通知先のSlackワークスペースを識別できるように適当な名前を付ける。「Slack Account Hook」に前述でコピーしたWebhook URLを設定し、一度「Update Configuration」←ここ重要!

  4. Slack設定で「Channel to post to」に「#チャネル名」、「Account」に「Slack Account Name」で設定した名前を選択し、「Update Configuration」で完了


  5. 通知テスト

    ダッシュボードの適当なメトリックの「📷」アイコンで「@」+「Slack Account Name」で送信

    Slackのみならず、登録されているアカウントやDatadogのサポートへ送信することもできる


  6. Slackで受信




設定ファイル

拡張機能の設定ファイルは/etc/datadog-agent/conf.d配下に適当に置けば読み込んでくれるかと思ったが、きちんと所定のフォルダに配置しなければならない


設定確認

datadog-agent statusでagentに適用されている設定を確認する

設定が間違っている場合はErrorとなっているので、デバッグとしても利用できる


Getting the status from the agent.

===============
Agent (v6.10.1)
===============

Status date: 2019-03-15 00:12:44.720529 JST
Pid: 21905
Python Version: 2.7.15
Logs:
Check Runners: 4
Log Level: info

Paths
=====
Config File: /etc/datadog-agent/datadog.yaml
conf.d: /etc/datadog-agent/conf.d
checks.d: /etc/datadog-agent/checks.d

Clocks
======
System UTC time: 2019-03-15 00:12:44.720529 JST

Host Info
=========
bootTime: 2019-03-14 23:08:43.000000 JST
kernelVersion: 4.14.97-90.72.amzn2.x86_64
os: linux
platform: amazon
platformFamily: rhel
platformVersion: 2
procs: 197
uptime: 1h4m0s
virtualizationRole: guest
virtualizationSystem: xen

Hostnames
=========
ec2-hostname: xxxxx.ap-northeast-1.compute.internal
hostname: xxxxx
instance-id: xxxxx
socket-fqdn: xxxxx.ap-northeast-1.compute.internal.
socket-hostname: xxxxx.ap-northeast-1.compute.internal
hostname provider: aws
unused hostname providers:
configuration/environment: hostname is empty
gce: unable to retrieve hostname from GCE: status code 404 trying to GET http://xxxxx/computeMetadata/v1/instance/hostname

=========
Collector
=========

Running Checks
==============

docker
------
Instance ID: docker [OK]
Total Runs: 1
Metric Samples: Last Run: 21, Total: 21
Events: Last Run: 0, Total: 0
Service Checks: Last Run: 1, Total: 1
Average Execution Time : 11ms

========
JMXFetch
========

Initialized checks
==================
no checks

Failed checks
=============
no checks

=========
Forwarder
=========

Transactions
============
CheckRunsV1: 0
Dropped: 0
DroppedOnInput: 0
Events: 0
HostMetadata: 0
IntakeV1: 1
Metadata: 0
Requeued: 0
Retried: 0
RetryQueueSize: 0
Series: 0
ServiceChecks: 0
SketchSeries: 0
Success: 1
TimeseriesV1: 0

API Keys status
===============
API key ending with : API Key valid

==========
Endpoints
==========
https://app.datadoghq.com - API Key ending with:

==========
Logs Agent
==========

tomcat
------
Type: file
Path: /var/log/hogehoge.log
Status: OK
Inputs: /var/log/hogehoge.log


ホストやコンテナのタグ付け

ダッシュボードでホストやリソースをグルーピングやフィルタリングするためにタグ付けをします

今どきの監視ツールにおいてはなくてはならない仕組みなので、予めタグ設計をしとくと良いでしょう

例えば、同じ役割を担うホストをappとタグ付けすることで、それらをまとめて俯瞰することができる

後述になりますが、「Host Map」で閾値に従ってビジュアライズすることもできるので、一目で問題箇所を特定することができる


/etc/datadog-agent/datadog.yaml

tags:

- env:prod
- role:app

EC2のタグを用いる場合はcollect_ec2_tags: trueを追加しましょう

※Nameタグは利用されないので、ご注意!


/etc/datadog-agent/datadog.yaml

collect_ec2_tags: true



Host Map

ホストまたはコンテナをタグ別に俯瞰できる

冗長化されたシステムやWEB、APP、DBなどの3層式構成の場合は、階層ごとにタグを分けることでどこで障害が発生しているのかも見つけやすくなる

下記の画像ではHostsのHost Mapですが、前述のサンプルを用いた場合は、ContainersのGroup hosts By tagをserviceにすることで同様な表示になります


タグ付けの制限

リファレンスにも書かれていますが、改めて


  • unicodeで200文字まで

  • すべて小文字

  • スネークケース(test_tag

  • キーでhostdevicesourceserviceは予約語のため使用してはいけない


Monitors

メトリックスが閾値に達した時、規定値を外れた時、普段とは異なる値になった時(機械学習)などにお知らせしてくれます

また、例えば特定の状況下でシステムの自動再起動も設定することができる


通知

検知したメトリックスの画像付きで通知してくれるので、非常にわかりやすい

また、メッセージで使用できるメッセージテンプレート変数も豊富なので、痒い所に手が届く作りかなと思う


履歴

メトリックスの履歴が保存されている


ダッシュボード

集めたデータ(各種メトリックス、ログ、発生したイベント、APM)をダッシュボードでシステム全体を俯瞰することができる

個人的に一番気に入っているのはダッシュボード内の情報を絞り込むための変数を定義することができるのでダッシュボードの可用性が高まる

例えば同じ中身でホストが違うダッシュボードをいくつも作るようなこともなくなる


レスポンステスト(Synthetics

グローバルゾーン(アメリカ、イギリス、ドイツ、東京)でレスポンステスト(ステータスコード、レスポンスタイム)が可能

HTTPメソッドごとにテストを作成できる

POSTパラメータを投入することでフォームのテストも可能

※連続したページのテストはできない

テストごとにタグを設定することでテスト結果のフィルタリングも可能


テスト結果

サイトの稼働率が一目でわかる

問題検知時と回復時にSlack通知

一旦トライアルが切れたのでここまですが、今後APMや他の設定を試したら追加していきたいと思います