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
Metadata
Release files for datadog-radar 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datadog_radar-0.1.2.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| datadog_radar-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.6 kB
Release files / datadog_radar-0.1.2.tar.gz
| Download URL | datadog_radar-0.1.2.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d13a98e2c6a6478348f07f240ac2e88c7b896658805f4f6977c8b1360696b83c
|
|
BLAKE2b-256 checksum How to use checksums |
0388fa44c4ef945572a05e44040ab2dfb480171bd0c8acfe4de7b3b21c4d03f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / datadog_radar-0.1.2-py3-none-any.whl
| Download URL | datadog_radar-0.1.2-py3-none-any.whl |
|---|---|
| Size | 19.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d6a8e0ae5db06e34bc357814847dd144e09a71fea997a3cd060c1fd6a88825dc
|
|
BLAKE2b-256 checksum How to use checksums |
f60e1fd31e603ab6597b7fdac7e58ed69e9c41256dad96cd8be1e190b36223ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|