Prometheus: Create feature flag to disable exemplar sampling (#60105)
:Fix rebase
This commit is contained in:
@@ -19,16 +19,17 @@ This page contains a list of available feature toggles. To learn how to turn on
|
|||||||
|
|
||||||
Some stable features are enabled by default. You can disable a stable feature by setting the feature flag to "false" in the configuration.
|
Some stable features are enabled by default. You can disable a stable feature by setting the feature flag to "false" in the configuration.
|
||||||
|
|
||||||
| Feature toggle name | Description | Enabled by default |
|
| Feature toggle name | Description | Enabled by default |
|
||||||
| ---------------------------- | ------------------------------------------------------------------------------------ | ------------------ |
|
| ----------------------------------- | ------------------------------------------------------------------------------------ | ------------------ |
|
||||||
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
|
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
|
||||||
| `database_metrics` | Add Prometheus metrics for database tables | |
|
| `database_metrics` | Add Prometheus metrics for database tables | |
|
||||||
| `lokiMonacoEditor` | Access to Monaco query editor for Loki | Yes |
|
| `lokiMonacoEditor` | Access to Monaco query editor for Loki | Yes |
|
||||||
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
||||||
| `commandPalette` | Enable command palette | Yes |
|
| `commandPalette` | Enable command palette | Yes |
|
||||||
| `cloudWatchDynamicLabels` | Use dynamic labels instead of alias patterns in CloudWatch datasource | Yes |
|
| `cloudWatchDynamicLabels` | Use dynamic labels instead of alias patterns in CloudWatch datasource | Yes |
|
||||||
| `internationalization` | Enables internationalization | Yes |
|
| `internationalization` | Enables internationalization | Yes |
|
||||||
| `accessTokenExpirationCheck` | Enable OAuth access_token expiration check and token refresh using the refresh_token | |
|
| `accessTokenExpirationCheck` | Enable OAuth access_token expiration check and token refresh using the refresh_token | |
|
||||||
|
| `disablePrometheusExemplarSampling` | Disable Prometheus examplar sampling | |
|
||||||
|
|
||||||
## Beta feature toggles
|
## Beta feature toggles
|
||||||
|
|
||||||
|
|||||||
@@ -84,5 +84,6 @@ export interface FeatureToggles {
|
|||||||
secureSocksDatasourceProxy?: boolean;
|
secureSocksDatasourceProxy?: boolean;
|
||||||
authnService?: boolean;
|
authnService?: boolean;
|
||||||
sessionRemoteCache?: boolean;
|
sessionRemoteCache?: boolean;
|
||||||
|
disablePrometheusExemplarSampling?: boolean;
|
||||||
alertingBacktesting?: boolean;
|
alertingBacktesting?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -382,6 +382,11 @@ var (
|
|||||||
Description: "Enable using remote cache for user sessions",
|
Description: "Enable using remote cache for user sessions",
|
||||||
State: FeatureStateAlpha,
|
State: FeatureStateAlpha,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "disablePrometheusExemplarSampling",
|
||||||
|
Description: "Disable Prometheus examplar sampling",
|
||||||
|
State: FeatureStateStable,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "alertingBacktesting",
|
Name: "alertingBacktesting",
|
||||||
Description: "Rule backtesting API for alerting",
|
Description: "Rule backtesting API for alerting",
|
||||||
|
|||||||
@@ -279,6 +279,10 @@ const (
|
|||||||
// Enable using remote cache for user sessions
|
// Enable using remote cache for user sessions
|
||||||
FlagSessionRemoteCache = "sessionRemoteCache"
|
FlagSessionRemoteCache = "sessionRemoteCache"
|
||||||
|
|
||||||
|
// FlagDisablePrometheusExemplarSampling
|
||||||
|
// Disable Prometheus examplar sampling
|
||||||
|
FlagDisablePrometheusExemplarSampling = "disablePrometheusExemplarSampling"
|
||||||
|
|
||||||
// FlagAlertingBacktesting
|
// FlagAlertingBacktesting
|
||||||
// Rule backtesting API for alerting
|
// Rule backtesting API for alerting
|
||||||
FlagAlertingBacktesting = "alertingBacktesting"
|
FlagAlertingBacktesting = "alertingBacktesting"
|
||||||
|
|||||||
@@ -16,17 +16,19 @@ type exemplar struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type exemplarSampler struct {
|
type exemplarSampler struct {
|
||||||
buckets map[time.Time][]exemplar
|
buckets map[time.Time][]exemplar
|
||||||
labelSet map[string]struct{}
|
labelSet map[string]struct{}
|
||||||
count int
|
disableSampling bool
|
||||||
mean float64
|
count int
|
||||||
m2 float64
|
mean float64
|
||||||
|
m2 float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func newExemplarSampler() *exemplarSampler {
|
func newExemplarSampler(disableSampling bool) *exemplarSampler {
|
||||||
return &exemplarSampler{
|
return &exemplarSampler{
|
||||||
buckets: map[time.Time][]exemplar{},
|
buckets: map[time.Time][]exemplar{},
|
||||||
labelSet: map[string]struct{}{},
|
labelSet: map[string]struct{}{},
|
||||||
|
disableSampling: disableSampling,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +100,18 @@ func (e *exemplarSampler) getLabelNames() []string {
|
|||||||
|
|
||||||
// getSampledExemplars returns the exemplars sorted by timestamp
|
// getSampledExemplars returns the exemplars sorted by timestamp
|
||||||
func (e *exemplarSampler) getSampledExemplars() []exemplar {
|
func (e *exemplarSampler) getSampledExemplars() []exemplar {
|
||||||
exemplars := make([]exemplar, 0, len(e.buckets))
|
var exemplars []exemplar
|
||||||
|
|
||||||
|
if e.disableSampling {
|
||||||
|
for _, bucket := range e.buckets {
|
||||||
|
exemplars = append(exemplars, bucket...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return exemplars
|
||||||
|
}
|
||||||
|
|
||||||
|
exemplars = make([]exemplar, 0, len(e.buckets))
|
||||||
|
|
||||||
for _, b := range e.buckets {
|
for _, b := range e.buckets {
|
||||||
// sort by value in descending order
|
// sort by value in descending order
|
||||||
sort.SliceStable(b, func(i, j int) bool {
|
sort.SliceStable(b, func(i, j int) bool {
|
||||||
|
|||||||
@@ -34,14 +34,15 @@ type ExemplarEvent struct {
|
|||||||
// QueryData handles querying but different from buffered package uses a custom client instead of default Go Prom
|
// QueryData handles querying but different from buffered package uses a custom client instead of default Go Prom
|
||||||
// client.
|
// client.
|
||||||
type QueryData struct {
|
type QueryData struct {
|
||||||
intervalCalculator intervalv2.Calculator
|
intervalCalculator intervalv2.Calculator
|
||||||
tracer tracing.Tracer
|
tracer tracing.Tracer
|
||||||
client *client.Client
|
client *client.Client
|
||||||
log log.Logger
|
log log.Logger
|
||||||
ID int64
|
ID int64
|
||||||
URL string
|
URL string
|
||||||
TimeInterval string
|
TimeInterval string
|
||||||
enableWideSeries bool
|
enableWideSeries bool
|
||||||
|
disablePrometheusExemplarSampling bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(
|
func New(
|
||||||
@@ -65,14 +66,15 @@ func New(
|
|||||||
promClient := client.NewClient(httpClient, httpMethod, settings.URL)
|
promClient := client.NewClient(httpClient, httpMethod, settings.URL)
|
||||||
|
|
||||||
return &QueryData{
|
return &QueryData{
|
||||||
intervalCalculator: intervalv2.NewCalculator(),
|
intervalCalculator: intervalv2.NewCalculator(),
|
||||||
tracer: tracer,
|
tracer: tracer,
|
||||||
log: plog,
|
log: plog,
|
||||||
client: promClient,
|
client: promClient,
|
||||||
TimeInterval: timeInterval,
|
TimeInterval: timeInterval,
|
||||||
ID: settings.ID,
|
ID: settings.ID,
|
||||||
URL: settings.URL,
|
URL: settings.URL,
|
||||||
enableWideSeries: features.IsEnabled(featuremgmt.FlagPrometheusWideSeries),
|
enableWideSeries: features.IsEnabled(featuremgmt.FlagPrometheusWideSeries),
|
||||||
|
disablePrometheusExemplarSampling: features.IsEnabled(featuremgmt.FlagDisablePrometheusExemplarSampling),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *htt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = processExemplars(q, r)
|
r = processExemplars(q, r, s.disablePrometheusExemplarSampling)
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,8 +136,8 @@ func getName(q *models.Query, field *data.Field) string {
|
|||||||
return legend
|
return legend
|
||||||
}
|
}
|
||||||
|
|
||||||
func processExemplars(q *models.Query, dr *backend.DataResponse) *backend.DataResponse {
|
func processExemplars(q *models.Query, dr *backend.DataResponse, disableSampling bool) *backend.DataResponse {
|
||||||
sampler := newExemplarSampler()
|
sampler := newExemplarSampler(disableSampling)
|
||||||
|
|
||||||
// we are moving from a multi-frame response returned
|
// we are moving from a multi-frame response returned
|
||||||
// by the converter to a single exemplar frame,
|
// by the converter to a single exemplar frame,
|
||||||
|
|||||||
Reference in New Issue
Block a user