package weather import ( "context" "errors" "github.com/rs/zerolog" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/ambient/config" ) type MetricRecorder struct { ctx context.Context l *zerolog.Logger } type RecordOpts struct { Float64Gauge metric.Float64Gauge Int64Gauge metric.Int64Gauge IntVal *int FloatVal *float64 Attributes []attribute.KeyValue Field string Station *config.WeatherStation } func (r *MetricRecorder) Record(opts *RecordOpts) { if opts.Station != nil && !opts.keep() { r.l.Trace(). Str("field", string(opts.Field)). Str("station", opts.Station.Name). Msg("Metric dropped by station config") return } else if opts.Int64Gauge == nil && opts.Float64Gauge == nil { r.l.Err(errors.New("neither int nor float gauge provided")).Send() return } if opts.Int64Gauge != nil { if opts.IntVal == nil { log := r.l.Trace().Str("field", string(opts.Field)) if opts.Station != nil { log = log.Str("station", opts.Station.Name) } log.Msg("Dropping nil int metric") return } r.recordInt(opts.Int64Gauge, *opts.IntVal, opts.Attributes...) } else if opts.Float64Gauge != nil { if opts.FloatVal == nil { log := r.l.Trace().Str("field", string(opts.Field)) if opts.Station != nil { log = log.Str("station", opts.Station.Name) } log.Msg("Dropping nil float metric") return } r.recordFloat(opts.Float64Gauge, *opts.FloatVal, opts.Attributes...) } } func (o *RecordOpts) keep() bool { // If keep fields are given, only check keep fields if len(o.Station.KeepMetrics) > 0 { for _, f := range o.Station.KeepMetrics { if f == o.Field { return true } } return false } for _, f := range o.Station.DropMetrics { if f == o.Field { return false } } return true } func (r *MetricRecorder) recordInt( m metric.Int64Gauge, value int, attributes ...attribute.KeyValue, ) { // Prepare metric attributes options := make([]metric.RecordOption, 0, len(attributes)) if len(attributes) > 0 { options = append(options, metric.WithAttributes(attributes...)) } val := int64(value) m.Record(r.ctx, val, options...) } func (r *MetricRecorder) recordFloat( m metric.Float64Gauge, value float64, attributes ...attribute.KeyValue, ) { // Prepare metric attributes options := make([]metric.RecordOption, 0, len(attributes)) if len(attributes) > 0 { options = append(options, metric.WithAttributes(attributes...)) } m.Record(r.ctx, value, options...) }