package prom import ( "context" "errors" "fmt" "math" "sync" "k8s.io/klog/v2" "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/model/exemplar" "github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/metadata" "github.com/prometheus/prometheus/scrape" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/agent" ) // copy-pasted from Prometheus' main.go type readyStorage struct { mtx sync.RWMutex db storage.Storage startTimeMargin int64 stats *tsdb.DBStats } func (s *readyStorage) ApplyConfig(conf *config.Config) error { return nil } func (s *readyStorage) Set(db storage.Storage, startTimeMargin int64) { s.mtx.Lock() defer s.mtx.Unlock() s.db = db s.startTimeMargin = startTimeMargin } func (s *readyStorage) get() storage.Storage { s.mtx.RLock() x := s.db s.mtx.RUnlock() return x } func (s *readyStorage) getStats() *tsdb.DBStats { s.mtx.RLock() x := s.stats s.mtx.RUnlock() return x } func (s *readyStorage) StartTime() (int64, error) { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return db.StartTime() default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return math.MaxInt64, tsdb.ErrNotReady } func (s *readyStorage) Querier(mint, maxt int64) (storage.Querier, error) { if x := s.get(); x != nil { return x.Querier(mint, maxt) } return nil, tsdb.ErrNotReady } func (s *readyStorage) ChunkQuerier(mint, maxt int64) (storage.ChunkQuerier, error) { if x := s.get(); x != nil { return x.ChunkQuerier(mint, maxt) } return nil, tsdb.ErrNotReady } func (s *readyStorage) ExemplarQuerier(ctx context.Context) (storage.ExemplarQuerier, error) { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return nil, agent.ErrUnsupported default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return nil, tsdb.ErrNotReady } func (s *readyStorage) Appender(ctx context.Context) storage.Appender { if x := s.get(); x != nil { return x.Appender(ctx) } return notReadyAppender{} } type notReadyAppender struct{} func (n notReadyAppender) Append(ref storage.SeriesRef, l labels.Labels, t int64, v float64) (storage.SeriesRef, error) { return 0, tsdb.ErrNotReady } func (n notReadyAppender) AppendExemplar(ref storage.SeriesRef, l labels.Labels, e exemplar.Exemplar) (storage.SeriesRef, error) { return 0, tsdb.ErrNotReady } func (n notReadyAppender) AppendHistogram(ref storage.SeriesRef, l labels.Labels, t int64, h *histogram.Histogram, fh *histogram.FloatHistogram) (storage.SeriesRef, error) { return 0, tsdb.ErrNotReady } func (n notReadyAppender) AppendCTZeroSample(ref storage.SeriesRef, l labels.Labels, t, ct int64) (storage.SeriesRef, error) { return 0, tsdb.ErrNotReady } func (n notReadyAppender) UpdateMetadata(ref storage.SeriesRef, l labels.Labels, m metadata.Metadata) (storage.SeriesRef, error) { return 0, tsdb.ErrNotReady } func (n notReadyAppender) Commit() error { return tsdb.ErrNotReady } func (n notReadyAppender) Rollback() error { return tsdb.ErrNotReady } func (s *readyStorage) Close() error { if x := s.get(); x != nil { return x.Close() } return nil } func (s *readyStorage) CleanTombstones() error { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return agent.ErrUnsupported default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return tsdb.ErrNotReady } func (s *readyStorage) Delete(ctx context.Context, mint, maxt int64, ms ...*labels.Matcher) error { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return agent.ErrUnsupported default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return tsdb.ErrNotReady } func (s *readyStorage) Snapshot(dir string, withHead bool) error { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return agent.ErrUnsupported default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return tsdb.ErrNotReady } func (s *readyStorage) Stats(statsByLabelName string, limit int) (*tsdb.Stats, error) { if x := s.get(); x != nil { switch db := x.(type) { case *agent.DB: return nil, agent.ErrUnsupported default: panic(fmt.Sprintf("unknown storage type %T", db)) } } return nil, tsdb.ErrNotReady } func (s *readyStorage) WALReplayStatus() (tsdb.WALReplayStatus, error) { if x := s.getStats(); x != nil { return x.Head.WALReplayStatus.GetWALReplayStatus(), nil } return tsdb.WALReplayStatus{}, tsdb.ErrNotReady } var ErrNotReady = errors.New("Scrape manager not ready") type readyScrapeManager struct { mtx sync.RWMutex m *scrape.Manager } func (rm *readyScrapeManager) Set(m *scrape.Manager) { rm.mtx.Lock() defer rm.mtx.Unlock() rm.m = m } func (rm *readyScrapeManager) Get() (*scrape.Manager, error) { rm.mtx.RLock() defer rm.mtx.RUnlock() if rm.m != nil { return rm.m, nil } return nil, ErrNotReady } type Logger struct{} func (l Logger) Log(v ...interface{}) error { klog.Infoln(v...) return nil }