Path: blob/main/component/otelcol/exporter/prometheus/internal/convert/cache.go
4100 views
package convert12import (3"sync"4"time"56"github.com/prometheus/common/model"7"github.com/prometheus/prometheus/model/labels"8"github.com/prometheus/prometheus/model/metadata"9"github.com/prometheus/prometheus/model/timestamp"10"github.com/prometheus/prometheus/storage"11)1213// memorySeries is an in-memory series mapped from an OpenTelemetry Collector14// data point.15type memorySeries struct {16// We shouldn't need an RWMutex here because there should only ever be17// exactly one goroutine for each memory series, since each series is18// intended to be unique.19sync.Mutex2021labels labels.Labels // Labels used for writing.22metadata map[string]string // Extra (optional) metadata used for conversion.2324id storage.SeriesRef // id returned by storage.Appender.2526timestamp time.Time // Timestamp used for out-of-order detection.27lastSeen time.Time // Timestamp used for garbage collection.2829value float64 // Value used for writing.30}3132func newMemorySeries(metadata map[string]string, labels labels.Labels) *memorySeries {33return &memorySeries{34metadata: metadata,35labels: labels,36}37}3839// Metadata returns a metadata value by key.40func (series *memorySeries) Metadata(key string) string {41if series.metadata == nil {42return ""43}44return series.metadata[key]45}4647// Timestamp returns the current timestamp of this series.48func (series *memorySeries) Timestamp() time.Time {49series.Lock()50defer series.Unlock()51return series.timestamp52}5354// SetTimestamp updates the current timestamp of this series.55func (series *memorySeries) SetTimestamp(newTime time.Time) {56// TODO(rfratto): does this need to be a CAS-style function instead?57series.Lock()58defer series.Unlock()59series.timestamp = newTime60}6162// LastSeen returns the timestamp when this series was last seen.63func (series *memorySeries) LastSeen() time.Time {64series.Lock()65defer series.Unlock()66return series.lastSeen67}6869// Ping updates the last seen timestamp of this series.70func (series *memorySeries) Ping() {71series.Lock()72defer series.Unlock()73series.lastSeen = time.Now()74}7576// Value gets the current value of this series.77func (series *memorySeries) Value() float64 {78series.Lock()79defer series.Unlock()80return series.value81}8283// SetValue updates the current value of this series.84func (series *memorySeries) SetValue(newValue float64) {85// TODO(rfratto): does this need to be a CAS-style function instead?86series.Lock()87defer series.Unlock()88series.value = newValue89}9091func (series *memorySeries) WriteTo(app storage.Appender, ts time.Time) error {92series.Lock()93defer series.Unlock()9495newID, err := app.Append(series.id, series.labels, timestamp.FromTime(ts), series.value)96if err != nil {97return err98}99100if newID != series.id {101series.id = newID102}103return nil104}105106type memoryMetadata struct {107sync.Mutex108109// ID returned by the underlying storage.Appender.110ID storage.SeriesRef111Name string112113lastSeen time.Time114metadata metadata.Metadata115116// Used for determining when a write needs to occur.117lastWrite, lastUpdate time.Time118}119120// WriteTo writes the metadata to app if the metadata has changed since the121// last update, otherwise WriteTo is a no-op.122func (md *memoryMetadata) WriteTo(app storage.Appender, ts time.Time) error {123md.Lock()124defer md.Unlock()125126if !md.lastWrite.Before(md.lastUpdate) {127return nil128}129130labels := labels.FromStrings(model.MetricNameLabel, md.Name)131132ref, err := app.UpdateMetadata(md.ID, labels, md.metadata)133if err != nil {134return err135}136if ref != md.ID {137md.ID = ref138}139140md.lastWrite = md.lastUpdate141return nil142}143144// Update updates the metadata used by md. The next call to WriteTo will write145// the new metadata only if m is different from the last metadata stored.146func (md *memoryMetadata) Update(m metadata.Metadata) {147md.Lock()148defer md.Unlock()149150md.lastSeen = time.Now()151152// Metadata hasn't changed; don't do anything.153if m == md.metadata {154return155}156157md.metadata = m158md.lastUpdate = time.Now()159}160161162