Merge branch 'release-3.0' into merge-release-into-main

pull/15415/head
Bryan Boreham 6 days ago
commit 26886d6d95

@ -2,29 +2,40 @@
## unreleased ## unreleased
## 3.0.0 / 2024-11-14
This release includes new features such as a brand new UI and UTF-8 support enabled by default. As this marks the first new major version in seven years, several breaking changes are introduced. The breaking changes are mainly around the removal of deprecated feature flags and CLI arguments, and the full list can be found below. For users that want to upgrade we recommend to read through our [migration guide](https://prometheus.io/docs/prometheus/3.0/migration/).
* [CHANGE] Set the `GOMAXPROCS` variable automatically to match the Linux CPU quota. Use `--no-auto-gomaxprocs` to disable it. The `auto-gomaxprocs` feature flag was removed. #15376
* [CHANGE] Set the `GOMEMLIMIT` variable automatically to match the Linux container memory limit. Use `--no-auto-gomemlimit` to disable it. The `auto-gomemlimit` feature flag was removed. #15373
* [CHANGE] Scraping: Remove implicit fallback to the Prometheus text format in case of invalid/missing Content-Type and fail the scrape instead. Add ability to specify a `fallback_scrape_protocol` in the scrape config. #15136 * [CHANGE] Scraping: Remove implicit fallback to the Prometheus text format in case of invalid/missing Content-Type and fail the scrape instead. Add ability to specify a `fallback_scrape_protocol` in the scrape config. #15136
* [CHANGE] Remote-write: default enable_http2 to false. #15219 * [CHANGE] Remote-write: default enable_http2 to false. #15219
* [CHANGE] Scraping: normalize "le" and "quantile" label values upon ingestion. #15164 * [CHANGE] Scraping: normalize "le" and "quantile" label values upon ingestion. #15164
* [CHANGE] Scraping: config `scrape_classic_histograms` was renamed to `always_scrape_classic_histograms`. #15178 * [CHANGE] Scraping: config `scrape_classic_histograms` was renamed to `always_scrape_classic_histograms`. #15178
* [CHANGE] Config: remove expand-external-labels flag, expand external labels env vars by default. #14657 * [CHANGE] Config: remove expand-external-labels flag, expand external labels env vars by default. #14657
* [CHANGE] Disallow configuring AM with the v1 api. #13883 * [CHANGE] Disallow configuring AM with the v1 api. #13883
* [ENHANCEMENT] Scraping, rules: handle targets reappearing, or rules moving group, when out-of-order is enabled. #14710
* [ENHANCEMENT] Tools: add debug printouts to promtool rules unit testing #15196
* [ENHANCEMENT] Scraping: support Created-Timestamp feature on native histograms. #14694
* [BUGFIX] PromQL: Fix stddev+stdvar aggregations to always ignore native histograms. #14941
* [BUGFIX] PromQL: Fix stddev+stdvar aggregations to treat Infinity consistently. #14941
* [BUGFIX] OTLP receiver: Preserve colons when generating metric names in suffix adding mode (this mode is always enabled, unless one uses Prometheus as a library). #15251
* [BUGFIX] Clamp functions: Ignore any points with native histograms. #15169
## 3.0.0-beta.1 / 2024-10-09
* [CHANGE] regexp `.` now matches all characters (performance improvement). #14505 * [CHANGE] regexp `.` now matches all characters (performance improvement). #14505
* [CHANGE] `holt_winters` is now called `double_exponential_smoothing` and moves behind the [experimental-promql-functions feature flag](https://prometheus.io/docs/prometheus/latest/feature_flags/#experimental-promql-functions). #14930 * [CHANGE] `holt_winters` is now called `double_exponential_smoothing` and moves behind the [experimental-promql-functions feature flag](https://prometheus.io/docs/prometheus/latest/feature_flags/#experimental-promql-functions). #14930
* [CHANGE] API: The OTLP receiver endpoint can now be enabled using `--web.enable-otlp-receiver` instead of `--enable-feature=otlp-write-receiver`. #14894 * [CHANGE] API: The OTLP receiver endpoint can now be enabled using `--web.enable-otlp-receiver` instead of `--enable-feature=otlp-write-receiver`. #14894
* [CHANGE] Prometheus will not add or remove port numbers from the target address. `no-default-scrape-port` feature flag removed. #14160 * [CHANGE] Prometheus will not add or remove port numbers from the target address. `no-default-scrape-port` feature flag removed. #14160
* [CHANGE] Logging: the format of log lines has changed a little, along with the adoption of Go's Structured Logging package. #14906 * [CHANGE] Logging: the format of log lines has changed a little, along with the adoption of Go's Structured Logging package. #14906
* [CHANGE] Don't create extra `_created` timeseries if feature-flag `created-timestamp-zero-ingestion' is enabled. #14738 * [CHANGE] Don't create extra `_created` timeseries if feature-flag `created-timestamp-zero-ingestion` is enabled. #14738
* [CHANGE] Float literals and time durations being the same is now a stable fetaure. #15111 * [CHANGE] Float literals and time durations being the same is now a stable fetaure. #15111
* [CHANGE] UI: The old web UI has been replaced by a completely new one that is less cluttered and adds a few new features (PromLens-style tree view, better metrics explorer, "Explain" tab). However, it is still missing some features of the old UI (notably, exemplar display and heatmaps). To switch back to the old UI, you can use the feature flag `--enable-feature=old-ui` for the time being. #14872
* [CHANGE] PromQL: Range selectors and the lookback delta are now left-open, i.e. a sample coinciding with the lower time limit is excluded rather than included. #13904
* [CHANGE] Kubernetes SD: Remove support for `discovery.k8s.io/v1beta1` API version of EndpointSlice. This version is no longer served as of Kubernetes v1.25. #14365
* [CHANGE] Kubernetes SD: Remove support for `networking.k8s.io/v1beta1` API version of Ingress. This version is no longer served as of Kubernetes v1.22. #14365
* [CHANGE] UTF-8: Enable UTF-8 support by default. Prometheus now allows all UTF-8 characters in metric and label names. The corresponding `utf8-name` feature flag has been removed. #14705
* [CHANGE] Console: Remove example files for the console feature. Users can continue using the console feature by supplying their own JavaScript and templates. #14807
* [CHANGE] SD: Enable the new service discovery manager by default. This SD manager does not restart unchanged discoveries upon reloading. This makes reloads faster and reduces pressure on service discoveries' sources. The corresponding `new-service-discovery-manager` feature flag has been removed. #14770
* [CHANGE] Agent mode has been promoted to stable. The feature flag `agent` has been removed. To run Prometheus in Agent mode, use the new `--agent` cmdline arg instead. #14747
* [CHANGE] Remove deprecated `remote-write-receiver`,`promql-at-modifier`, and `promql-negative-offset` feature flags. #13456, #14526
* [CHANGE] Remove deprecated `storage.tsdb.allow-overlapping-blocks`, `alertmanager.timeout`, and `storage.tsdb.retention` flags. #14640, #14643
* [FEATURE] OTLP receiver: Ability to skip UTF-8 normalization using `otlp.translation_strategy = NoUTF8EscapingWithSuffixes` configuration option. #15384
* [FEATURE] Support config reload automatically - feature flag `auto-reload-config`. #14769
* [ENHANCEMENT] Scraping, rules: handle targets reappearing, or rules moving group, when out-of-order is enabled. #14710
* [ENHANCEMENT] Tools: add debug printouts to promtool rules unit testing #15196
* [ENHANCEMENT] Scraping: support Created-Timestamp feature on native histograms. #14694
* [ENHANCEMENT] UI: Many fixes and improvements. #14898, #14899, #14907, #14908, #14912, #14913, #14914, #14931, #14940, #14945, #14946, #14972, #14981, #14982, #14994, #15096 * [ENHANCEMENT] UI: Many fixes and improvements. #14898, #14899, #14907, #14908, #14912, #14913, #14914, #14931, #14940, #14945, #14946, #14972, #14981, #14982, #14994, #15096
* [ENHANCEMENT] UI: Web UI now displays notifications, e.g. when starting up and shutting down. #15082 * [ENHANCEMENT] UI: Web UI now displays notifications, e.g. when starting up and shutting down. #15082
* [ENHANCEMENT] PromQL: Introduce exponential interpolation for native histograms. #14677 * [ENHANCEMENT] PromQL: Introduce exponential interpolation for native histograms. #14677
@ -32,10 +43,16 @@
* [ENHANCEMENT] Alerts: remove metrics for removed Alertmanagers. #13909 * [ENHANCEMENT] Alerts: remove metrics for removed Alertmanagers. #13909
* [ENHANCEMENT] Kubernetes SD: Support sidecar containers in endpoint discovery. #14929 * [ENHANCEMENT] Kubernetes SD: Support sidecar containers in endpoint discovery. #14929
* [ENHANCEMENT] Consul SD: Support catalog filters. #11224 * [ENHANCEMENT] Consul SD: Support catalog filters. #11224
* [ENHANCEMENT] Move AM discovery page from "Monitoring status" to "Server status". #14875
* [PERF] TSDB: Parallelize deletion of postings after head compaction. #14975 * [PERF] TSDB: Parallelize deletion of postings after head compaction. #14975
* [PERF] TSDB: Chunk encoding: shorten some write sequences. #14932 * [PERF] TSDB: Chunk encoding: shorten some write sequences. #14932
* [PERF] TSDB: Grow postings by doubling. #14721 * [PERF] TSDB: Grow postings by doubling. #14721
* [PERF] Relabeling: Optimize adding a constant label pair. #12180 * [PERF] Relabeling: Optimize adding a constant label pair. #12180
* [BUGFIX] Scraping: Don't log errors on empty scrapes. #15357
* [BUGFIX] UI: fix selector / series formatting for empty metric names. #15341
* [BUGFIX] PromQL: Fix stddev+stdvar aggregations to always ignore native histograms. #14941
* [BUGFIX] PromQL: Fix stddev+stdvar aggregations to treat Infinity consistently. #14941
* [BUGFIX] OTLP receiver: Preserve colons when generating metric names in suffix adding mode (this mode is always enabled, unless one uses Prometheus as a library). #15251
* [BUGFIX] Scraping: Unit was missing when using protobuf format. #15095 * [BUGFIX] Scraping: Unit was missing when using protobuf format. #15095
* [BUGFIX] PromQL: Only return "possible non-counter" annotation when `rate` returns points. #14910 * [BUGFIX] PromQL: Only return "possible non-counter" annotation when `rate` returns points. #14910
* [BUGFIX] TSDB: Chunks could have one unnecessary zero byte at the end. #14854 * [BUGFIX] TSDB: Chunks could have one unnecessary zero byte at the end. #14854
@ -43,25 +60,6 @@
* [BUGFIX] PromQL: Unary negation of native histograms. #14821 * [BUGFIX] PromQL: Unary negation of native histograms. #14821
* [BUGFIX] PromQL: Handle stale marker in native histogram series (e.g. if series goes away and comes back). #15025 * [BUGFIX] PromQL: Handle stale marker in native histogram series (e.g. if series goes away and comes back). #15025
* [BUGFIX] Autoreload: Reload invalid yaml files. #14947 * [BUGFIX] Autoreload: Reload invalid yaml files. #14947
## 3.0.0-beta.0 / 2024-09-05
Release 3.0.0-beta.0 includes new features such as a brand new UI and UTF-8 support enabled by default. As a new major version, several breaking changes are introduced. The breaking changes are mainly around the removal of deprecated feature flags and CLI arguments, and the full list can be found below. Most users should be able to try this release out of the box without any configuration changes.
As is traditional with a beta release, we do **not** recommend users install 3.0.0-beta on critical production systems, but we do want everyone to test it out and find bugs.
* [CHANGE] UI: The old web UI has been replaced by a completely new one that is less cluttered and adds a few new features (PromLens-style tree view, better metrics explorer, "Explain" tab). However, it is still missing some features of the old UI (notably, exemplar display and heatmaps). To switch back to the old UI, you can use the feature flag `--enable-feature=old-ui` for the time being. #14872
* [CHANGE] PromQL: Range selectors and the lookback delta are now left-open, i.e. a sample coinciding with the lower time limit is excluded rather than included. #13904
* [CHANGE] Kubernetes SD: Remove support for `discovery.k8s.io/v1beta1` API version of EndpointSlice. This version is no longer served as of Kubernetes v1.25. #14365
* [CHANGE] Kubernetes SD: Remove support for `networking.k8s.io/v1beta1` API version of Ingress. This version is no longer served as of Kubernetes v1.22. #14365
* [CHANGE] UTF-8: Enable UTF-8 support by default. Prometheus now allows all UTF-8 characters in metric and label names. The corresponding `utf8-name` feature flag has been removed. #14705
* [CHANGE] Console: Remove example files for the console feature. Users can continue using the console feature by supplying their own JavaScript and templates. #14807
* [CHANGE] SD: Enable the new service discovery manager by default. This SD manager does not restart unchanged discoveries upon reloading. This makes reloads faster and reduces pressure on service discoveries' sources. The corresponding `new-service-discovery-manager` feature flag has been removed. #14770
* [CHANGE] Agent mode has been promoted to stable. The feature flag `agent` has been removed. To run Prometheus in Agent mode, use the new `--agent` cmdline arg instead. #14747
* [CHANGE] Remove deprecated `remote-write-receiver`,`promql-at-modifier`, and `promql-negative-offset` feature flags. #13456, #14526
* [CHANGE] Remove deprecated `storage.tsdb.allow-overlapping-blocks`, `alertmanager.timeout`, and `storage.tsdb.retention` flags. #14640, #14643
* [ENHANCEMENT] Move AM discovery page from "Monitoring status" to "Server status". #14875
* [FEATURE] Support config reload automatically - feature flag `auto-reload-config`. #14769
* [BUGFIX] Scrape: Do not override target parameter labels with config params. #11029 * [BUGFIX] Scrape: Do not override target parameter labels with config params. #11029
## 2.55.1 / 2024-01-04 ## 2.55.1 / 2024-01-04

@ -1 +1 @@
3.0.0-beta.1 3.0.0

@ -171,8 +171,17 @@ remote_write:
[ - <remote_write> ... ] [ - <remote_write> ... ]
# Settings related to the OTLP receiver feature. # Settings related to the OTLP receiver feature.
# See https://prometheus.io/docs/guides/opentelemetry/ for best practices.
otlp: otlp:
[ promote_resource_attributes: [<string>, ...] | default = [ ] ] [ promote_resource_attributes: [<string>, ...] | default = [ ] ]
# Configures translation of OTLP metrics when received through the OTLP metrics
# endpoint. Available values:
# - "UnderscoreEscapingWithSuffixes" refers to commonly agreed normalization used
# by OpenTelemetry in https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/translator/prometheus
# - "NoUTF8EscapingWithSuffixes" is a mode that relies on UTF-8 support in Prometheus.
# It preserves all special characters like dots, but it still add required suffixes
# for units and _total like in UnderscoreEscapingWithSuffixes.
[ translation_strategy: <string> | default = "UnderscoreEscapingWithSuffixes" ]
# Settings related to the remote read feature. # Settings related to the remote read feature.
remote_read: remote_read:

@ -18,19 +18,27 @@ This document offers guidance on migrating from Prometheus 2.x to Prometheus 3.0
- `remote-write-receiver` - `remote-write-receiver`
- `new-service-discovery-manager` - `new-service-discovery-manager`
- `expand-external-labels` - `expand-external-labels`
Environment variable references `${var}` or `$var` in external label values - Environment variable references `${var}` or `$var` in external label values
are replaced according to the values of the current environment variables. are replaced according to the values of the current environment variables.
References to undefined variables are replaced by the empty string. - References to undefined variables are replaced by the empty string.
The `$` character can be escaped by using `$$`. The `$` character can be escaped by using `$$`.
- `no-default-scrape-port` - `no-default-scrape-port`
Prometheus v3 will no longer add ports to scrape targets according to the - Prometheus v3 will no longer add ports to scrape targets according to the
specified scheme. Target will now appear in labels as configured. specified scheme. Target will now appear in labels as configured.
If you rely on scrape targets like - If you rely on scrape targets like
`https://example.com/metrics` or `http://exmaple.com/metrics` to be `https://example.com/metrics` or `http://exmaple.com/metrics` to be
represented as `https://example.com/metrics:443` and represented as `https://example.com/metrics:443` and
`http://example.com/metrics:80` respectively, add them to your target URLs `http://example.com/metrics:80` respectively, add them to your target URLs
- `agent` - `agent`
Instead use the dedicated `--agent` cli flag. - Instead use the dedicated `--agent` CLI flag.
- `auto-gomemlimit`
- Prometheus v3 will automatically set `GOMEMLIMIT` to match the Linux
container memory limit. If there is no container limit, or the process is
running outside of containers, the system memory total is used. To disable
this, `--no-auto-gomemlimit` is available.
- `auto-gomaxprocs`
- Prometheus v3 will automatically set `GOMAXPROCS` to match the Linux
container CPU quota. To disable this, `--no-auto-gomaxprocs` is available.
Prometheus v3 will log a warning if you continue to pass these to Prometheus v3 will log a warning if you continue to pass these to
`--enable-feature`. `--enable-feature`.
@ -54,38 +62,34 @@ This document offers guidance on migrating from Prometheus 2.x to Prometheus 3.0
- The `.` pattern in regular expressions in PromQL matches newline characters. - The `.` pattern in regular expressions in PromQL matches newline characters.
With this change a regular expressions like `.*` matches strings that include With this change a regular expressions like `.*` matches strings that include
`\n`. This applies to matchers in queries and relabel configs. For example the `\n`. This applies to matchers in queries and relabel configs.
following regular expressions now match the accompanying strings, wheras in - For example, the following regular expressions now match the accompanying
Prometheus v2 these combinations didn't match. strings, whereas in Prometheus v2 these combinations didn't match.
- `.*` additionally matches `foo\n` and `Foo\nBar`
| Regex | Additional matches | - `foo.?bar` additionally matches `foo\nbar`
| ----- | ------ | - `foo.+bar` additionally matches `foo\nbar`
| ".*" | "foo\n", "Foo\nBar" | - If you want Prometheus v3 to behave like v2, you will have to change your
| "foo.?bar" | "foo\nbar" | regular expressions by replacing all `.` patterns with `[^\n]`, e.g.
| "foo.+bar" | "foo\nbar" |
If you want Prometheus v3 to behave like v2 did, you will have to change your
regular expressions by replacing all `.` patterns with `[^\n]`, e.g.
`foo[^\n]*`. `foo[^\n]*`.
- Lookback and range selectors are left open and right closed (previously left - Lookback and range selectors are left open and right closed (previously left
closed and right closed). This change affects queries when the evaluation time closed and right closed). This change affects queries when the evaluation time
perfectly aligns with the sample timestamps. For example assume querying a perfectly aligns with the sample timestamps. For example assume querying a
timeseries with even spaced samples exactly 1 minute apart. Before Prometheus timeseries with evenly spaced samples exactly 1 minute apart. Before Prometheus
3.x, range query with `5m` will mostly return 5 samples. But if the query v3, a range query with `5m` would usually return 5 samples. But if the query
evaluation aligns perfectly with a scrape, it would return 6 samples. In evaluation aligns perfectly with a scrape, it would return 6 samples. In
Prometheus 3.x queries like this will always return 5 samples. Prometheus v3 queries like this will always return 5 samples.
This change has likely few effects for everyday use, except for some sub query This change has likely few effects for everyday use, except for some subquery
use cases. use cases.
Query front-ends that align queries usually align sub-queries to multiples of Query front-ends that align queries usually align subqueries to multiples of
the step size. These sub queries will likely be affected. the step size. These subqueries will likely be affected.
Tests are more likely to affected. To fix those either adjust the expected Tests are more likely to affected. To fix those either adjust the expected
number of samples or extend to range by less then one sample interval. number of samples or extend the range by less than one sample interval.
- The `holt_winters` function has been renamed to `double_exponential_smoothing` - The `holt_winters` function has been renamed to `double_exponential_smoothing`
and is now guarded by the `promql-experimental-functions` feature flag. and is now guarded by the `promql-experimental-functions` feature flag.
If you want to keep using holt_winters, you have to do both of these things: If you want to keep using `holt_winters`, you have to do both of these things:
- Rename holt_winters to double_exponential_smoothing in your queries. - Rename `holt_winters` to `double_exponential_smoothing` in your queries.
- Pass `--enable-feature=promql-experimental-functions` in your Prometheus - Pass `--enable-feature=promql-experimental-functions` in your Prometheus
cli invocation.. CLI invocation.
## Scrape protocols ## Scrape protocols
Prometheus v3 is more strict concerning the Content-Type header received when Prometheus v3 is more strict concerning the Content-Type header received when
@ -95,7 +99,7 @@ header was unparsable or unrecognised. This could lead to incorrect data being
parsed in the scrape. Prometheus v3 will now fail the scrape in such cases. parsed in the scrape. Prometheus v3 will now fail the scrape in such cases.
If a scrape target is not providing the correct Content-Type header the If a scrape target is not providing the correct Content-Type header the
fallback protocol can be specified using the fallback_scrape_protocol fallback protocol can be specified using the `fallback_scrape_protocol`
parameter. See [Prometheus scrape_config documentation.](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) parameter. See [Prometheus scrape_config documentation.](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)
This is a breaking change as scrapes that may have succeeded with Prometheus v2 This is a breaking change as scrapes that may have succeeded with Prometheus v2
@ -104,26 +108,32 @@ may now fail if this fallback protocol is not specified.
## Miscellaneous ## Miscellaneous
### TSDB format and downgrade ### TSDB format and downgrade
The TSDB format has been changed in Prometheus v2.55 in preparation for changes
to the index format. Consequently a Prometheus v3 tsdb can only be read by a
Prometheus v2.55 or newer.
Before upgrading to Prometheus v3 please upgrade to v2.55 first and confirm
Prometheus works as expected. Only then continue with the upgrade to v3.
### TSDB Storage contract The TSDB format has been changed slightly in Prometheus v2.55 in preparation for changes
to the index format. Consequently, a Prometheus v3 TSDB can only be read by a
Prometheus v2.55 or newer. Keep that in mind when upgrading to v3 -- you will be only
able to downgrade to v2.55, not lower, without loosing your TSDB persitent data.
As an extra safety measure, you could optionally consider upgrading to v2.55 first and
confirm Prometheus works as expected, before upgrading to v3.
### TSDB storage contract
TSDB compatible storage is now expected to return results matching the specified TSDB compatible storage is now expected to return results matching the specified
selectors. This might impact some third party implementations, most likely selectors. This might impact some third party implementations, most likely
implementing `remote_read`. implementing `remote_read`.
This contract is not explicitly enforced, but can cause undefined behavior. This contract is not explicitly enforced, but can cause undefined behavior.
### UTF-8 names ### UTF-8 names
Prometheus v3 supports UTF-8 in metric and label names. This means metric and Prometheus v3 supports UTF-8 in metric and label names. This means metric and
label names can change after upgrading according to what is exposed by label names can change after upgrading according to what is exposed by
endpoints. Furthermore, metric and label names that would have previously been endpoints. Furthermore, metric and label names that would have previously been
flagged as invalid no longer will be. flagged as invalid no longer will be.
Users wishing to preserve the original validation behavior can update their Users wishing to preserve the original validation behavior can update their
prometheus yaml configuration to specify the legacy validation scheme: Prometheus yaml configuration to specify the legacy validation scheme:
``` ```
global: global:
@ -143,6 +153,7 @@ scrape_configs:
### Log message format ### Log message format
Prometheus v3 has adopted `log/slog` over the previous `go-kit/log`. This Prometheus v3 has adopted `log/slog` over the previous `go-kit/log`. This
results in a change of log message format. An example of the old log format is: results in a change of log message format. An example of the old log format is:
``` ```
ts=2024-10-23T22:01:06.074Z caller=main.go:627 level=info msg="No time or size retention was set so using the default time retention" duration=15d ts=2024-10-23T22:01:06.074Z caller=main.go:627 level=info msg="No time or size retention was set so using the default time retention" duration=15d
ts=2024-10-23T22:01:06.074Z caller=main.go:671 level=info msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=91d80252c3e528728b0f88d254dd720f6be07cb8-modified)" ts=2024-10-23T22:01:06.074Z caller=main.go:671 level=info msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=91d80252c3e528728b0f88d254dd720f6be07cb8-modified)"
@ -151,6 +162,7 @@ ts=2024-10-23T22:01:06.074Z caller=main.go:677 level=info host_details="(Linux 5
``` ```
a similar sequence in the new log format looks like this: a similar sequence in the new log format looks like this:
``` ```
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:640 msg="No time or size retention was set so using the default time retention" duration=15d time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:640 msg="No time or size retention was set so using the default time retention" duration=15d
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:681 msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=7c7116fea8343795cae6da42960cacd0207a2af8)" time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:681 msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=7c7116fea8343795cae6da42960cacd0207a2af8)"
@ -159,7 +171,7 @@ time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.co
### `le` and `quantile` label values ### `le` and `quantile` label values
In Prometheus v3, the values of the `le` label of classic histograms and the In Prometheus v3, the values of the `le` label of classic histograms and the
`quantile` label of summaries are normalized upon ingestions. In Prometheus v2 `quantile` label of summaries are normalized upon ingestion. In Prometheus v2
the value of these labels depended on the scrape protocol (protobuf vs text the value of these labels depended on the scrape protocol (protobuf vs text
format) in some situations. This led to label values changing based on the format) in some situations. This led to label values changing based on the
scrape protocol. E.g. a metric exposed as `my_classic_hist{le="1"}` would be scrape protocol. E.g. a metric exposed as `my_classic_hist{le="1"}` would be
@ -195,6 +207,12 @@ This should **only** be applied to metrics that currently produce such labels.
regex: (\d+)\.0+;.*_bucket regex: (\d+)\.0+;.*_bucket
``` ```
### Disallow configuring Alertmanager with the v1 API
Prometheus 3 no longer supports Alertmanager's v1 API. Effectively Prometheus 3
requires [Alertmanager 0.16.0](https://github.com/prometheus/alertmanager/releases/tag/v0.16.0) or later. Users with older Alertmanager
versions or configurations that use `alerting: alertmanagers: [api_version: v1]`
need to upgrade Alertmanager and change their configuration to use `api_version: v2`.
# Prometheus 2.0 migration guide # Prometheus 2.0 migration guide
For the Prometheus 1.8 to 2.0 please refer to the [Prometheus v2.55 documentation](https://prometheus.io/docs/prometheus/2.55/migration/). For the Prometheus 1.8 to 2.0 please refer to the [Prometheus v2.55 documentation](https://prometheus.io/docs/prometheus/2.55/migration/).

@ -1552,7 +1552,34 @@ type appendErrors struct {
numExemplarOutOfOrder int numExemplarOutOfOrder int
} }
// Update the stale markers.
func (sl *scrapeLoop) updateStaleMarkers(app storage.Appender, defTime int64) (err error) {
sl.cache.forEachStale(func(lset labels.Labels) bool {
// Series no longer exposed, mark it stale.
app.SetOptions(&storage.AppendOptions{DiscardOutOfOrder: true})
_, err = app.Append(0, lset, defTime, math.Float64frombits(value.StaleNaN))
app.SetOptions(nil)
switch {
case errors.Is(err, storage.ErrOutOfOrderSample), errors.Is(err, storage.ErrDuplicateSampleForTimestamp):
// Do not count these in logging, as this is expected if a target
// goes away and comes back again with a new scrape loop.
err = nil
}
return err == nil
})
return
}
func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, ts time.Time) (total, added, seriesAdded int, err error) { func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, ts time.Time) (total, added, seriesAdded int, err error) {
defTime := timestamp.FromTime(ts)
if len(b) == 0 {
// Empty scrape. Just update the stale makers and swap the cache (but don't flush it).
err = sl.updateStaleMarkers(app, defTime)
sl.cache.iterDone(false)
return
}
p, err := textparse.New(b, contentType, sl.fallbackScrapeProtocol, sl.alwaysScrapeClassicHist, sl.enableCTZeroIngestion, sl.symbolTable) p, err := textparse.New(b, contentType, sl.fallbackScrapeProtocol, sl.alwaysScrapeClassicHist, sl.enableCTZeroIngestion, sl.symbolTable)
if p == nil { if p == nil {
sl.l.Error( sl.l.Error(
@ -1574,9 +1601,7 @@ func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string,
"err", err, "err", err,
) )
} }
var ( var (
defTime = timestamp.FromTime(ts)
appErrs = appendErrors{} appErrs = appendErrors{}
sampleLimitErr error sampleLimitErr error
bucketLimitErr error bucketLimitErr error
@ -1617,9 +1642,8 @@ func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string,
if err != nil { if err != nil {
return return
} }
// Only perform cache cleaning if the scrape was not empty. // Flush and swap the cache as the scrape was non-empty.
// An empty scrape (usually) is used to indicate a failed scrape. sl.cache.iterDone(true)
sl.cache.iterDone(len(b) > 0)
}() }()
loop: loop:
@ -1862,19 +1886,7 @@ loop:
sl.l.Warn("Error on ingesting out-of-order exemplars", "num_dropped", appErrs.numExemplarOutOfOrder) sl.l.Warn("Error on ingesting out-of-order exemplars", "num_dropped", appErrs.numExemplarOutOfOrder)
} }
if err == nil { if err == nil {
sl.cache.forEachStale(func(lset labels.Labels) bool { err = sl.updateStaleMarkers(app, defTime)
// Series no longer exposed, mark it stale.
app.SetOptions(&storage.AppendOptions{DiscardOutOfOrder: true})
_, err = app.Append(0, lset, defTime, math.Float64frombits(value.StaleNaN))
app.SetOptions(nil)
switch {
case errors.Is(err, storage.ErrOutOfOrderSample), errors.Is(err, storage.ErrDuplicateSampleForTimestamp):
// Do not count these in logging, as this is expected if a target
// goes away and comes back again with a new scrape loop.
err = nil
}
return err == nil
})
} }
return return
} }

