@@ -15,6 +15,7 @@ import (
15
15
"github.com/prometheus/client_golang/prometheus"
16
16
"github.com/prometheus/client_golang/prometheus/promhttp"
17
17
18
+ prometheusbridge "go.opentelemetry.io/contrib/bridges/prometheus"
18
19
"go.opentelemetry.io/otel"
19
20
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
20
21
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
@@ -71,10 +72,24 @@ func RegisterMetricReader(name string, factory func(context.Context) (metric.Rea
71
72
must (metricsSignal .registry .store (name , factory ))
72
73
}
73
74
75
+ func RegisterMetricProducer (name string , factory func (context.Context ) (metric.Producer , error )) {
76
+ must (metricsProducers .registry .store (name , factory ))
77
+ }
78
+
74
79
var metricsSignal = newSignal [metric.Reader ]("OTEL_METRICS_EXPORTER" )
80
+ var metricsProducers = newProducerRegistry ("OTEL_METRICS_PRODUCERS" )
75
81
76
82
func init () {
77
83
RegisterMetricReader ("otlp" , func (ctx context.Context ) (metric.Reader , error ) {
84
+ producer , err := metricsProducers .create (ctx )
85
+ if err != nil {
86
+ return nil , err
87
+ }
88
+ readerOpts := []metric.PeriodicReaderOption {}
89
+ if producer != nil {
90
+ readerOpts = append (readerOpts , metric .WithProducer (producer ))
91
+ }
92
+
78
93
proto := os .Getenv (otelExporterOTLPProtoEnvKey )
79
94
if proto == "" {
80
95
proto = "http/protobuf"
@@ -86,23 +101,32 @@ func init() {
86
101
if err != nil {
87
102
return nil , err
88
103
}
89
- return metric .NewPeriodicReader (r ), nil
104
+ return metric .NewPeriodicReader (r , readerOpts ... ), nil
90
105
case "http/protobuf" :
91
106
r , err := otlpmetrichttp .New (ctx )
92
107
if err != nil {
93
108
return nil , err
94
109
}
95
- return metric .NewPeriodicReader (r ), nil
110
+ return metric .NewPeriodicReader (r , readerOpts ... ), nil
96
111
default :
97
112
return nil , errInvalidOTLPProtocol
98
113
}
99
114
})
100
115
RegisterMetricReader ("console" , func (ctx context.Context ) (metric.Reader , error ) {
116
+ producer , err := metricsProducers .create (ctx )
117
+ if err != nil {
118
+ return nil , err
119
+ }
120
+ readerOpts := []metric.PeriodicReaderOption {}
121
+ if producer != nil {
122
+ readerOpts = append (readerOpts , metric .WithProducer (producer ))
123
+ }
124
+
101
125
r , err := stdoutmetric .New ()
102
126
if err != nil {
103
127
return nil , err
104
128
}
105
- return metric .NewPeriodicReader (r ), nil
129
+ return metric .NewPeriodicReader (r , readerOpts ... ), nil
106
130
})
107
131
RegisterMetricReader ("none" , func (ctx context.Context ) (metric.Reader , error ) {
108
132
return newNoopMetricReader (), nil
@@ -148,6 +172,10 @@ func init() {
148
172
149
173
return readerWithServer {lis .Addr (), reader , & server }, nil
150
174
})
175
+
176
+ RegisterMetricProducer ("prometheus" , func (ctx context.Context ) (metric.Producer , error ) {
177
+ return prometheusbridge .NewMetricProducer (), nil
178
+ })
151
179
}
152
180
153
181
type readerWithServer struct {
@@ -170,3 +198,26 @@ func getenv(key, fallback string) string {
170
198
}
171
199
return result
172
200
}
201
+
202
+ type producerRegistry struct {
203
+ envKey string
204
+ registry * registry [metric.Producer ]
205
+ }
206
+
207
+ func newProducerRegistry (envKey string ) producerRegistry {
208
+ return producerRegistry {
209
+ envKey : envKey ,
210
+ registry : & registry [metric.Producer ]{
211
+ names : make (map [string ]func (context.Context ) (metric.Producer , error )),
212
+ },
213
+ }
214
+ }
215
+
216
+ func (pr producerRegistry ) create (ctx context.Context ) (metric.Producer , error ) {
217
+ expType := os .Getenv (pr .envKey )
218
+ if expType == "" {
219
+ return nil , nil
220
+ }
221
+
222
+ return pr .registry .load (ctx , expType )
223
+ }
0 commit comments