Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: gauges optimization #655

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 44 additions & 25 deletions stats/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,18 @@ type otelStats struct {
tracerMap map[string]Tracer
tracerMapMu sync.Mutex

meter metric.Meter
noopMeter metric.Meter
counters map[string]metric.Int64Counter
countersMu sync.Mutex
gauges map[string]*otelGauge
gaugesMu sync.Mutex
timers map[string]metric.Float64Histogram
timersMu sync.Mutex
histograms map[string]metric.Float64Histogram
histogramsMu sync.Mutex
meter metric.Meter
noopMeter metric.Meter
counters map[string]metric.Int64Counter
countersMu sync.Mutex
gauges map[string]*otelGauge
gaugesOtel map[string]metric.Float64ObservableGauge
gaugesMu sync.RWMutex
gaugesRegisterOnce sync.Once
timers map[string]metric.Float64Histogram
timersMu sync.Mutex
histograms map[string]metric.Float64Histogram
histogramsMu sync.Mutex

otelManager otel.Manager
collectorAggregator *aggregatedCollector
Expand Down Expand Up @@ -380,34 +382,51 @@ func (s *otelStats) getGauge(

if s.gauges == nil {
s.gauges = make(map[string]*otelGauge)
s.gaugesOtel = make(map[string]metric.Float64ObservableGauge)
} else {
og, ok = s.gauges[mapKey]
}

if !ok {
g, exists := s.gaugesOtel[name]
if !exists {
var err error
g, err = s.meter.Float64ObservableGauge(name)
if err != nil {
s.logger.Warnf("failed to create observable gauge %s: %v", name, err)
g, _ = s.noopMeter.Float64ObservableGauge(name)
}
}

og = &otelGauge{otelMeasurement: &otelMeasurement{
genericMeasurement: genericMeasurement{statType: GaugeType},
attributes: attributes,
}}
}, observableGauge: g}

g, err := s.meter.Float64ObservableGauge(name)
if err != nil {
s.logger.Warnf("failed to create gauge %s: %v", name, err)
g, _ = s.noopMeter.Float64ObservableGauge(name)
} else {
_, err = s.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error {
s.gauges[mapKey] = og
s.gaugesOtel[name] = g
}

s.gaugesRegisterOnce.Do(func() {
_, err := s.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error {
s.gaugesMu.RLock()
defer s.gaugesMu.RUnlock()

for _, og := range s.gauges {
if og.disabled {
continue
}
if value := og.getValue(); value != nil {
o.ObserveFloat64(g, cast.ToFloat64(value), metric.WithAttributes(attributes...))
o.ObserveFloat64(og.observableGauge, cast.ToFloat64(value), metric.WithAttributes(og.attributes...))
}
return nil
}, g)
if err != nil {
panic(fmt.Errorf("failed to register callback for gauge %s: %w", name, err))
}
}

s.gauges[mapKey] = og
}
return nil
})
if err != nil {
panic(fmt.Errorf("failed to register callback for gauge %s: %w", name, err))
}
})

return og
}
Expand Down
3 changes: 2 additions & 1 deletion stats/otel_measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func (c *otelCounter) Increment() {
// otelGauge represents a gauge stat
type otelGauge struct {
*otelMeasurement
value atomic.Value
value atomic.Value
observableGauge metric.Float64ObservableGauge
}

// Gauge records an absolute value for this stat. Only applies to GaugeType stats
Expand Down
Loading