From pup
Manages Datadog monitors: list, create, update, mute/unmute via pup CLI, plus best practices for thresholds, scoping, recovery, and alert fatigue prevention.
npx claudepluginhub datadog-labs/pup --plugin pupThis skill uses the workspace's default tool permissions.
Create, manage, and maintain monitors for alerting.
Manages Datadog monitors, dashboards, metrics, logs, events, and incidents via Python CLI using REST API. Requires DD_API_KEY and DD_APP_KEY.
Automates Datadog tasks via Rube MCP/Composio: query metrics/logs, manage monitors/dashboards, create events/downtimes. Useful for observability workflows after connecting toolkit.
Automates Datadog tasks via Rube MCP: query metrics, search logs, manage monitors/dashboards, create events and downtimes. Requires active Datadog connection.
Share bugs, ideas, or general feedback.
Create, manage, and maintain monitors for alerting.
This requires Go or the pup binary in your path.
pup - go install github.com/datadog-labs/pup@latest
Ensure ~/go/bin is in $PATH.
pup auth login
pup monitors list
pup monitors list --tags "team:platform"
pup monitors search --query "status:Alert"
pup monitors get <id>
pup monitors create --file monitor.json
# Mute with duration
pup monitors update 12345 --file monitor-muted.json
# Or mute with specific end time
pup monitors update 12345 --file monitor-muted-until.json
# Unmute
pup monitors update 12345 --file monitor-unmuted.json
| Rule | Why |
|---|---|
| No flapping alerts | Use last_Xm not last_1m |
| Meaningful thresholds | Based on SLOs, not guesses |
| Actionable alerts | If no action needed, don't alert |
| Include runbook | @runbook-url in message |
# WRONG - will flap constantly
query = "avg(last_1m):avg:system.cpu.user{*} > 50" # ❌ Too sensitive
# CORRECT - stable alerting
query = "avg(last_5m):avg:system.cpu.user{env:prod} by {host} > 80" # ✅ Reasonable window
# WRONG - alerts on everything
query = "avg(last_5m):avg:system.cpu.user{*} > 80" # ❌ No scope
# CORRECT - scoped to what matters
query = "avg(last_5m):avg:system.cpu.user{env:prod,service:api} by {host} > 80" # ✅
monitor = {
"query": "avg(last_5m):avg:system.cpu.user{env:prod} > 80",
"options": {
"thresholds": {
"critical": 80,
"critical_recovery": 70, # ✅ Prevents flapping
"warning": 60,
"warning_recovery": 50
}
}
}
message = """
## High CPU Alert
Host: {{host.name}}
Current Value: {{value}}
Threshold: {{threshold}}
### Runbook
1. Check top processes: `ssh {{host.name}} 'top -bn1 | head -20'`
2. Check recent deploys
3. Scale if needed
@slack-ops @pagerduty-oncall
"""
Use safe deletion workflow (same as dashboards):
def safe_mark_monitor_for_deletion(monitor_id: str, client) -> bool:
"""Mark monitor instead of deleting."""
monitor = client.get_monitor(monitor_id)
name = monitor.get("name", "")
if "[MARKED FOR DELETION]" in name:
print(f"Already marked: {name}")
return False
new_name = f"[MARKED FOR DELETION] {name}"
client.update_monitor(monitor_id, {"name": new_name})
print(f"✓ Marked: {new_name}")
return True
| Type | Use Case |
|---|---|
metric alert | CPU, memory, custom metrics |
query alert | Complex metric queries |
service check | Agent check status |
event alert | Event stream patterns |
log alert | Log pattern matching |
composite | Combine multiple monitors |
apm | APM metrics |
# Find monitors without owners
pup monitors list | jq '.[] | select(.tags | contains(["team:"]) | not) | {id, name}'
# Find noisy monitors (high alert count)
pup monitors list | jq 'sort_by(.overall_state_modified) | .[:10] | .[] | {id, name, status: .overall_state}'
| Use | When |
|---|---|
| Mute monitor | Quick one-off, < 1 hour |
| Downtime | Scheduled maintenance, recurring |
# Downtime (preferred)
pup downtime create --file downtime.json
| Problem | Fix |
|---|---|
| Alert not firing | Check query returns data, thresholds |
| Too many alerts | Increase window, add recovery threshold |
| No data alerts | Check agent connectivity, metric exists |
| Auth error | pup auth refresh |