datadog-radar
Observability FinOps scanner for Datadog. Pulls cost, usage, custom metric cardinality and configuration inventory from one CLI command, then flags the things that actually drive a Datadog bill.
Part of the Hyperscaler Radar suite.
Install
pip install datadog-radar
Auth
Datadog read endpoints need two credentials:
- API key — Organization Settings → API Keys
- Application key — Organization Settings → Application Keys
The Application key must belong to a user with usage_read and billing_read. Cost endpoints are parent-org only — a child org will return 403 on cost but still scan everything else.
export DD_API_KEY=<api-key>
export DD_APP_KEY=<app-key>
export DD_SITE=datadoghq.com # optional; see sites below
Or pass --api-key / --app-key / --site inline.
Supported sites
datadoghq.com (default) · us3.datadoghq.com · us5.datadoghq.com · datadoghq.eu · ap1.datadoghq.com · ap2.datadoghq.com · ddog-gov.com · us2.ddog-gov.com
Usage
# Full scan — all domains, rich tables
datadog-radar scan
# Cost and custom metrics only
datadog-radar scan --domains cost,metrics
# EU org, six months of history
datadog-radar scan --site datadoghq.eu --months 6
# JSON to stdout
datadog-radar scan --output json
# JSON to a file plus per-resource CSVs for an SA review packet
datadog-radar scan --out-file report.json --csv-dir ./review/
# Sample more custom metrics (default 100)
datadog-radar scan --domains metrics --metric-limit 500
datadog-radar domains
datadog-radar version
Domains
| Domain | What it scans |
|---|---|
cost |
Estimated, projected, historical and billable cost; sub-org breakdown |
usage |
Usage summary across all product families |
metrics |
Top custom metrics by hourly average; Metrics without Limits configuration |
attribution |
Active billing dimensions and monthly cost attribution |
inventory |
Hosts, monitors, log indexes, synthetics, RUM apps, dashboards, SLOs, orgs |
Findings engine
The scan is the input; the findings are the point. Each one names the signal it fired on so you can verify it against the customer's contract before acting.
| Severity | Example finding |
|---|---|
high |
High-cardinality custom metrics dominating billed timeseries |
high |
Log indexes with no daily_limit — uncapped overage exposure |
high |
Hosts missing env / service / team — chargeback is impossible |
high |
Projected month-end cost running ahead of month-to-date pace |
medium |
Metrics without Limits never configured — every tag combo billed |
medium |
Indexes retained past 15 days that belong in Flex Logs or archive |
medium |
Indexes with no exclusion filter |
medium |
Browser synthetic tests running every 5 minutes or faster |
medium |
Monitors stuck in No Data — decommissioned infra, live config |
low |
Muted hosts still reporting and still billing |
Findings are sorted by severity and exported to findings.csv alongside the resource inventory.
Example output
╭──────────────────────────────────────────────╮
│ Datadog Radar · Observability FinOps Scanner │
│ site: datadoghq.com │
╰──────────────────────────────────────────────╯
💰 Cost
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ View ┃ Org / Period ┃ Total ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ estimated │ Acme · 2026-07 │ $48,210.44 │
│ projected │ Acme · 2026-07 │ $61,980.10 │
│ historical │ Acme · 2026-06 │ $45,102.00 │
└────────────┴────────────────┴────────────┘
🎯 FinOps findings
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Sev ┃ Category ┃ Finding ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ HIGH │ custom-metrics │ 2 high-cardinality custom metric(s) │
│ HIGH │ logs │ 1 log index(es) with no daily quota │
│ HIGH │ attribution │ 1 of 2 hosts missing attribution tags│
└─────────┴────────────────┴─────────────────────────────────────┘
Python API
from datadog_radar import DatadogClient
from datadog_radar.scanners import run_scan
from datadog_radar.findings import build_findings
client = DatadogClient() # reads DD_API_KEY / DD_APP_KEY / DD_SITE
results = run_scan(client, domains=["cost", "metrics"])
for f in build_findings(results):
print(f["severity"], f["title"])
Design notes
Graceful degradation. Every API call is wrapped in _safe(). A permission gap, a deprecated endpoint, or a child-org 403 degrades one row — the rest of the scan still completes and the gap is reported as an info finding.
Retry. 429 responses honour X-RateLimit-Reset; 5xx and network errors retry with linear backoff.
Read-only. Every call is a GET. Nothing is created, modified, or deleted.
Hyperscaler Radar Suite
| Package | Target |
|---|---|
aws-radar |
AWS |
gcp-radar |
Google Cloud |
azure-radar |
Microsoft Azure |
oci-radar |
Oracle Cloud |
coreweave-radar |
CoreWeave |
openai-radar |
OpenAI |
aws-bedrock-radar |
AWS Bedrock |
datadog-radar |
Datadog ← you are here |
Publish
pip install build twine
python -m build
twine check dist/*
twine upload dist/*
License
MIT © sarimor
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file datadog_radar-0.1.0.tar.gz.
File metadata
- Download URL: datadog_radar-0.1.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b299f56c08b492e0f55c8225b02d0d59e106fde851405b8b983924ce8e90932
|
|
| MD5 |
c651a086c2a6c731bb672f6b4127f5df
|
|
| BLAKE2b-256 |
272dad3ad2bd7060ccf2c270999126382a33dc0bd538ee3916b81e2c6d6de13e
|
File details
Details for the file datadog_radar-0.1.0-py3-none-any.whl.
File metadata
- Download URL: datadog_radar-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dea9988eb7bcf927ba0384ecfe39c144113f08c973e3c9970984c08b8b532a9d
|
|
| MD5 |
b642d1ec4b7407837286e651afcdec35
|
|
| BLAKE2b-256 |
80594022703dd63d58a2de7d8e7a80758b6a2be78e933384a78685bda9346755
|