@@ -19,29 +19,22 @@ import (
19
19
20
20
"go.opentelemetry.io/otel"
21
21
"go.opentelemetry.io/otel/attribute"
22
+ "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
22
23
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
24
+ "go.opentelemetry.io/otel/metric"
23
25
"go.opentelemetry.io/otel/propagation"
26
+ sdkmetric "go.opentelemetry.io/otel/sdk/metric"
24
27
"go.opentelemetry.io/otel/sdk/resource"
25
28
sdktrace "go.opentelemetry.io/otel/sdk/trace"
26
29
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
27
30
"go.opentelemetry.io/otel/trace"
28
31
)
29
32
30
- // Initializes an OTLP exporter, and configures the corresponding trace and
31
- // metric providers.
32
- func initProvider () (func (context.Context ) error , error ) {
33
- ctx := context .Background ()
34
-
35
- res , err := resource .New (ctx ,
36
- resource .WithAttributes (
37
- // the service name used to display traces in backends
38
- semconv .ServiceName ("test-service" ),
39
- ),
40
- )
41
- if err != nil {
42
- return nil , fmt .Errorf ("failed to create resource: %w" , err )
43
- }
33
+ var serviceName = semconv .ServiceNameKey .String ("test-service" )
44
34
35
+ // Initialize a gRPC connection to be used by both the tracer and meter
36
+ // providers.
37
+ func initConn () (* grpc.ClientConn , error ) {
45
38
// It connects the OpenTelemetry Collector through local gRPC connection.
46
39
// You may replace `localhost:4317` with your endpoint.
47
40
conn , err := grpc .NewClient ("localhost:4317" ,
@@ -52,8 +45,13 @@ func initProvider() (func(context.Context) error, error) {
52
45
return nil , fmt .Errorf ("failed to create gRPC connection to collector: %w" , err )
53
46
}
54
47
48
+ return conn , err
49
+ }
50
+
51
+ // Initializes an OTLP exporter, and configures the corresponding trace provider.
52
+ func initTracerProvider (ctx context.Context , res * resource.Resource , conn * grpc.ClientConn ) (func (context.Context ) error , error ) {
55
53
// Set up a trace exporter
56
- traceExporter , err := otlptracegrpc .New (context . Background () , otlptracegrpc .WithGRPCConn (conn ))
54
+ traceExporter , err := otlptracegrpc .New (ctx , otlptracegrpc .WithGRPCConn (conn ))
57
55
if err != nil {
58
56
return nil , fmt .Errorf ("failed to create trace exporter: %w" , err )
59
57
}
@@ -68,30 +66,72 @@ func initProvider() (func(context.Context) error, error) {
68
66
)
69
67
otel .SetTracerProvider (tracerProvider )
70
68
71
- // set global propagator to tracecontext (the default is no-op).
69
+ // Set global propagator to tracecontext (the default is no-op).
72
70
otel .SetTextMapPropagator (propagation.TraceContext {})
73
71
74
72
// Shutdown will flush any remaining spans and shut down the exporter.
75
73
return tracerProvider .Shutdown , nil
76
74
}
77
75
76
+ // Initializes an OTLP exporter, and configures the corresponding meter provider.
77
+ func initMeterProvider (ctx context.Context , res * resource.Resource , conn * grpc.ClientConn ) (func (context.Context ) error , error ) {
78
+ metricExporter , err := otlpmetricgrpc .New (ctx , otlpmetricgrpc .WithGRPCConn (conn ))
79
+ if err != nil {
80
+ return nil , fmt .Errorf ("failed to create metrics exporter: %w" , err )
81
+ }
82
+
83
+ meterProvider := sdkmetric .NewMeterProvider (
84
+ sdkmetric .WithReader (sdkmetric .NewPeriodicReader (metricExporter )),
85
+ sdkmetric .WithResource (res ),
86
+ )
87
+ otel .SetMeterProvider (meterProvider )
88
+
89
+ return meterProvider .Shutdown , nil
90
+ }
91
+
78
92
func main () {
79
93
log .Printf ("Waiting for connection..." )
80
94
81
95
ctx , cancel := signal .NotifyContext (context .Background (), os .Interrupt )
82
96
defer cancel ()
83
97
84
- shutdown , err := initProvider ()
98
+ conn , err := initConn ()
99
+ if err != nil {
100
+ log .Fatal (err )
101
+ }
102
+
103
+ res , err := resource .New (ctx ,
104
+ resource .WithAttributes (
105
+ // The service name used to display traces in backends
106
+ serviceName ,
107
+ ),
108
+ )
109
+ if err != nil {
110
+ log .Fatal (err )
111
+ }
112
+
113
+ shutdownTracerProvider , err := initTracerProvider (ctx , res , conn )
85
114
if err != nil {
86
115
log .Fatal (err )
87
116
}
88
117
defer func () {
89
- if err := shutdown (ctx ); err != nil {
90
- log .Fatal ("failed to shutdown TracerProvider: %w" , err )
118
+ if err := shutdownTracerProvider (ctx ); err != nil {
119
+ log .Fatalf ("failed to shutdown TracerProvider: %s" , err )
120
+ }
121
+ }()
122
+
123
+ shutdownMeterProvider , err := initMeterProvider (ctx , res , conn )
124
+ if err != nil {
125
+ log .Fatal (err )
126
+ }
127
+ defer func () {
128
+ if err := shutdownMeterProvider (ctx ); err != nil {
129
+ log .Fatalf ("failed to shutdown MeterProvider: %s" , err )
91
130
}
92
131
}()
93
132
94
133
tracer := otel .Tracer ("test-tracer" )
134
+ meter := otel .Meter ("test-meter" )
95
135
96
136
// Attributes represent additional key-value descriptors that can be bound
97
137
// to a metric observer or recorder.
@@ -101,14 +141,20 @@ func main() {
101
141
attribute .String ("attrC" , "vanilla" ),
102
142
}
103
143
104
- // work begins
144
+ runCount , err := meter .Int64Counter ("run" , metric .WithDescription ("The number of times the iteration ran" ))
145
+ if err != nil {
146
+ log .Fatal (err )
147
+ }
148
+
149
+ // Work begins
105
150
ctx , span := tracer .Start (
106
151
ctx ,
107
152
"CollectorExporter-Example" ,
108
153
trace .WithAttributes (commonAttrs ... ))
109
154
defer span .End ()
110
155
for i := 0 ; i < 10 ; i ++ {
111
156
_ , iSpan := tracer .Start (ctx , fmt .Sprintf ("Sample-%d" , i ))
157
+ runCount .Add (ctx , 1 , metric .WithAttributes (commonAttrs ... ))
112
158
log .Printf ("Doing really hard work (%d / 10)\n " , i + 1 )
113
159
114
160
<- time .After (time .Second )
0 commit comments