@ -120,13 +120,13 @@ func runScrapeLoopTest(t *testing.T, s *teststorage.TestStorage, expectOutOfOrde
timestampInorder2 := now.Add(5 * time.Minute) timestampInorder2 := now.Add(5 * time.Minute)
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1`), "", timestampInorder1) _, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1`), "text/plain", timestampInorder1)
require.NoError(t, err) require.NoError(t, err)
_, _, _, err = sl.append(slApp, []byte(`metric_a{a="1",b="1"} 2`), "", timestampOutOfOrder) _, _, _, err = sl.append(slApp, []byte(`metric_a{a="1",b="1"} 2`), "text/plain", timestampOutOfOrder)
require.NoError(t, err) require.NoError(t, err)
_, _, _, err = sl.append(slApp, []byte(`metric_a{a="1",b="1"} 3`), "", timestampInorder2) _, _, _, err = sl.append(slApp, []byte(`metric_a{a="1",b="1"} 3`), "text/plain", timestampInorder2)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -756,6 +756,10 @@ func TestScrapePoolScrapeLoopsStarted(t *testing.T) {
} }
func newBasicScrapeLoop(t testing.TB, ctx context.Context, scraper scraper, app func(ctx context.Context) storage.Appender, interval time.Duration) *scrapeLoop { func newBasicScrapeLoop(t testing.TB, ctx context.Context, scraper scraper, app func(ctx context.Context) storage.Appender, interval time.Duration) *scrapeLoop {
return newBasicScrapeLoopWithFallback(t, ctx, scraper, app, interval, "")
}
func newBasicScrapeLoopWithFallback(t testing.TB, ctx context.Context, scraper scraper, app func(ctx context.Context) storage.Appender, interval time.Duration, fallback string) *scrapeLoop {
return newScrapeLoop(ctx, return newScrapeLoop(ctx,
scraper, scraper,
nil, nil, nil, nil,
@ -783,7 +787,7 @@ func newBasicScrapeLoop(t testing.TB, ctx context.Context, scraper scraper, app
newTestScrapeMetrics(t), newTestScrapeMetrics(t),
false, false,
model.LegacyValidation, model.LegacyValidation,
"text/plain", fallback,
) )
} }
@ -844,7 +848,8 @@ func TestScrapeLoopStop(t *testing.T) {
app = func(ctx context.Context) storage.Appender { return appender } app = func(ctx context.Context) storage.Appender { return appender }
) )
sl := newBasicScrapeLoop(t, context.Background(), scraper, app, 10*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, context.Background(), scraper, app, 10*time.Millisecond, "text/plain")
// Terminate loop after 2 scrapes. // Terminate loop after 2 scrapes.
numScrapes := 0 numScrapes := 0
@ -928,7 +933,7 @@ func TestScrapeLoopRun(t *testing.T) {
scrapeMetrics, scrapeMetrics,
false, false,
model.LegacyValidation, model.LegacyValidation,
"text/plain", "",
) )
// The loop must terminate during the initial offset if the context // The loop must terminate during the initial offset if the context
@ -1075,7 +1080,7 @@ func TestScrapeLoopMetadata(t *testing.T) {
scrapeMetrics, scrapeMetrics,
false, false,
model.LegacyValidation, model.LegacyValidation,
"text/plain", "",
) )
defer cancel() defer cancel()
@ -1126,7 +1131,7 @@ func TestScrapeLoopSeriesAdded(t *testing.T) {
ctx, sl := simpleTestScrapeLoop(t) ctx, sl := simpleTestScrapeLoop(t)
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\n"), "", time.Time{}) total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.Equal(t, 1, total) require.Equal(t, 1, total)
@ -1134,7 +1139,7 @@ func TestScrapeLoopSeriesAdded(t *testing.T) {
require.Equal(t, 1, seriesAdded) require.Equal(t, 1, seriesAdded)
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1\n"), "", time.Time{}) total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1\n"), "text/plain", time.Time{})
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, total) require.Equal(t, 1, total)
@ -1164,7 +1169,7 @@ func TestScrapeLoopFailWithInvalidLabelsAfterRelabel(t *testing.T) {
} }
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\n"), "", time.Time{}) total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\n"), "text/plain", time.Time{})
require.ErrorContains(t, err, "invalid metric name or label names") require.ErrorContains(t, err, "invalid metric name or label names")
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
require.Equal(t, 1, total) require.Equal(t, 1, total)
@ -1188,7 +1193,7 @@ func TestScrapeLoopFailLegacyUnderUTF8(t *testing.T) {
sl.validationScheme = model.LegacyValidation sl.validationScheme = model.LegacyValidation
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
total, added, seriesAdded, err := sl.append(slApp, []byte("{\"test.metric\"} 1\n"), "", time.Time{}) total, added, seriesAdded, err := sl.append(slApp, []byte("{\"test.metric\"} 1\n"), "text/plain", time.Time{})
require.ErrorContains(t, err, "invalid metric name or label names") require.ErrorContains(t, err, "invalid metric name or label names")
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
require.Equal(t, 1, total) require.Equal(t, 1, total)
@ -1199,7 +1204,7 @@ func TestScrapeLoopFailLegacyUnderUTF8(t *testing.T) {
sl.validationScheme = model.UTF8Validation sl.validationScheme = model.UTF8Validation
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
total, added, seriesAdded, err = sl.append(slApp, []byte("{\"test.metric\"} 1\n"), "", time.Time{}) total, added, seriesAdded, err = sl.append(slApp, []byte("{\"test.metric\"} 1\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, total) require.Equal(t, 1, total)
require.Equal(t, 1, added) require.Equal(t, 1, added)
@ -1229,7 +1234,7 @@ func BenchmarkScrapeLoopAppend(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ts = ts.Add(time.Second) ts = ts.Add(time.Second)
_, _, _, _ = sl.append(slApp, metrics, "", ts) _, _, _, _ = sl.append(slApp, metrics, "text/plain", ts)
} }
} }
@ -1338,7 +1343,8 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrape(t *testing.T) {
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
sl := newBasicScrapeLoop(t, ctx, scraper, app, 10*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, ctx, scraper, app, 10*time.Millisecond, "text/plain")
// Succeed once, several failures, then stop. // Succeed once, several failures, then stop.
numScrapes := 0 numScrapes := 0
@ -1384,7 +1390,8 @@ func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) {
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
sl := newBasicScrapeLoop(t, ctx, scraper, app, 10*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, ctx, scraper, app, 10*time.Millisecond, "text/plain")
// Succeed once, several failures, then stop. // Succeed once, several failures, then stop.
scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error { scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error {
@ -1435,7 +1442,8 @@ func TestScrapeLoopCache(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
// Decreasing the scrape interval could make the test fail, as multiple scrapes might be initiated at identical millisecond timestamps. // Decreasing the scrape interval could make the test fail, as multiple scrapes might be initiated at identical millisecond timestamps.
// See https://github.com/prometheus/prometheus/issues/12727. // See https://github.com/prometheus/prometheus/issues/12727.
sl := newBasicScrapeLoop(t, ctx, scraper, app, 100*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, ctx, scraper, app, 100*time.Millisecond, "text/plain")
numScrapes := 0 numScrapes := 0
@ -1600,7 +1608,7 @@ func TestScrapeLoopAppend(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(test.scrapeLabels), "", now) _, _, _, err := sl.append(slApp, []byte(test.scrapeLabels), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1681,7 +1689,7 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) {
return mutateSampleLabels(l, &Target{labels: labels.FromStrings(tc.targetLabels...)}, false, nil) return mutateSampleLabels(l, &Target{labels: labels.FromStrings(tc.targetLabels...)}, false, nil)
} }
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(tc.exposedLabels), "", time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC)) _, _, _, err := sl.append(slApp, []byte(tc.exposedLabels), "text/plain", time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1719,7 +1727,7 @@ func TestScrapeLoopAppendCacheEntryButErrNotFound(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, metric, "", now) _, _, _, err := sl.append(slApp, metric, "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1756,7 +1764,7 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
total, added, seriesAdded, err := sl.append(app, []byte("metric_a 1\nmetric_b 1\nmetric_c 1\n"), "", now) total, added, seriesAdded, err := sl.append(app, []byte("metric_a 1\nmetric_b 1\nmetric_c 1\n"), "text/plain", now)
require.ErrorIs(t, err, errSampleLimit) require.ErrorIs(t, err, errSampleLimit)
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
require.Equal(t, 3, total) require.Equal(t, 3, total)
@ -1785,7 +1793,7 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) {
now = time.Now() now = time.Now()
slApp = sl.appender(context.Background()) slApp = sl.appender(context.Background())
total, added, seriesAdded, err = sl.append(slApp, []byte("metric_a 1\nmetric_b 1\nmetric_c{deleteme=\"yes\"} 1\nmetric_d 1\nmetric_e 1\nmetric_f 1\nmetric_g 1\nmetric_h{deleteme=\"yes\"} 1\nmetric_i{deleteme=\"yes\"} 1\n"), "", now) total, added, seriesAdded, err = sl.append(slApp, []byte("metric_a 1\nmetric_b 1\nmetric_c{deleteme=\"yes\"} 1\nmetric_d 1\nmetric_e 1\nmetric_f 1\nmetric_g 1\nmetric_h{deleteme=\"yes\"} 1\nmetric_i{deleteme=\"yes\"} 1\n"), "text/plain", now)
require.ErrorIs(t, err, errSampleLimit) require.ErrorIs(t, err, errSampleLimit)
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
require.Equal(t, 9, total) require.Equal(t, 9, total)
@ -1913,12 +1921,12 @@ func TestScrapeLoop_ChangingMetricString(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1`), "", now) _, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1`), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
slApp = sl.appender(context.Background()) slApp = sl.appender(context.Background())
_, _, _, err = sl.append(slApp, []byte(`metric_a{b="1",a="1"} 2`), "", now.Add(time.Minute)) _, _, _, err = sl.append(slApp, []byte(`metric_a{b="1",a="1"} 2`), "text/plain", now.Add(time.Minute))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1937,6 +1945,33 @@ func TestScrapeLoop_ChangingMetricString(t *testing.T) {
require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender) require.Equal(t, want, capp.resultFloats, "Appended samples not as expected:\n%s", appender)
} }
func TestScrapeLoopAppendFailsWithNoContentType(t *testing.T) {
app := &collectResultAppender{}
// Explicitly setting the lack of fallback protocol here to make it obvious.
sl := newBasicScrapeLoopWithFallback(t, context.Background(), nil, func(ctx context.Context) storage.Appender { return app }, 0, "")
now := time.Now()
slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte("metric_a 1\n"), "", now)
// We expect the appropriate error.
require.ErrorContains(t, err, "non-compliant scrape target sending blank Content-Type and no fallback_scrape_protocol specified for target", "Expected \"non-compliant scrape\" error but got: %s", err)
}
func TestScrapeLoopAppendEmptyWithNoContentType(t *testing.T) {
// This test ensures we there are no errors when we get a blank scrape or just want to append a stale marker.
app := &collectResultAppender{}
// Explicitly setting the lack of fallback protocol here to make it obvious.
sl := newBasicScrapeLoopWithFallback(t, context.Background(), nil, func(ctx context.Context) storage.Appender { return app }, 0, "")
now := time.Now()
slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(""), "", now)
require.NoError(t, err)
require.NoError(t, slApp.Commit())
}
func TestScrapeLoopAppendStaleness(t *testing.T) { func TestScrapeLoopAppendStaleness(t *testing.T) {
app := &collectResultAppender{} app := &collectResultAppender{}
@ -1944,7 +1979,7 @@ func TestScrapeLoopAppendStaleness(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte("metric_a 1\n"), "", now) _, _, _, err := sl.append(slApp, []byte("metric_a 1\n"), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1973,7 +2008,7 @@ func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) {
sl := newBasicScrapeLoop(t, context.Background(), nil, func(ctx context.Context) storage.Appender { return app }, 0) sl := newBasicScrapeLoop(t, context.Background(), nil, func(ctx context.Context) storage.Appender { return app }, 0)
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte("metric_a 1 1000\n"), "", now) _, _, _, err := sl.append(slApp, []byte("metric_a 1 1000\n"), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -1999,7 +2034,7 @@ func TestScrapeLoopAppendStalenessIfTrackTimestampStaleness(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte("metric_a 1 1000\n"), "", now) _, _, _, err := sl.append(slApp, []byte("metric_a 1 1000\n"), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -2519,7 +2554,7 @@ func TestScrapeLoopAppendGracefullyIfAmendOrOutOfOrderOrOutOfBounds(t *testing.T
now := time.Unix(1, 0) now := time.Unix(1, 0)
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
total, added, seriesAdded, err := sl.append(slApp, []byte("out_of_order 1\namend 1\nnormal 1\nout_of_bounds 1\n"), "", now) total, added, seriesAdded, err := sl.append(slApp, []byte("out_of_order 1\namend 1\nnormal 1\nout_of_bounds 1\n"), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -2550,7 +2585,7 @@ func TestScrapeLoopOutOfBoundsTimeError(t *testing.T) {
now := time.Now().Add(20 * time.Minute) now := time.Now().Add(20 * time.Minute)
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
total, added, seriesAdded, err := sl.append(slApp, []byte("normal 1\n"), "", now) total, added, seriesAdded, err := sl.append(slApp, []byte("normal 1\n"), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.Equal(t, 1, total) require.Equal(t, 1, total)
@ -2850,7 +2885,7 @@ func TestScrapeLoop_RespectTimestamps(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1 0`), "", now) _, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1 0`), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -2877,7 +2912,7 @@ func TestScrapeLoop_DiscardTimestamps(t *testing.T) {
now := time.Now() now := time.Now()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1 0`), "", now) _, _, _, err := sl.append(slApp, []byte(`metric_a{a="1",b="1"} 1 0`), "text/plain", now)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -2901,7 +2936,7 @@ func TestScrapeLoopDiscardDuplicateLabels(t *testing.T) {
// We add a good and a bad metric to check that both are discarded. // We add a good and a bad metric to check that both are discarded.
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
_, _, _, err := sl.append(slApp, []byte("test_metric{le=\"500\"} 1\ntest_metric{le=\"600\",le=\"700\"} 1\n"), "", time.Time{}) _, _, _, err := sl.append(slApp, []byte("test_metric{le=\"500\"} 1\ntest_metric{le=\"600\",le=\"700\"} 1\n"), "text/plain", time.Time{})
require.Error(t, err) require.Error(t, err)
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
// We need to cycle staleness cache maps after a manual rollback. Otherwise they will have old entries in them, // We need to cycle staleness cache maps after a manual rollback. Otherwise they will have old entries in them,
@ -2916,7 +2951,7 @@ func TestScrapeLoopDiscardDuplicateLabels(t *testing.T) {
// We add a good metric to check that it is recorded. // We add a good metric to check that it is recorded.
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
_, _, _, err = sl.append(slApp, []byte("test_metric{le=\"500\"} 1\n"), "", time.Time{}) _, _, _, err = sl.append(slApp, []byte("test_metric{le=\"500\"} 1\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -2945,7 +2980,7 @@ func TestScrapeLoopDiscardUnnamedMetrics(t *testing.T) {
defer cancel() defer cancel()
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte("nok 1\nnok2{drop=\"drop\"} 1\n"), "", time.Time{}) _, _, _, err := sl.append(slApp, []byte("nok 1\nnok2{drop=\"drop\"} 1\n"), "text/plain", time.Time{})
require.Error(t, err) require.Error(t, err)
require.NoError(t, slApp.Rollback()) require.NoError(t, slApp.Rollback())
require.Equal(t, errNameLabelMandatory, err) require.Equal(t, errNameLabelMandatory, err)
@ -3191,7 +3226,7 @@ func TestScrapeAddFast(t *testing.T) {
defer cancel() defer cancel()
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
_, _, _, err := sl.append(slApp, []byte("up 1\n"), "", time.Time{}) _, _, _, err := sl.append(slApp, []byte("up 1\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
@ -3202,7 +3237,7 @@ func TestScrapeAddFast(t *testing.T) {
} }
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
_, _, _, err = sl.append(slApp, []byte("up 1\n"), "", time.Time{}.Add(time.Second)) _, _, _, err = sl.append(slApp, []byte("up 1\n"), "text/plain", time.Time{}.Add(time.Second))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
} }
@ -3257,7 +3292,8 @@ func TestScrapeReportSingleAppender(t *testing.T) {
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
sl := newBasicScrapeLoop(t, ctx, scraper, s.Appender, 10*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, ctx, scraper, s.Appender, 10*time.Millisecond, "text/plain")
numScrapes := 0 numScrapes := 0
@ -3484,7 +3520,7 @@ func TestScrapeLoopLabelLimit(t *testing.T) {
sl.labelLimits = &test.labelLimits sl.labelLimits = &test.labelLimits
slApp := sl.appender(context.Background()) slApp := sl.appender(context.Background())
_, _, _, err := sl.append(slApp, []byte(test.scrapeLabels), "", time.Now()) _, _, _, err := sl.append(slApp, []byte(test.scrapeLabels), "text/plain", time.Now())
t.Logf("Test:%s", test.title) t.Logf("Test:%s", test.title)
if test.expectErr { if test.expectErr {
@ -4176,7 +4212,8 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrapeForTimestampedMetrics(t *
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
sl := newBasicScrapeLoop(t, ctx, scraper, app, 10*time.Millisecond) // Since we're writing samples directly below we need to provide a protocol fallback.
sl := newBasicScrapeLoopWithFallback(t, ctx, scraper, app, 10*time.Millisecond, "text/plain")
sl.trackTimestampsStaleness = true sl.trackTimestampsStaleness = true
// Succeed once, several failures, then stop. // Succeed once, several failures, then stop.
numScrapes := 0 numScrapes := 0
@ -4421,7 +4458,7 @@ func TestScrapeLoopSeriesAddedDuplicates(t *testing.T) {
ctx, sl := simpleTestScrapeLoop(t) ctx, sl := simpleTestScrapeLoop(t)
slApp := sl.appender(ctx) slApp := sl.appender(ctx)
total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\ntest_metric 2\ntest_metric 3\n"), "", time.Time{}) total, added, seriesAdded, err := sl.append(slApp, []byte("test_metric 1\ntest_metric 2\ntest_metric 3\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.Equal(t, 3, total) require.Equal(t, 3, total)
@ -4430,7 +4467,7 @@ func TestScrapeLoopSeriesAddedDuplicates(t *testing.T) {
require.Equal(t, 2.0, prom_testutil.ToFloat64(sl.metrics.targetScrapeSampleDuplicate)) require.Equal(t, 2.0, prom_testutil.ToFloat64(sl.metrics.targetScrapeSampleDuplicate))
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1\ntest_metric 1\ntest_metric 1\n"), "", time.Time{}) total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1\ntest_metric 1\ntest_metric 1\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.Equal(t, 3, total) require.Equal(t, 3, total)
@ -4440,7 +4477,7 @@ func TestScrapeLoopSeriesAddedDuplicates(t *testing.T) {
// When different timestamps are supplied, multiple samples are accepted. // When different timestamps are supplied, multiple samples are accepted.
slApp = sl.appender(ctx) slApp = sl.appender(ctx)
total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1 1001\ntest_metric 1 1002\ntest_metric 1 1003\n"), "", time.Time{}) total, added, seriesAdded, err = sl.append(slApp, []byte("test_metric 1 1001\ntest_metric 1 1002\ntest_metric 1 1003\n"), "text/plain", time.Time{})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, slApp.Commit()) require.NoError(t, slApp.Commit())
require.Equal(t, 3, total) require.Equal(t, 3, total)

@ -1,7 +1,7 @@
{ {
"name": "@prometheus-io/mantine-ui", "name": "@prometheus-io/mantine-ui",
"private": true, "private": true,
"version": "0.300.0-beta.1", "version": "0.300.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
@ -28,7 +28,7 @@
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@nexucis/fuzzy": "^0.5.1", "@nexucis/fuzzy": "^0.5.1",
"@nexucis/kvsearch": "^0.9.1", "@nexucis/kvsearch": "^0.9.1",
"@prometheus-io/codemirror-promql": "0.300.0-beta.1", "@prometheus-io/codemirror-promql": "0.300.0",
"@reduxjs/toolkit": "^2.2.1", "@reduxjs/toolkit": "^2.2.1",
"@tabler/icons-react": "^3.19.0", "@tabler/icons-react": "^3.19.0",
"@tanstack/react-query": "^5.59.0", "@tanstack/react-query": "^5.59.0",

@ -1,6 +1,6 @@
{ {
"name": "@prometheus-io/codemirror-promql", "name": "@prometheus-io/codemirror-promql",
"version": "0.300.0-beta.1", "version": "0.300.0",
"description": "a CodeMirror mode for the PromQL language", "description": "a CodeMirror mode for the PromQL language",
"types": "dist/esm/index.d.ts", "types": "dist/esm/index.d.ts",
"module": "dist/esm/index.js", "module": "dist/esm/index.js",
@ -29,7 +29,7 @@
}, },
"homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md", "homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md",
"dependencies": { "dependencies": {
"@prometheus-io/lezer-promql": "0.300.0-beta.1", "@prometheus-io/lezer-promql": "0.300.0",
"lru-cache": "^11.0.1" "lru-cache": "^11.0.1"
}, },
"devDependencies": { "devDependencies": {

@ -1,6 +1,6 @@
{ {
"name": "@prometheus-io/lezer-promql", "name": "@prometheus-io/lezer-promql",
"version": "0.300.0-beta.1", "version": "0.300.0",
"description": "lezer-based PromQL grammar", "description": "lezer-based PromQL grammar",
"main": "dist/index.cjs", "main": "dist/index.cjs",
"type": "module", "type": "module",

@ -1,12 +1,12 @@
{ {
"name": "prometheus-io", "name": "prometheus-io",
"version": "0.300.0-beta.1", "version": "0.300.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "prometheus-io", "name": "prometheus-io",
"version": "0.300.0-beta.1", "version": "0.300.0",
"workspaces": [ "workspaces": [
"mantine-ui", "mantine-ui",
"module/*" "module/*"
@ -24,7 +24,7 @@
}, },
"mantine-ui": { "mantine-ui": {
"name": "@prometheus-io/mantine-ui", "name": "@prometheus-io/mantine-ui",
"version": "0.300.0-beta.1", "version": "0.300.0",
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.18.1", "@codemirror/autocomplete": "^6.18.1",
"@codemirror/language": "^6.10.2", "@codemirror/language": "^6.10.2",
@ -42,7 +42,7 @@
"@microsoft/fetch-event-source": "^2.0.1", "@microsoft/fetch-event-source": "^2.0.1",
"@nexucis/fuzzy": "^0.5.1", "@nexucis/fuzzy": "^0.5.1",
"@nexucis/kvsearch": "^0.9.1", "@nexucis/kvsearch": "^0.9.1",
"@prometheus-io/codemirror-promql": "0.300.0-beta.1", "@prometheus-io/codemirror-promql": "0.300.0",
"@reduxjs/toolkit": "^2.2.1", "@reduxjs/toolkit": "^2.2.1",
"@tabler/icons-react": "^3.19.0", "@tabler/icons-react": "^3.19.0",
"@tanstack/react-query": "^5.59.0", "@tanstack/react-query": "^5.59.0",
@ -155,10 +155,10 @@
}, },
"module/codemirror-promql": { "module/codemirror-promql": {
"name": "@prometheus-io/codemirror-promql", "name": "@prometheus-io/codemirror-promql",
"version": "0.300.0-beta.1", "version": "0.300.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@prometheus-io/lezer-promql": "0.300.0-beta.1", "@prometheus-io/lezer-promql": "0.300.0",
"lru-cache": "^11.0.1" "lru-cache": "^11.0.1"
}, },
"devDependencies": { "devDependencies": {
@ -188,7 +188,7 @@
}, },
"module/lezer-promql": { "module/lezer-promql": {
"name": "@prometheus-io/lezer-promql", "name": "@prometheus-io/lezer-promql",
"version": "0.300.0-beta.1", "version": "0.300.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"devDependencies": { "devDependencies": {
"@lezer/generator": "^1.7.1", "@lezer/generator": "^1.7.1",

@ -1,7 +1,7 @@
{ {
"name": "prometheus-io", "name": "prometheus-io",
"description": "Monorepo for the Prometheus UI", "description": "Monorepo for the Prometheus UI",
"version": "0.300.0-beta.1", "version": "0.300.0",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "bash build_ui.sh --all", "build": "bash build_ui.sh --all",

@ -1,12 +1,12 @@
{ {
"name": "@prometheus-io/app", "name": "@prometheus-io/app",
"version": "0.55.0", "version": "0.300.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@prometheus-io/app", "name": "@prometheus-io/app",
"version": "0.55.0", "version": "0.300.0",
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.17.0", "@codemirror/autocomplete": "^6.17.0",
"@codemirror/commands": "^6.6.0", "@codemirror/commands": "^6.6.0",

@ -1,6 +1,6 @@
{ {
"name": "@prometheus-io/app", "name": "@prometheus-io/app",
"version": "0.55.0", "version": "0.300.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.17.0", "@codemirror/autocomplete": "^6.17.0",

Loading…
Cancel
Save