Fix incorrect interpolation when counter resets occur in smoothed range
selector evaluation. Previously, the asymmetric handling of counter
resets (y1=0 on left edge, y2+=y1 on right edge) produced wrong values.
Now uniformly set y1=0 when a counter reset is detected, correctly
modeling the counter as starting from 0 post-reset.
This fixes rate calculations across counter resets. For example,
rate(metric[10s] smoothed) where metric goes from 100 to 10 (a reset)
now correctly computes 0.666... by treating the counter as resetting
to 0 rather than producing inflated values from the old behavior.
Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
Add bounds check to prevent index out of range panic when
trimStringByBytes receives a string containing only UTF-8 continuation
bytes (0x80-0xBF). Previously, the loop would decrement size below 0
when no valid rune start byte was found, causing a panic.
A malicious query string with only continuation bytes could crash
the Prometheus server via the ActiveQueryTracker before the query
was parsed or validated.
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
testutil.T was needed before https://go.dev/doc/go1.13#testingpkgtesting
Now it's inconsistent and confusing, so let's kill it.
Signed-off-by: bwplotka <bwplotka@gmail.com>
No implementation yet. Just to test the shape of the interface.
AtST is implemented for trivial cases, anything else is hard coded
to return 0.
Ref: https://github.com/prometheus/prometheus/issues/17791
Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
When filtering by a label that exists on both the input metric and
target_info (e.g., info(metric, {host_name="orbstack"}) where host_name
exists on both), the function incorrectly returned empty results.
The bug was in combineWithInfoVector: when no new labels were added
(because they all overlapped with base metric labels), the code entered
the "no match" filtering block even though an info series WAS matched.
The fix checks len(seenInfoMetrics) == 0 to correctly identify when no
info series matched. If an info series matched (seenInfoMetrics is
non-empty), the series is kept even if no new labels were added.
Fixes#17813
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
Moved some Metric.Get() calls in PromQL functions to avoid unnecessary label extraction.
In many cases, this work was done to extract metric name, and was only used if annotations were emitted.
In the same go I also replaced labels.MetricName with model.MetricNameLabel, since the former was deprecated.
Signed-off-by: Vilius Pranckaitis <vpranckaitis@gmail.com>
This commit addresses the PR feedback for issue #17615. The previous
implementation could not distinguish between:
- No counter reset hint specified (meaning "don't care")
- counter_reset_hint:unknown explicitly specified (meaning "verify it's unknown")
Changes:
- Added CounterResetHintSet field to parser.SequenceValue to track
whether counter_reset_hint was explicitly specified in the test file
- Modified buildHistogramFromMap to set this flag when the hint is
present in the descriptor map
- Updated newHistogramSequenceValue helper and histogramsSeries
functions to propagate the flag through histogram series creation
- Updated yacc grammar to use the new helper function
- Modified compareNativeHistogram to accept the flag and only compare
hints when explicitly specified
This allows tests to:
1. Not specify a hint (no comparison, backward compatible)
2. Explicitly specify counter_reset_hint:unknown (verify it's unknown)
3. Explicitly specify counter_reset_hint:gauge/reset/not_reset (verify match)
Fixes#17615
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
Add fast path that returns early when no duplicate labelsets exist,
avoiding allocations in the common case. For the merge case, simplify
collision detection by checking for duplicate timestamps after sorting
instead of building a timestamp map, reducing memory overhead.
Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
Generally, binary operations between two vectors fail if there is a many-to-one
or one-to-many matching situation between series within a match group and no
`group_left()` or `group_right()` modifier is present. For filter ops this is
also generally the case, but there can be situations where multiple series on
one side can match a single series on the other side, but only 0 or 1 of those
multiple series remains after the filter operator has been applied. In this
case, the PromQL engine does not produce a matching error, since it only tracks
series matching for those series that survive the filtering. IMO this is
incorrect behavior (which can also erratically make a query sometimes fail and
sometimes succeed, depending on current sample values), and we should always
produce an error if there is a match error prior to applying the filter op.
This PR ensures that we do the cardinality / match tracking independently of
the result of the filter operation.
Signed-off-by: Julius Volz <julius.volz@gmail.com>
Currently both the backend and frontend printers/formatters/serializers
incorrectly transform the following expression:
```
up * ignoring() group_left(__name__) node_boot_time_seconds
```
...into:
```
up * node_boot_time_seconds
```
...which yields a different result (including the metric name in the result
vs. no metric name).
We need to keep empty `ignoring()` modifiers if there is a grouping modifier
present.
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit adds support for configuring a custom start timestamp
for Prometheus unit tests, allowing tests to use realistic timestamps
instead of starting at Unix epoch 0.
Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
The test at line 1283 for avg_over_time(nhcb_metric[13m]) incorrectly
expected counter_reset_hint:gauge in the result. However, the actual
avg_over_time implementation does not explicitly set the CounterResetHint
to GaugeType on its output histogram.
With the new counter reset hint comparison logic added to the promqltest
framework (which compares hints when explicitly specified in expected
results), this incorrect expectation was now being caught.
This fix removes the incorrect counter_reset_hint:gauge from the expected
result, allowing the test to correctly verify the avg_over_time behavior
without asserting a specific hint value that the function does not set.
The counter reset hint comparison logic works as designed: if the expected
histogram has UnknownCounterReset (the default when not specified), no
comparison is performed. Only when a hint is explicitly specified in the
test expectation will it be compared against the actual result.
Fixes the test failure introduced by the counter reset hint comparison
feature in promqltest.
Signed-off-by: Aviral Garg <aviralg2106@gmail.com>
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
This commit implements counter reset hint comparison in the promqltest
framework to address issue #17615. Previously, while test definitions
could specify a counter_reset_hint in expected native histogram results,
the framework did not actually compare this hint between expected and
actual results.
The implementation adds optional comparison logic to the
compareNativeHistogram function:
- If the expected histogram has UnknownCounterReset (the default),
the hint is not compared (meaning "don't care")
- If the expected histogram explicitly specifies CounterReset,
NotCounterReset, or GaugeType, it is verified against the actual
histogram's hint
This allows tests to verify that PromQL functions correctly set or
preserve counter reset hints while maintaining backward compatibility
with existing tests that don't specify explicit hints.
Fixes#17615
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
This adds the following native histograms (with a few classic buckets for backwards compatibility), while keeping the corresponding summaries (same name, just without `_histogram`):
- `prometheus_sd_refresh_duration_histogram_seconds`
- `prometheus_rule_evaluation_duration_histogram_seconds`
- `prometheus_rule_group_duration_histogram_seconds`
- `prometheus_target_sync_length_histogram_seconds`
- `prometheus_target_interval_length_histogram_seconds`
- `prometheus_engine_query_duration_histogram_seconds`
Signed-off-by: Harsh <harshmastic@gmail.com>
Signed-off-by: harsh kumar <135993950+hxrshxz@users.noreply.github.com>
Co-authored-by: Björn Rabenstein <github@rabenste.in>
Methods added:
- `SampleOffset(metric *labels.Labels) float64` to calculate the sample offset for a given label set.
- `AddRatioSampleWithOffset(ratioLimit, sampleOffset float64) bool` to find out whether a given sample offset falls within a given ratio limit.
The already existing method `AddRatioSample(ratioLimit float64, sample *Sample) bool` is now implemented as a simple combination of the two other methods. Exposing these methods helps downstream projects to re-use the implementations including easier testing.
Signed-off-by: Andrew Hall <andrew.hall@grafana.com>