Datadog
クラウドネイティブ環境向けの統合監視・可視化プラットフォーム。APM、インフラ監視、ログ管理、セキュリティ監視を一元化。機械学習による異常検知機能。
監視サーバー
Datadog
概要
Datadogはクラウドネイティブ環境向けの統合監視・可視化プラットフォームです。APM、インフラ監視、ログ管理、セキュリティ監視を一元化し、機械学習による異常検知機能を提供します。SaaS監視市場でリーダーポジションを維持し、年間売上20億ドル超、Fortune 500企業の多くが採用するAI・機械学習統合の次世代監視プラットフォームです。
詳細
Datadogは2010年にOlivier Pomelらによって設立され、現在ではSaaS監視市場でリーダーポジションを維持しています。年間売上20億ドル超、Fortune 500企業の多くが採用し、AI・機械学習統合で次世代監視プラットフォームに進化を続けています。クラウドファースト戦略により継続的な成長を遂げ、統合監視ソリューションの業界標準として確立されています。
主要な技術的特徴
- 統合監視プラットフォーム: インフラ、APM、ログ、セキュリティの一元管理
- 機械学習統合: AI支援による異常検知と予測分析
- クラウドネイティブ対応: AWS、Azure、GCP等主要クラウドとの深い統合
- リアルタイム監視: 高頻度メトリクス収集と即座のアラート
- 豊富なインテグレーション: 800+のサービス・ツール統合
用途
- クラウドインフラ監視
- アプリケーション性能監視(APM)
- ログ管理と分析
- セキュリティ監視とSIEM
- ビジネスメトリクス可視化
メリット・デメリット
メリット
- 統合プラットフォーム: 全領域をカバーする統一ソリューション
- AI/ML機能: 機械学習による高度な異常検知
- 豊富なインテグレーション: 800+のサービス統合
- スケーラビリティ: エンタープライズ規模での高い信頼性
- ユーザビリティ: 直感的なUI/UXと高い操作性
- 24/7サポート: 充実したサポート体制
デメリット
- 高コスト: エンタープライズ向けの高額な料金体系
- ベンダーロックイン: SaaSプラットフォームへの依存
- 学習コスト: 豊富な機能による習得の複雑さ
- データ主権: クラウドベースによるデータ管理の制約
- カスタマイズ制限: SaaSによるカスタマイズの限界
参考ページ
書き方の例
Datadog Agent設定
# datadog.yaml
api_key: YOUR_API_KEY_HERE
site: datadoghq.com
# ホスト名設定
hostname: web-server-01
hostname_fqdn: web-server-01.example.com
# タグ設定
tags:
- env:production
- service:web
- team:backend
- region:us-east-1
# ログ収集設定
logs_enabled: true
logs_config:
container_collect_all: true
use_http: true
compression_level: 6
# APM設定
apm_config:
enabled: true
receiver_port: 8126
max_traces_per_second: 10
# プロセス監視
process_config:
enabled: true
scrub_args: true
# Network Performance Monitoring
network_config:
enabled: true
# システムプローブ
system_probe_config:
enabled: true
# 収集間隔
check_runners: 4
collection_timeout: 30
# プロキシ設定
proxy:
http: http://proxy.example.com:8080
https: https://proxy.example.com:8080
no_proxy:
- localhost
- 127.0.0.1
# JMX設定
jmx_use_cgroup_memory_limit: true
# Security Agent
security_agent:
enabled: true
# Remote Configuration
remote_configuration:
enabled: true
カスタムメトリクス送信
# custom_metrics.py
from datadog import initialize, api, statsd
import time
import psutil
import requests
# Datadog初期化
options = {
'api_key': 'YOUR_API_KEY',
'app_key': 'YOUR_APP_KEY'
}
initialize(**options)
class CustomMetricsCollector:
def __init__(self):
self.statsd = statsd
def collect_system_metrics(self):
"""システムメトリクス収集"""
# CPU使用率
cpu_percent = psutil.cpu_percent(interval=1)
self.statsd.gauge('custom.system.cpu_percent', cpu_percent,
tags=['host:web-01', 'env:prod'])
# メモリ使用率
memory = psutil.virtual_memory()
self.statsd.gauge('custom.system.memory_percent', memory.percent,
tags=['host:web-01', 'env:prod'])
# ディスク使用率
disk = psutil.disk_usage('/')
disk_percent = (disk.used / disk.total) * 100
self.statsd.gauge('custom.system.disk_percent', disk_percent,
tags=['host:web-01', 'env:prod'])
def collect_application_metrics(self):
"""アプリケーションメトリクス収集"""
# API レスポンス時間測定
start_time = time.time()
try:
response = requests.get('http://localhost:8080/health', timeout=5)
response_time = (time.time() - start_time) * 1000
self.statsd.histogram('custom.api.response_time', response_time,
tags=['endpoint:health', 'env:prod'])
# ステータスコード
self.statsd.increment('custom.api.requests',
tags=[f'status_code:{response.status_code}', 'env:prod'])
except requests.RequestException as e:
self.statsd.increment('custom.api.errors',
tags=['error_type:timeout', 'env:prod'])
def send_custom_event(self, title, text, alert_type='info'):
"""カスタムイベント送信"""
api.Event.create(
title=title,
text=text,
alert_type=alert_type,
tags=['custom:event', 'env:prod']
)
def run_continuous_monitoring(self):
"""継続的監視実行"""
while True:
try:
self.collect_system_metrics()
self.collect_application_metrics()
time.sleep(60) # 1分間隔
except Exception as e:
print(f"Monitoring error: {e}")
time.sleep(60)
if __name__ == "__main__":
collector = CustomMetricsCollector()
collector.run_continuous_monitoring()
Docker統合設定
# docker-compose.yml
version: '3.8'
services:
datadog-agent:
image: gcr.io/datadoghq/agent:7
container_name: datadog-agent
restart: unless-stopped
environment:
- DD_API_KEY=${DD_API_KEY}
- DD_SITE=datadoghq.com
- DD_LOGS_ENABLED=true
- DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL=true
- DD_APM_ENABLED=true
- DD_APM_NON_LOCAL_TRAFFIC=true
- DD_PROCESS_AGENT_ENABLED=true
- DD_SYSTEM_PROBE_ENABLED=true
- DD_DOGSTATSD_NON_LOCAL_TRAFFIC=true
- DD_AC_EXCLUDE=image:gcr.io/datadoghq/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc/:/host/proc/:ro
- /opt/datadog-agent/run:/opt/datadog-agent/run:rw
- /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /etc/passwd:/etc/passwd:ro
- ./datadog.yaml:/etc/datadog-agent/datadog.yaml:ro
- ./conf.d:/etc/datadog-agent/conf.d:ro
ports:
- "8125:8125/udp" # DogStatsD
- "8126:8126" # APM
cap_add:
- SYS_ADMIN
- SYS_RESOURCE
- SYS_PTRACE
- NET_ADMIN
- NET_BROADCAST
- NET_RAW
- IPC_LOCK
security_opt:
- apparmor:unconfined
networks:
- monitoring
webapp:
image: nginx:alpine
container_name: webapp
labels:
- "com.datadoghq.ad.check_names=[\"nginx\"]"
- "com.datadoghq.ad.init_configs=[{}]"
- "com.datadoghq.ad.instances=[{\"nginx_status_url\":\"http://%%host%%:81/nginx_status\"}]"
- "com.datadoghq.ad.logs=[{\"source\":\"nginx\",\"service\":\"webapp\"}]"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
- "81:81"
networks:
- monitoring
networks:
monitoring:
driver: bridge
Kubernetes統合設定
# datadog-agent.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: datadog-agent
namespace: datadog
spec:
selector:
matchLabels:
app: datadog-agent
template:
metadata:
labels:
app: datadog-agent
name: datadog-agent
spec:
serviceAccountName: datadog-agent
containers:
- image: gcr.io/datadoghq/agent:7
imagePullPolicy: Always
name: datadog-agent
ports:
- containerPort: 8125
name: dogstatsdport
protocol: UDP
- containerPort: 8126
name: traceport
protocol: TCP
env:
- name: DD_API_KEY
valueFrom:
secretKeyRef:
name: datadog-secret
key: api-key
- name: DD_CLUSTER_NAME
value: "production-cluster"
- name: DD_SITE
value: "datadoghq.com"
- name: DD_LOGS_ENABLED
value: "true"
- name: DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL
value: "true"
- name: DD_APM_ENABLED
value: "true"
- name: DD_APM_NON_LOCAL_TRAFFIC
value: "true"
- name: DD_PROCESS_AGENT_ENABLED
value: "true"
- name: DD_KUBERNETES_KUBELET_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: KUBERNETES
value: "true"
- name: DD_HEALTH_PORT
value: "5555"
- name: DD_DOGSTATSD_NON_LOCAL_TRAFFIC
value: "true"
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "500m"
volumeMounts:
- name: dockersocket
mountPath: /var/run/docker.sock
- name: procdir
mountPath: /host/proc
readOnly: true
- name: cgroups
mountPath: /host/sys/fs/cgroup
readOnly: true
- name: config
mountPath: /etc/datadog-agent
livenessProbe:
httpGet:
path: /health
port: 5555
initialDelaySeconds: 15
periodSeconds: 15
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 5555
initialDelaySeconds: 15
periodSeconds: 15
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
volumes:
- hostPath:
path: /var/run/docker.sock
name: dockersocket
- hostPath:
path: /proc
name: procdir
- hostPath:
path: /sys/fs/cgroup
name: cgroups
- configMap:
name: datadog-config
name: config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: datadog-config
namespace: datadog
data:
datadog.yaml: |
api_key: ${DD_API_KEY}
site: datadoghq.com
logs_enabled: true
apm_config:
enabled: true
process_config:
enabled: true
kubernetes_kubelet_host: ${DD_KUBERNETES_KUBELET_HOST}
tags:
- cluster:production
- env:prod
アラート設定(Terraform)
# alerts.tf
terraform {
required_providers {
datadog = {
source = "DataDog/datadog"
version = "~> 3.0"
}
}
}
provider "datadog" {
api_key = var.datadog_api_key
app_key = var.datadog_app_key
api_url = "https://api.datadoghq.com/"
}
# CPU使用率アラート
resource "datadog_monitor" "high_cpu" {
name = "High CPU Usage"
type = "metric alert"
message = <<-EOF
CPU usage is above 80% for more than 5 minutes
@slack-alerts
@pagerduty-team
EOF
query = "avg(last_5m):avg:system.cpu.user{env:production} by {host} > 80"
monitor_thresholds {
critical = 80
warning = 70
}
notify_no_data = true
no_data_timeframe = 10
tags = ["team:sre", "env:production", "service:system"]
}
# APMエラー率アラート
resource "datadog_monitor" "high_error_rate" {
name = "High Error Rate"
type = "metric alert"
message = <<-EOF
Error rate is above 5% for service {{service.name}}
@slack-alerts
EOF
query = "avg(last_10m):sum:trace.web.request.errors{env:production} by {service}.as_rate() / sum:trace.web.request.hits{env:production} by {service}.as_rate() > 0.05"
monitor_thresholds {
critical = 0.05
warning = 0.03
}
tags = ["team:backend", "env:production", "service:apm"]
}
# ログベースアラート
resource "datadog_monitor" "error_logs" {
name = "Error Log Spike"
type = "log alert"
message = "Error log count is unusually high @slack-alerts"
query = "logs(\"status:error env:production\").index(\"*\").rollup(\"count\").last(\"15m\") > 100"
monitor_thresholds {
critical = 100
warning = 50
}
tags = ["team:sre", "env:production", "service:logs"]
}
# 外形監視
resource "datadog_synthetics_test" "api_test" {
type = "api"
subtype = "http"
name = "API Health Check"
message = "API endpoint is down @slack-alerts"
locations = ["aws:us-east-1", "aws:eu-west-1"]
options_list {
tick_every = 60
retry {
count = 2
interval = 300
}
monitor_options {
renotify_interval = 120
}
}
request_definition {
method = "GET"
url = "https://api.example.com/health"
assertion {
type = "statusCode"
operator = "is"
target = "200"
}
assertion {
type = "responseTime"
operator = "lessThan"
target = "2000"
}
}
tags = ["team:api", "env:production", "service:synthetics"]
}
ダッシュボード設定
{
"title": "Infrastructure Overview",
"description": "Main infrastructure monitoring dashboard",
"widgets": [
{
"id": 1,
"definition": {
"type": "timeseries",
"requests": [
{
"q": "avg:system.cpu.user{env:production} by {host}",
"display_type": "line",
"style": {
"palette": "dog_classic",
"line_type": "solid",
"line_width": "normal"
}
}
],
"title": "CPU Usage by Host",
"title_size": "16",
"title_align": "left",
"yaxis": {
"label": "Percentage",
"scale": "linear",
"min": "auto",
"max": "auto"
}
},
"layout": {
"x": 0,
"y": 0,
"width": 47,
"height": 15
}
},
{
"id": 2,
"definition": {
"type": "query_value",
"requests": [
{
"q": "avg:system.mem.pct_usable{env:production}",
"aggregator": "avg"
}
],
"title": "Average Memory Usage",
"title_size": "16",
"title_align": "left",
"precision": 2,
"unit": "%"
},
"layout": {
"x": 48,
"y": 0,
"width": 23,
"height": 15
}
},
{
"id": 3,
"definition": {
"type": "toplist",
"requests": [
{
"q": "top(avg:trace.web.request.duration{env:production} by {service}, 10, 'mean', 'desc')"
}
],
"title": "Slowest Services",
"title_size": "16",
"title_align": "left"
},
"layout": {
"x": 72,
"y": 0,
"width": 47,
"height": 15
}
},
{
"id": 4,
"definition": {
"type": "log_stream",
"query": "status:error env:production",
"columns": [
"host",
"service",
"@timestamp",
"message"
],
"title": "Error Logs",
"title_size": "16",
"title_align": "left",
"message_display": "expanded-md",
"sort": {
"column": "@timestamp",
"order": "desc"
}
},
"layout": {
"x": 0,
"y": 16,
"width": 119,
"height": 36
}
}
],
"template_variables": [
{
"name": "env",
"default": "production",
"prefix": "env"
},
{
"name": "service",
"default": "*",
"prefix": "service"
}
],
"layout_type": "ordered",
"is_read_only": false,
"notify_list": [],
"reflow_type": "fixed",
"tags": ["team:sre", "env:production"]
}
アプリケーション統合(Python)
# app_integration.py
from ddtrace import tracer, patch
from ddtrace.contrib.flask import TraceMiddleware
from datadog import DogStatsdClient
import logging
import time
from flask import Flask, request
# トレーシング設定
patch(sqlalchemy=True, requests=True, redis=True)
# メトリクス設定
statsd = DogStatsdClient(host='localhost', port=8125)
# ログ設定
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
traced_app = TraceMiddleware(app, tracer, service="web-app")
@app.before_request
def before_request():
request.start_time = time.time()
# リクエストメトリクス
statsd.increment('web.request.count',
tags=[f'endpoint:{request.endpoint}', 'env:production'])
@app.after_request
def after_request(response):
# レスポンス時間
response_time = (time.time() - request.start_time) * 1000
statsd.histogram('web.request.duration', response_time,
tags=[f'endpoint:{request.endpoint}',
f'status_code:{response.status_code}'])
# ステータスコード
statsd.increment('web.response.count',
tags=[f'status_code:{response.status_code}'])
return response
@tracer.wrap('database', service='db')
def get_user_data(user_id):
"""データベースアクセスのトレーシング"""
with tracer.trace('db.query', service='postgresql') as span:
span.set_tag('user.id', user_id)
span.set_tag('db.operation', 'select')
# DBアクセスシミュレーション
time.sleep(0.01)
return {"user_id": user_id, "name": "Test User"}
@app.route('/health')
def health_check():
"""ヘルスチェックエンドポイント"""
return {"status": "healthy", "timestamp": time.time()}
@app.route('/user/<int:user_id>')
def get_user(user_id):
"""ユーザー情報取得"""
try:
with tracer.trace('user.get', service='web-app') as span:
span.set_tag('user.id', user_id)
user_data = get_user_data(user_id)
logger.info(f"User data retrieved", extra={
'user_id': user_id,
'dd.trace_id': span.trace_id,
'dd.span_id': span.span_id
})
return user_data
except Exception as e:
statsd.increment('web.error.count',
tags=['error_type:user_not_found'])
logger.error(f"Error retrieving user: {e}", extra={
'user_id': user_id,
'error': str(e)
})
return {"error": "User not found"}, 404
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)