Skip to content

Commit c1126f1

Browse files
MrAliaspellaredchalinsvrnm
authored
Add logging to Go getting-started example (#4490)
Co-authored-by: Robert Pająk <[email protected]> Co-authored-by: Patrice Chalin <[email protected]> Co-authored-by: Severin Neumann <[email protected]>
1 parent 5e09ac0 commit c1126f1

File tree

1 file changed

+139
-14
lines changed

1 file changed

+139
-14
lines changed

content/en/docs/languages/go/getting-started.md

+139-14
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@ cSpell:ignore: chan fatalln funcs intn itoa khtml otelhttp rolldice stdouttrace
1111
This page will show you how to get started with OpenTelemetry in Go.
1212

1313
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 %}}
1522

1623
## Prerequisites
1724

1825
Ensure that you have the following installed locally:
1926

20-
- [Go](https://go.dev/)
27+
- [Go](https://go.dev/) 1.22 or greater
2128

2229
## Example application
2330

@@ -135,9 +142,12 @@ import (
135142
"time"
136143

137144
"go.opentelemetry.io/otel"
145+
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
138146
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
139147
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
148+
"go.opentelemetry.io/otel/log/global"
140149
"go.opentelemetry.io/otel/propagation"
150+
"go.opentelemetry.io/otel/sdk/log"
141151
"go.opentelemetry.io/otel/sdk/metric"
142152
"go.opentelemetry.io/otel/sdk/trace"
143153
)
@@ -186,6 +196,15 @@ func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, er
186196
shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown)
187197
otel.SetMeterProvider(meterProvider)
188198

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+
189208
return
190209
}
191210

@@ -224,6 +243,18 @@ func newMeterProvider() (*metric.MeterProvider, error) {
224243
)
225244
return meterProvider, nil
226245
}
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+
}
227258
```
228259
<!-- prettier-ignore-end -->
229260

@@ -318,7 +349,8 @@ func newHTTPHandler() http.Handler {
318349
}
319350

320351
// Register handlers.
321-
handleFunc("/rolldice", rolldice)
352+
handleFunc("/rolldice/", rolldice)
353+
handleFunc("/rolldice/{player}", rolldice)
322354

323355
// Add HTTP instrumentation for the whole server.
324356
handler := otelhttp.NewHandler(mux, "/")
@@ -348,14 +380,23 @@ import (
348380
"net/http"
349381
"strconv"
350382

383+
"go.opentelemetry.io/contrib/bridges/otelslog"
351384
"go.opentelemetry.io/otel"
352385
"go.opentelemetry.io/otel/attribute"
353386
"go.opentelemetry.io/otel/metric"
387+
"go.opentelemetry.io/otel/sdk/instrumentation"
354388
)
355389

390+
const name = "rolldice"
391+
356392
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+
)
359400
rollCnt metric.Int64Counter
360401
)
361402

@@ -375,6 +416,14 @@ func rolldice(w http.ResponseWriter, r *http.Request) {
375416

376417
roll := 1 + rand.Intn(6)
377418

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+
378427
rollValueAttr := attribute.Int("roll.value", roll)
379428
span.SetAttributes(rollValueAttr)
380429
rollCnt.Add(ctx, 1, metric.WithAttributes(rollValueAttr))
@@ -400,11 +449,11 @@ export OTEL_RESOURCE_ATTRIBUTES="service.name=dice,service.version=0.1.0"
400449
go run .
401450
```
402451

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
404453
request to the server, you'll see two spans in the trace emitted to the console.
405454
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.
408457

409458
<details>
410459
<summary>View example output</summary>
@@ -571,7 +620,7 @@ it is a child of the previously mentioned span.
571620
"Key": "http.route",
572621
"Value": {
573622
"Type": "STRING",
574-
"Value": "/rolldice"
623+
"Value": "/rolldice/Alice"
575624
}
576625
},
577626
{
@@ -646,8 +695,83 @@ it is a child of the previously mentioned span.
646695

647696
</details>
648697

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
651775
console output. You'll see the `dice.rolls` metric emitted to the console, with
652776
separate counts for each roll value, as well as the HTTP metrics generated by
653777
the instrumentation library.
@@ -832,7 +956,7 @@ the instrumentation library.
832956
"Key": "http.route",
833957
"Value": {
834958
"Type": "STRING",
835-
"Value": "/rolldice"
959+
"Value": "/rolldice/Alice"
836960
}
837961
},
838962
{
@@ -899,7 +1023,7 @@ the instrumentation library.
8991023
"Key": "http.route",
9001024
"Value": {
9011025
"Type": "STRING",
902-
"Value": "/rolldice"
1026+
"Value": "/rolldice/Alice"
9031027
}
9041028
},
9051029
{
@@ -966,7 +1090,7 @@ the instrumentation library.
9661090
"Key": "http.route",
9671091
"Value": {
9681092
"Type": "STRING",
969-
"Value": "/rolldice"
1093+
"Value": "/rolldice/Alice"
9701094
}
9711095
},
9721096
{
@@ -1041,3 +1165,4 @@ If you'd like to explore a more complex example, take a look at the
10411165

10421166
[traces]: /docs/concepts/signals/traces/
10431167
[metrics]: /docs/concepts/signals/metrics/
1168+
[logs]: /docs/concepts/signals/logs/

0 commit comments

Comments
 (0)