-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
metrics.go
138 lines (113 loc) · 3.81 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2023, Roel Schut. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package telemetry
import (
"github.com/go-pogo/env"
"github.com/go-pogo/errors"
"github.com/go-pogo/rawconv"
"github.com/prometheus/client_golang/prometheus"
runtimemetrics "go.opentelemetry.io/contrib/instrumentation/runtime"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
otelprom "go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
"golang.org/x/net/context"
"time"
)
var _ env.Environment = (*MeterProviderConfig)(nil)
// MeterProviderConfig holds the configuration for the MeterProviderBuilder.
// These values may be set using any external source, such as environment
// variables, config files, etc.
type MeterProviderConfig struct {
Enabled bool `env:"OTEL_METRIC_ENABLED" default:"true"`
// OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
// OTEL_EXPORTER_OTLP_METRICS_HEADERS
// OTEL_EXPORTER_OTLP_METRICS_TIMEOUT
// ExportInterval is the time interval (in milliseconds) between the start
// of two export attempts.
ExportInterval int `env:"OTEL_METRIC_EXPORT_INTERVAL" default:"60000"`
// ExportTimeout is the maximum allowed time (in milliseconds) to export
// data.
ExportTimeout int `env:"OTEL_METRIC_EXPORT_TIMEOUT" default:"30000"`
}
func (c MeterProviderConfig) ExportIntervalDuration() time.Duration {
return time.Duration(c.ExportInterval) * time.Millisecond
}
func (c MeterProviderConfig) ExportTimeoutDuration() time.Duration {
return time.Duration(c.ExportTimeout) * time.Millisecond
}
func (c MeterProviderConfig) Environ() (env.Map, error) {
return env.Map{
"OTEL_METRIC_EXPORT_INTERVAL": rawconv.ValueFromInt(c.ExportInterval),
"OTEL_METRIC_EXPORT_TIMEOUT": rawconv.ValueFromInt(c.ExportTimeout),
}, nil
}
type MeterProviderBuilder struct {
*MeterProviderConfig
opts []metric.Option
errs errList
DisableRuntimeMetrics bool
SetGlobal bool
}
func NewMeterProviderBuilder(conf *MeterProviderConfig) *MeterProviderBuilder {
if conf == nil {
conf = new(MeterProviderConfig)
}
return &MeterProviderBuilder{MeterProviderConfig: conf}
}
func (met *MeterProviderBuilder) With(opts ...metric.Option) *MeterProviderBuilder {
if met.opts == nil {
met.opts = opts
return met
}
met.opts = append(met.opts, opts...)
return met
}
func (met *MeterProviderBuilder) WithReader(r metric.Reader, views ...metric.View) *MeterProviderBuilder {
met.With(metric.WithReader(r))
if len(views) > 0 {
met.With(metric.WithView(views...))
}
return met
}
func (met *MeterProviderBuilder) WithGrpcExporter(opts ...otlpmetricgrpc.Option) *MeterProviderBuilder {
exp, err := otlpmetricgrpc.New(context.Background(), opts...)
if err != nil {
met.errs.append(errors.WithStack(err))
return met
}
return met.With(metric.WithReader(metric.NewPeriodicReader(exp)))
}
func (met *MeterProviderBuilder) WithPrometheusExporter(reg prometheus.Registerer, views ...metric.View) *MeterProviderBuilder {
if reg == nil {
return met
}
exp, err := otelprom.New(otelprom.WithRegisterer(reg))
if err != nil {
met.errs.append(errors.WithStack(err))
return met
}
return met.WithReader(exp, views...)
}
func (met *MeterProviderBuilder) Build(opts ...metric.Option) (*metric.MeterProvider, error) {
if err := met.errs.join(); err != nil {
return nil, err
}
if met.MeterProviderConfig != nil {
if err := env.Load(met.MeterProviderConfig); err != nil {
return nil, err
}
}
opts = append(met.opts, opts...)
prov := metric.NewMeterProvider(opts...)
if !met.DisableRuntimeMetrics {
if err := runtimemetrics.Start(runtimemetrics.WithMeterProvider(prov)); err != nil {
return prov, errors.WithStack(err)
}
}
if met.SetGlobal {
otel.SetMeterProvider(prov)
}
return prov, nil
}