@@ -11,13 +11,20 @@ cSpell:ignore: chan fatalln funcs intn itoa khtml otelhttp rolldice stdouttrace
11
11
This page will show you how to get started with OpenTelemetry in Go.
12
12
13
13
You will learn how you can instrument a simple application manually, in such a
14
- way that [ traces] [ ] and [ metrics] [ ] are emitted to the console.
14
+ way that [ traces] [ ] , [ metrics] [ ] , and [ logs] [ ] are emitted to the console.
15
+
16
+ {{% alert title="Note" %}}
17
+
18
+ The logs signal is still experimental. Breaking changes may be introduced in
19
+ future versions.
20
+
21
+ {{% /alert %}}
15
22
16
23
## Prerequisites
17
24
18
25
Ensure that you have the following installed locally:
19
26
20
- - [ Go] ( https://go.dev/ )
27
+ - [ Go] ( https://go.dev/ ) 1.22 or greater
21
28
22
29
## Example application
23
30
@@ -135,9 +142,12 @@ import (
135
142
" time"
136
143
137
144
" go.opentelemetry.io/otel"
145
+ " go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
138
146
" go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
139
147
" go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
148
+ " go.opentelemetry.io/otel/log/global"
140
149
" go.opentelemetry.io/otel/propagation"
150
+ " go.opentelemetry.io/otel/sdk/log"
141
151
" go.opentelemetry.io/otel/sdk/metric"
142
152
" go.opentelemetry.io/otel/sdk/trace"
143
153
)
@@ -186,6 +196,15 @@ func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, er
186
196
shutdownFuncs = append (shutdownFuncs, meterProvider.Shutdown )
187
197
otel.SetMeterProvider (meterProvider)
188
198
199
+ // Set up logger provider.
200
+ loggerProvider , err := newLoggerProvider ()
201
+ if err != nil {
202
+ handleErr (err)
203
+ return
204
+ }
205
+ shutdownFuncs = append (shutdownFuncs, loggerProvider.Shutdown )
206
+ global.SetLoggerProvider (loggerProvider)
207
+
189
208
return
190
209
}
191
210
@@ -224,6 +243,18 @@ func newMeterProvider() (*metric.MeterProvider, error) {
224
243
)
225
244
return meterProvider, nil
226
245
}
246
+
247
+ func newLoggerProvider () (*log .LoggerProvider , error ) {
248
+ logExporter , err := stdoutlog.New ()
249
+ if err != nil {
250
+ return nil , err
251
+ }
252
+
253
+ loggerProvider := log.NewLoggerProvider (
254
+ log.WithProcessor (log.NewBatchProcessor (logExporter)),
255
+ )
256
+ return loggerProvider, nil
257
+ }
227
258
```
228
259
<!-- prettier-ignore-end -->
229
260
@@ -318,7 +349,8 @@ func newHTTPHandler() http.Handler {
318
349
}
319
350
320
351
// Register handlers.
321
- handleFunc (" /rolldice" , rolldice)
352
+ handleFunc (" /rolldice/" , rolldice)
353
+ handleFunc (" /rolldice/{player}" , rolldice)
322
354
323
355
// Add HTTP instrumentation for the whole server.
324
356
handler := otelhttp.NewHandler (mux, " /" )
@@ -348,14 +380,23 @@ import (
348
380
" net/http"
349
381
" strconv"
350
382
383
+ " go.opentelemetry.io/contrib/bridges/otelslog"
351
384
" go.opentelemetry.io/otel"
352
385
" go.opentelemetry.io/otel/attribute"
353
386
" go.opentelemetry.io/otel/metric"
387
+ " go.opentelemetry.io/otel/sdk/instrumentation"
354
388
)
355
389
390
+ const name = " rolldice"
391
+
356
392
var (
357
- tracer = otel.Tracer (" rolldice" )
358
- meter = otel.Meter (" rolldice" )
393
+ tracer = otel.Tracer (name)
394
+ meter = otel.Meter (name)
395
+ logger = otelslog.NewLogger (
396
+ otelslog.WithInstrumentationScope (instrumentation.Scope {
397
+ Name : name,
398
+ }),
399
+ )
359
400
rollCnt metric.Int64Counter
360
401
)
361
402
@@ -375,6 +416,14 @@ func rolldice(w http.ResponseWriter, r *http.Request) {
375
416
376
417
roll := 1 + rand.Intn (6 )
377
418
419
+ var msg string
420
+ if player := r.PathValue (" player" ); player != " " {
421
+ msg = fmt.Sprintf (" %s is rolling the dice" , player)
422
+ } else {
423
+ msg = " Anonymous player is rolling the dice"
424
+ }
425
+ logger.InfoContext (ctx, msg, " result" , roll)
426
+
378
427
rollValueAttr := attribute.Int (" roll.value" , roll)
379
428
span.SetAttributes (rollValueAttr)
380
429
rollCnt.Add (ctx, 1 , metric.WithAttributes (rollValueAttr))
@@ -400,11 +449,11 @@ export OTEL_RESOURCE_ATTRIBUTES="service.name=dice,service.version=0.1.0"
400
449
go run .
401
450
```
402
451
403
- Open < http://localhost:8080/rolldice > in your web browser. When you send a
452
+ Open < http://localhost:8080/rolldice/Alice > in your web browser. When you send a
404
453
request to the server, you'll see two spans in the trace emitted to the console.
405
454
The span generated by the instrumentation library tracks the lifetime of a
406
- request to the ` /rolldice ` route. The span called ` roll ` is created manually and
407
- it is a child of the previously mentioned span.
455
+ request to the ` /rolldice/{player} ` route. The span called ` roll ` is created
456
+ manually and it is a child of the previously mentioned span.
408
457
409
458
<details >
410
459
<summary >View example output</summary >
@@ -571,7 +620,7 @@ it is a child of the previously mentioned span.
571
620
"Key" : " http.route" ,
572
621
"Value" : {
573
622
"Type" : " STRING" ,
574
- "Value" : " /rolldice"
623
+ "Value" : " /rolldice/Alice "
575
624
}
576
625
},
577
626
{
@@ -646,8 +695,83 @@ it is a child of the previously mentioned span.
646
695
647
696
</details >
648
697
649
- Refresh the < http://localhost:8080/rolldice > page a few times, and then either
650
- wait for a little bit or terminate the app and you'll see metrics as in the
698
+ Along with the trace, log messages are emitted to the console.
699
+
700
+ <details >
701
+ <summary >View example output</summary >
702
+
703
+ ``` json
704
+ {
705
+ "Timestamp" : " 2023-09-25T12:42:05.177136776+02:00" ,
706
+ "ObservedTimestamp" : " 2023-09-25T12:42:06.809396011+02:00" ,
707
+ "Severity" : 9 ,
708
+ "SeverityText" : " " ,
709
+ "Body" : {
710
+ "Type" : " String" ,
711
+ "Value" : " Alice is rolling the dice"
712
+ },
713
+ "Attributes" : [
714
+ {
715
+ "Key" : " result" ,
716
+ "Value" : {
717
+ "Type" : " Int64" ,
718
+ "Value" : 6
719
+ }
720
+ }
721
+ ],
722
+ "TraceID" : " 829fb7ceb787403c96eac3caf285c965" ,
723
+ "SpanID" : " 8b6b408b6c1a35e5" ,
724
+ "TraceFlags" : " 01" ,
725
+ "Resource" : [
726
+ {
727
+ "Key" : " service.name" ,
728
+ "Value" : {
729
+ "Type" : " STRING" ,
730
+ "Value" : " dice"
731
+ }
732
+ },
733
+ {
734
+ "Key" : " service.version" ,
735
+ "Value" : {
736
+ "Type" : " STRING" ,
737
+ "Value" : " 0.1.0"
738
+ }
739
+ },
740
+ {
741
+ "Key" : " telemetry.sdk.language" ,
742
+ "Value" : {
743
+ "Type" : " STRING" ,
744
+ "Value" : " go"
745
+ }
746
+ },
747
+ {
748
+ "Key" : " telemetry.sdk.name" ,
749
+ "Value" : {
750
+ "Type" : " STRING" ,
751
+ "Value" : " opentelemetry"
752
+ }
753
+ },
754
+ {
755
+ "Key" : " telemetry.sdk.version" ,
756
+ "Value" : {
757
+ "Type" : " STRING" ,
758
+ "Value" : " 1.19.0-rc.1"
759
+ }
760
+ }
761
+ ],
762
+ "Scope" : {
763
+ "Name" : " rolldice" ,
764
+ "Version" : " " ,
765
+ "SchemaURL" : " "
766
+ },
767
+ "DroppedAttributes" : 0
768
+ }
769
+ ```
770
+
771
+ </details >
772
+
773
+ Refresh the < http://localhost:8080/rolldice/Alice > page a few times, and then
774
+ either wait a little or terminate the app and you'll see metrics as in the
651
775
console output. You'll see the ` dice.rolls ` metric emitted to the console, with
652
776
separate counts for each roll value, as well as the HTTP metrics generated by
653
777
the instrumentation library.
@@ -832,7 +956,7 @@ the instrumentation library.
832
956
"Key" : " http.route" ,
833
957
"Value" : {
834
958
"Type" : " STRING" ,
835
- "Value" : " /rolldice"
959
+ "Value" : " /rolldice/Alice "
836
960
}
837
961
},
838
962
{
@@ -899,7 +1023,7 @@ the instrumentation library.
899
1023
"Key" : " http.route" ,
900
1024
"Value" : {
901
1025
"Type" : " STRING" ,
902
- "Value" : " /rolldice"
1026
+ "Value" : " /rolldice/Alice "
903
1027
}
904
1028
},
905
1029
{
@@ -966,7 +1090,7 @@ the instrumentation library.
966
1090
"Key" : " http.route" ,
967
1091
"Value" : {
968
1092
"Type" : " STRING" ,
969
- "Value" : " /rolldice"
1093
+ "Value" : " /rolldice/Alice "
970
1094
}
971
1095
},
972
1096
{
@@ -1041,3 +1165,4 @@ If you'd like to explore a more complex example, take a look at the
1041
1165
1042
1166
[ traces ] : /docs/concepts/signals/traces/
1043
1167
[ metrics ] : /docs/concepts/signals/metrics/
1168
+ [ logs ] : /docs/concepts/signals/logs/
0 commit comments