Documentation
¶
Overview ¶
Package promquery asks a Prometheus-compatible store what it recorded about an Atlas node (ADR-0189 P5b).
It is the read side of what [metrics] writes, and it is a separate package for that reason: `metrics` owns Atlas's registry and the /metrics handler, and putting a client for somebody else's server in it would make the exposition depend on a query language it does not speak.
What this can and cannot ask ¶
Atlas's metrics carry no per-element labels, and ADR-0142 says why: a label whose values the data can invent — a process id, an instance key — turns one metric into unboundedly many series. That rule is the reason this package answers about a *node* and never about one process, and it is a property of the contract rather than a gap to close later.
A node is identified the only way a metrics store knows one: by the scrape target it came from. Atlas can derive that from a deployment target's base URL, and for the server itself it cannot derive it at all — how this process appears in somebody's Prometheus is their scrape configuration, not Atlas's. So it is configured, and left unset it makes the local node honestly unidentifiable rather than silently matching the wrong series.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrQueryRefused = fmt.Errorf("promquery: query refused")
ErrQueryRefused is returned when the store answered and declined — credentials, or a permission on its side. Callers separate it from a transport failure because the two send an operator to different places.
Functions ¶
func EscapeLabelValue ¶
EscapeLabelValue quotes a value for a PromQL label matcher. Every value this package matches on is operator configuration rather than user input, but a base URL with a quote in it would still produce a query that means something other than intended, and a malformed one is the better failure.
Types ¶
type Config ¶
type Config struct {
URL string
Username string
Password string
// Instance is how *this* node appears in the store's `instance` label. Atlas
// cannot derive it: a scrape target is the operator's configuration, and
// guessing it would answer a question about somebody else's process while
// looking exactly like an answer about this one. Left empty, a binding to this
// server's own runtime is reported unidentifiable and says so.
Instance string
}
Config is the server-side configuration of the metrics reader. URL is the Prometheus-compatible base URL (e.g. "https://prometheus:9090"); an empty URL disables it. Username/Password are optional HTTP basic-auth credentials.
type HTTPClient ¶
type HTTPClient struct {
// contains filtered or unexported fields
}
HTTPClient implements Querier against a real store.
func NewHTTPClient ¶
func NewHTTPClient(cfg Config) *HTTPClient
NewHTTPClient builds a client for a configured store.
func (*HTTPClient) QueryRange ¶
func (c *HTTPClient) QueryRange(ctx context.Context, expr string, from, to, step int64) ([]Sample, error)
QueryRange posts one range query to /api/v1/query_range.
The caller's expression is expected to reduce to a single series — every expression this serves wraps its metric in an aggregation — so only the first result is read. A store that returned several would mean the aggregation was dropped, and quietly summing them here would hide that.
type Querier ¶
type Querier interface {
// QueryRange evaluates expr at each step between from and to, in Unix seconds, and
// returns the samples of the single series it reduces to. A query that matches
// nothing returns no samples and no error — that is an answer, not a failure.
QueryRange(ctx context.Context, expr string, from, to, step int64) ([]Sample, error)
}
Querier runs one range query. It is an interface so a caller is testable without a live store.