-
Notifications
You must be signed in to change notification settings - Fork 2
/
metrics.go
92 lines (78 loc) · 2.87 KB
/
metrics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package middleware
import (
"fmt"
"log/slog"
"net/http"
"sync"
"go.opentelemetry.io/otel/exporters/prometheus"
metric_api "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk/metric"
"github.com/pgillich/opentracing-example/internal/logger"
)
func Int64CounterGetInstrument(name string, options ...metric_api.Int64CounterOption) (metric_api.Int64Counter, error) {
return regInt64Counter.GetInstrument(name, options...)
}
func Float64CounterGetInstrument(name string, options ...metric_api.Float64CounterOption) (metric_api.Float64Counter, error) {
return regFloat64Counter.GetInstrument(name, options...)
}
// InstrumentReg stores the already registered instruments
//
//nolint:structcheck // generics
type InstrumentReg[T any, O any] struct {
instruments map[string]T
mu sync.Mutex
newInstrument func(name string, options ...O) (T, error)
}
// GetInstrument registers a new instrument, otherwise returns the already created.
func (r *InstrumentReg[T, O]) GetInstrument(name string, options ...O) (T, error) {
var err error
r.mu.Lock()
defer r.mu.Unlock()
instrument, has := r.instruments[name]
if !has {
instrument, err = r.newInstrument(name, options...)
if err != nil {
return instrument, fmt.Errorf("unable to register metric %T %s: %w", r, name, err)
}
r.instruments[name] = instrument
}
return instrument, nil
}
var (
// meter is the default meter
meter metric_api.Meter //nolint:gochecknoglobals // private
// meterOnce is used to init meter
meterOnce sync.Once //nolint:gochecknoglobals // private
// regInt64Counter stores Int64Counters
regInt64Counter *InstrumentReg[metric_api.Int64Counter, metric_api.Int64CounterOption] //nolint:gochecknoglobals // private
// regFloat64Counter stores Float64Counters
regFloat64Counter *InstrumentReg[metric_api.Float64Counter, metric_api.Float64CounterOption] //nolint:gochecknoglobals // private
)
// GetMeter returns the default meter.
// Inits meter and InstrumentRegs (if needed)
func GetMeter(log *slog.Logger) metric_api.Meter {
meterOnce.Do(func() {
exporter, err := prometheus.New()
if err != nil {
log.Error("unable to instantiate prometheus exporter", logger.KeyError, err)
panic(err)
}
provider := metric.NewMeterProvider(metric.WithReader(exporter))
meter = provider.Meter("github.com/pgillich/opentracing-example/internal/middleware", metric_api.WithInstrumentationVersion("0.1"))
regInt64Counter = &InstrumentReg[metric_api.Int64Counter, metric_api.Int64CounterOption]{
instruments: map[string]metric_api.Int64Counter{},
newInstrument: meter.Int64Counter,
}
regFloat64Counter = &InstrumentReg[metric_api.Float64Counter, metric_api.Float64CounterOption]{
instruments: map[string]metric_api.Float64Counter{},
newInstrument: meter.Float64Counter,
}
})
return meter
}
func GetHost(r *http.Request) string {
if r.Host != "" {
return r.Host
}
return r.URL.Host
}