Add query_samples_total metric

query_samples_total is a counter that tracks the total number of samples loaded by all queries.

The goal with this metric is to be able to see the amount of 'work' done by Prometheus to service queries.
At the moment we have metrics with the number of queries, plus more detailed metrics showing how much time each step of a query takes.
While those metrics do help they don't show us the whole picture.
Queries that do load more samples are (in general) more expensive than queries that do load fewer samples.
This means that looking only at the number of queries doesn't tell us how much 'work' Prometheus received.
Adding a counter that tracks the total number of samples loaded allows us to see if there was a spike in the cost of queries, not just the number of them.

Signed-off-by: Łukasz Mierzwa <l.mierzwa@gmail.com>
This commit is contained in:
Łukasz Mierzwa 2023-04-12 14:05:06 +01:00
parent 6e0a46900b
commit b6573353c1

View file

@ -70,6 +70,7 @@ type engineMetrics struct {
queryPrepareTime prometheus.Observer
queryInnerEval prometheus.Observer
queryResultSort prometheus.Observer
querySamples prometheus.Counter
}
// convertibleToInt64 returns true if v does not over-/underflow an int64.
@ -332,6 +333,12 @@ func NewEngine(opts EngineOpts) *Engine {
Name: "queries_concurrent_max",
Help: "The max number of concurrent queries.",
}),
querySamples: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "query_samples_total",
Help: "The total number of samples loaded by all queries.",
}),
queryQueueTime: queryResultSummary.WithLabelValues("queue_time"),
queryPrepareTime: queryResultSummary.WithLabelValues("prepare_time"),
queryInnerEval: queryResultSummary.WithLabelValues("inner_eval"),
@ -357,6 +364,7 @@ func NewEngine(opts EngineOpts) *Engine {
metrics.maxConcurrentQueries,
metrics.queryLogEnabled,
metrics.queryLogFailures,
metrics.querySamples,
queryResultSummary,
)
}
@ -537,7 +545,10 @@ func (ng *Engine) newTestQuery(f func(context.Context) error) Query {
// statements are not handled by the Engine.
func (ng *Engine) exec(ctx context.Context, q *query) (v parser.Value, ws storage.Warnings, err error) {
ng.metrics.currentQueries.Inc()
defer ng.metrics.currentQueries.Dec()
defer func() {
ng.metrics.currentQueries.Dec()
ng.metrics.querySamples.Add(float64(q.sampleStats.TotalSamples))
}()
ctx, cancel := context.WithTimeout(ctx, ng.timeout)
q.cancel = cancel