Documentation
¶
Overview ¶
Package promapi is the shared Prometheus HTTP-API client core (v0.9.1150) — envelope decoding + a bounded GET, with nothing in it that knows about clusters, metrics pages, or Coremetry's read model.
Why a package and not a helper in internal/vmetrics: the SAME wire contract now has two consumers with different jobs — internal/thanos (multi-cluster pod/host metrics for /clusters) and internal/vmetrics (the metric read backend, Faz 1). The decoding rules that matter are the non-obvious ones, and each was a bug somewhere first:
- status != "success" carries errorType/error INSTEAD of data, so a 200 with a broken query is an ERROR, not an empty result. Treating it as empty is the "no data" lie.
- sample values arrive as JSON STRINGS ("1.5", "NaN", "+Inf"), never numbers. A struct with float64 silently fails to unmarshal.
- non-finite values are legal Prometheus output (staleness markers, 0/0 in a recording rule). They must be DROPPED, not coerced to 0 — v0.9.1149 taught us a %f-formatted +Inf travels all the way into a prompt.
DELIBERATELY NOT a refactor of internal/thanos. thanos' doQuery stays exactly where it is: it is load-bearing on a surface with no test harness for a live Querier, and the spec for this release scoped the blast radius to the new reader. This package is the copy-the-pattern half of "copy the pattern, share the core" — new callers use it, the old one is left alone until something else forces it to move.
Index ¶
- Constants
- func BuildURL(baseURL, path string, params url.Values) string
- func DecodeStrings(label string, body []byte) ([]string, error)
- func Do(ctx context.Context, req Request) ([]byte, error)
- func FirstN(s string, n int) string
- func QueryStrings(ctx context.Context, req Request) ([]string, error)
- func Sample(raw []json.RawMessage) (tsSec float64, val float64, ok bool)
- type Request
- type Series
Constants ¶
const MaxBodyBytes = 8 << 20
MaxBodyBytes — 8MB read ceiling. A bounded vector is a few hundred KB; anything past this means the shield upstream failed and we would rather fail than allocate.
const MaxSeriesParsed = 1000
MaxSeriesParsed is the defensive backstop behind whatever cardinality shield the query itself carries (topk / a bounded selector): even a misbehaving backend can't hand us more rows than this. Mirrors thanos.maxSeriesParsed.
Variables ¶
This section is empty.
Functions ¶
func BuildURL ¶
BuildURL joins base + path + encoded params. Pure — the trailing-slash case is table-tested; "https://vm/" + "/api/v1/labels" must not produce a double slash, because some reverse proxies 404 on it.
func DecodeStrings ¶
DecodeStrings parses a labels / label-values body — data is a plain string array. `"data": null` decodes to an empty slice, not an error: a metric with no labels is a legitimate answer.
func Do ¶
Do performs the GET and returns the raw body. HTTP >= 300 is an error carrying the first 200 bytes of the body — a 401 from VM says which auth it wanted, and hiding that costs an operator an hour.
func FirstN ¶
FirstN truncates for error messages. Rune-safe: slicing bytes mid-rune puts U+FFFD in an operator-visible string (the v0.9.842 truncate trap).
func QueryStrings ¶
QueryStrings = Do + DecodeStrings.
func Sample ¶
func Sample(raw []json.RawMessage) (tsSec float64, val float64, ok bool)
Sample decodes one [timestamp, "value"] pair.
ok=false means the pair is UNUSABLE and the caller must skip the point: malformed JSON, wrong arity, or a non-finite value. Prometheus emits NaN / +Inf / -Inf as ordinary strings and they are not exceptional — a counter divided by a zero interval, a staleness marker. Coercing them to 0 draws a line to the floor that the operator reads as a real measurement, and a formatted ±Inf leaks into every downstream string (v0.9.1149). Dropping leaves a gap, which is what a gap is.
Types ¶
type Request ¶
type Request struct {
Label string
BaseURL string
Path string
Params url.Values
AuthType string // "" / "none" / "bearer"
Token string
SkipTLS bool
}
Request is one Prometheus-API GET. Label names the backend in every error message ("victoriametrics") — an error that reads "connection refused" without saying WHOSE connection sends the operator hunting.
type Series ¶
type Series struct {
Metric map[string]string `json:"metric"`
Value []json.RawMessage `json:"value"`
Values [][]json.RawMessage `json:"values"`
}
Series is one result row of /api/v1/query (Value filled, instant vector) or /api/v1/query_range (Values filled, range matrix). json.RawMessage because element 0 is a number and element 1 is a string — see Sample.
func DecodeSeries ¶
DecodeSeries parses a query / query_range body into series. Pure — table-tested in promapi_test.go.