Skip to content

feat(metrics): add v1 metrics search and fix v2 query request body#32

Merged
platinummonkey merged 2 commits into
DataDog:mainfrom
MichaelVessia:feat/v1-metrics-search
Feb 11, 2026
Merged

feat(metrics): add v1 metrics search and fix v2 query request body#32
platinummonkey merged 2 commits into
DataDog:mainfrom
MichaelVessia:feat/v1-metrics-search

Conversation

@MichaelVessia
Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes the v2 metrics query request body (which was causing 400 Bad Request for
all queries) and adds a new metrics search subcommand backed by the v1
QueryMetrics API, following the same convention as logs search (v1) /
logs query (v2).

After this PR:

# v1 API, classic query syntax:
pup metrics search --query="avg:system.cpu.user{*}" --from="1h"

# v2 API, now works correctly:
pup metrics query --query="avg:system.cpu.user{*}" --from="1h"

Motivation

pup metrics query returns 400 Bad Request for every query. The v2
TimeseriesFormulaQueryRequest body was missing two required fields:

  1. Name on the query: each MetricsTimeseriesQuery must have a name
    (e.g. "a") so formulas can reference it.
  2. Formulas array: the request must include at least one formula
    referencing the named query (e.g. {Formula: "a"}).

Repro:

pup auth login
pup auth status  # confirm: authenticated, token valid

pup metrics query --query="avg:system.cpu.user{*}" --from="1h"
# => Error: failed to query metrics: 400 Bad Request (status: 400)

The existing code (cmd/metrics.go) was:

metricsQuery := datadogV2.NewMetricsTimeseriesQuery(datadogV2.METRICSDATASOURCE_METRICS, queryString)
timeseriesQuery := datadogV2.MetricsTimeseriesQueryAsTimeseriesQuery(metricsQuery)

This sets DataSource and Query but leaves Name nil and never populates
Formulas. The fix matches the official SDK example at
examples/v2/metrics/QueryTimeseriesData.go.

Additional Changes

Test improvements (cmd/metrics_test.go): Removed duplicate test case,
added wantErrContains assertions to verify error message content, replaced
brittle string-literal checks in TestMetricsSearchCmd with behavioral
assertions (subcommand registration, flag existence), added
TestMetricsCmd_Subcommands.

Additional Notes

Tested manually against a live Datadog account after building from this branch:

v1 search (new command):

$ pup metrics search --query="avg:system.cpu.user{*}" --from="1h"
{
  "from_date": 1770777733000,
  "query": "avg:system.cpu.user{*}",
  "res_type": "time_series",
  "resp_version": 1,
  "series": [
    {
      "aggr": "avg",
      "display_name": "system.cpu.user",
      "expression": "avg:system.cpu.user{*}",
      "interval": 20,
      "length": 180,
      "metric": "system.cpu.user",
      "pointlist": [[1770777740000, 12.03], [1770777760000, 10.95], ...]
    }
  ]
}

v2 query (fixed, previously 400'd):

$ pup metrics query --query="avg:system.cpu.user{*}" --from="1h"
{
  "data": {
    "attributes": {
      "series": [{"group_tags": [], "query_index": 0}],
      "times": [1770777740000, 1770777760000, ...],
      "values": [[12.03, 10.95, ...]]
    }
  }
}

Help output confirms both subcommands with API version labels:

$ pup metrics --help
Available Commands:
  query       Query time-series metrics data (v2 API)
  search      Search metrics (v1 API)

Unit tests: 13 test functions, 28 sub-tests, 0 failures.

Checklist

  • The code change follows the project conventions (see CONTRIBUTING.md)
  • Tests have been added/updated (if applicable)
  • Documentation has been updated (if applicable)
  • All CI checks pass
  • Code coverage is maintained or improved

Related Issues

MichaelVessia and others added 2 commits February 10, 2026 22:50
The v2 QueryTimeseriesData request was missing the required Formulas
array and Name field, causing 400 Bad Request for all queries. Fix the
request body to match the official SDK example and add a v1 metrics
search subcommand using QueryMetrics (same convention as logs search/query).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove duplicate test case in TestRunMetricsSearch
- Add wantErrContains assertions to verify error message content
- Replace brittle string-literal checks in TestMetricsSearchCmd with
  behavioral assertions (subcommand registration, flag existence)
- Add TestMetricsCmd_Subcommands verifying all 6 subcommands registered

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@MichaelVessia MichaelVessia requested a review from a team as a code owner February 11, 2026 04:21
@MichaelVessia
Copy link
Copy Markdown
Contributor Author

Hey 👋 , got a little carried away - not sure if v1 support is wanted but I saw it was there for some other APIs so I followed suit. Can adjust to decrease the scope if you want.

@platinummonkey platinummonkey merged commit 54c7d7d into DataDog:main Feb 11, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants