Files
Carles Garciaandzeekay 5dcc25ddfa Fix metrics generator panic when write_relabel_configs is set (#6396) (#6399)
The Prometheus dependency upgrade from v0.304.2 to v0.307.3 (PR
  prometheus/prometheus#16928) moved label name validation from a global
  to a per-config NameValidationScheme field on relabel.Config. This field
  must be initialized by calling Validate() before use, otherwise
  relabeling panics with "Invalid name validation scheme requested: unset".

  Tempo constructs RemoteWriteConfig programmatically rather than going
  through Prometheus's config.Load() path, so Validate() was never called.

  Call RemoteWriteConfig.Validate(model.UTF8Validation) once at startup
  in storage.Config.Validate(), which initializes NameValidationScheme on
  all write relabel configs before any tenant storage instances are created.

  Also fix a pre-existing bug in watchOverrides where cached state was
  updated before ApplyConfig succeeded, preventing retries on failure.
2026-02-22 00:55:22 -08:00

88 lines
3.0 KiB
Go

package storage
import (
"flag"
"fmt"
"time"
"github.com/prometheus/common/model"
prometheus_config "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/tsdb/agent"
"github.com/prometheus/prometheus/util/compression"
)
type Config struct {
// Path to store the WAL. Each tenant will be stored in its own subdirectory.
Path string `yaml:"path"`
Wal agentOptions `yaml:"wal"`
// How long to wait when flushing sample on shutdown
RemoteWriteFlushDeadline time.Duration `yaml:"remote_write_flush_deadline"`
// Add X-Scope-OrgID header in remote write requests
RemoteWriteAddOrgIDHeader bool `yaml:"remote_write_add_org_id_header,omitempty"`
// Prometheus remote write config
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write
RemoteWrite []prometheus_config.RemoteWriteConfig `yaml:"remote_write,omitempty"`
}
// Validate initializes and validates the remote write configurations. This must
// be called once at startup before any tenant storage instances are created, so
// that NameValidationScheme is set on all write relabel configs. Without this,
// relabeling panics with "Invalid name validation scheme requested: unset".
func (cfg *Config) Validate() error {
for i := range cfg.RemoteWrite {
if err := cfg.RemoteWrite[i].Validate(model.UTF8Validation); err != nil {
return fmt.Errorf("invalid remote write config %q: %w", cfg.RemoteWrite[i].Name, err)
}
}
return nil
}
func (cfg *Config) RegisterFlagsAndApplyDefaults(string, *flag.FlagSet) {
cfg.Wal = agentDefaultOptions()
cfg.RemoteWriteFlushDeadline = time.Minute
cfg.RemoteWriteAddOrgIDHeader = true
}
// agentOptions is a copy of agent.Options but with yaml struct tags. Refer to agent.Options for
// documentation.
type agentOptions struct {
WALSegmentSize int `yaml:"wal_segment_size"`
WALCompression compression.Type `yaml:"wal_compression"`
StripeSize int `yaml:"stripe_size"`
TruncateFrequency time.Duration `yaml:"truncate_frequency"`
MinWALTime int64 `yaml:"min_wal_time"`
MaxWALTime int64 `yaml:"max_wal_time"`
NoLockfile bool `yaml:"no_lockfile"`
}
func agentDefaultOptions() agentOptions {
defaultOptions := agent.DefaultOptions()
return agentOptions{
WALSegmentSize: defaultOptions.WALSegmentSize,
WALCompression: defaultOptions.WALCompression,
StripeSize: defaultOptions.StripeSize,
TruncateFrequency: defaultOptions.TruncateFrequency,
MinWALTime: defaultOptions.MinWALTime,
MaxWALTime: defaultOptions.MaxWALTime,
NoLockfile: defaultOptions.NoLockfile,
}
}
func (a *agentOptions) toPrometheusAgentOptions() *agent.Options {
return &agent.Options{
WALSegmentSize: a.WALSegmentSize,
WALCompression: a.WALCompression,
StripeSize: a.StripeSize,
TruncateFrequency: a.TruncateFrequency,
MinWALTime: a.MinWALTime,
MaxWALTime: a.MaxWALTime,
NoLockfile: a.NoLockfile,
}
}