Skip to content

Commit

Permalink
Add logging to Go getting-started example (#4490)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Patrice Chalin <chalin@users.noreply.github.com>
Co-authored-by: Severin Neumann <neumanns@cisco.com>
  • Loading branch information
4 people committed May 16, 2024
1 parent 5e09ac0 commit c1126f1
Showing 1 changed file with 139 additions and 14 deletions.
153 changes: 139 additions & 14 deletions content/en/docs/languages/go/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ cSpell:ignore: chan fatalln funcs intn itoa khtml otelhttp rolldice stdouttrace
This page will show you how to get started with OpenTelemetry in Go.

You will learn how you can instrument a simple application manually, in such a
way that [traces][] and [metrics][] are emitted to the console.
way that [traces][], [metrics][], and [logs][] are emitted to the console.

{{% alert title="Note" %}}

The logs signal is still experimental. Breaking changes may be introduced in
future versions.

{{% /alert %}}

## Prerequisites

Ensure that you have the following installed locally:

- [Go](https://go.dev/)
- [Go](https://go.dev/) 1.22 or greater

## Example application

Expand Down Expand Up @@ -135,9 +142,12 @@ import (
"time"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
"go.opentelemetry.io/otel/log/global"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/log"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/trace"
)
Expand Down Expand Up @@ -186,6 +196,15 @@ func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, er
shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown)
otel.SetMeterProvider(meterProvider)

// Set up logger provider.
loggerProvider, err := newLoggerProvider()
if err != nil {
handleErr(err)
return
}
shutdownFuncs = append(shutdownFuncs, loggerProvider.Shutdown)
global.SetLoggerProvider(loggerProvider)

return
}

Expand Down Expand Up @@ -224,6 +243,18 @@ func newMeterProvider() (*metric.MeterProvider, error) {
)
return meterProvider, nil
}

func newLoggerProvider() (*log.LoggerProvider, error) {
logExporter, err := stdoutlog.New()
if err != nil {
return nil, err
}

loggerProvider := log.NewLoggerProvider(
log.WithProcessor(log.NewBatchProcessor(logExporter)),
)
return loggerProvider, nil
}
```
<!-- prettier-ignore-end -->

Expand Down Expand Up @@ -318,7 +349,8 @@ func newHTTPHandler() http.Handler {
}

// Register handlers.
handleFunc("/rolldice", rolldice)
handleFunc("/rolldice/", rolldice)
handleFunc("/rolldice/{player}", rolldice)

// Add HTTP instrumentation for the whole server.
handler := otelhttp.NewHandler(mux, "/")
Expand Down Expand Up @@ -348,14 +380,23 @@ import (
"net/http"
"strconv"

"go.opentelemetry.io/contrib/bridges/otelslog"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk/instrumentation"
)

const name = "rolldice"

var (
tracer = otel.Tracer("rolldice")
meter = otel.Meter("rolldice")
tracer = otel.Tracer(name)
meter = otel.Meter(name)
logger = otelslog.NewLogger(
otelslog.WithInstrumentationScope(instrumentation.Scope{
Name: name,
}),
)
rollCnt metric.Int64Counter
)

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

roll := 1 + rand.Intn(6)

var msg string
if player := r.PathValue("player"); player != "" {
msg = fmt.Sprintf("%s is rolling the dice", player)
} else {
msg = "Anonymous player is rolling the dice"
}
logger.InfoContext(ctx, msg, "result", roll)

rollValueAttr := attribute.Int("roll.value", roll)
span.SetAttributes(rollValueAttr)
rollCnt.Add(ctx, 1, metric.WithAttributes(rollValueAttr))
Expand All @@ -400,11 +449,11 @@ export OTEL_RESOURCE_ATTRIBUTES="service.name=dice,service.version=0.1.0"
go run .
```

Open <http://localhost:8080/rolldice> in your web browser. When you send a
Open <http://localhost:8080/rolldice/Alice> in your web browser. When you send a
request to the server, you'll see two spans in the trace emitted to the console.
The span generated by the instrumentation library tracks the lifetime of a
request to the `/rolldice` route. The span called `roll` is created manually and
it is a child of the previously mentioned span.
request to the `/rolldice/{player}` route. The span called `roll` is created
manually and it is a child of the previously mentioned span.

<details>
<summary>View example output</summary>
Expand Down Expand Up @@ -571,7 +620,7 @@ it is a child of the previously mentioned span.
"Key": "http.route",
"Value": {
"Type": "STRING",
"Value": "/rolldice"
"Value": "/rolldice/Alice"
}
},
{
Expand Down Expand Up @@ -646,8 +695,83 @@ it is a child of the previously mentioned span.

</details>

Refresh the <http://localhost:8080/rolldice> page a few times, and then either
wait for a little bit or terminate the app and you'll see metrics as in the
Along with the trace, log messages are emitted to the console.

<details>
<summary>View example output</summary>

```json
{
"Timestamp": "2023-09-25T12:42:05.177136776+02:00",
"ObservedTimestamp": "2023-09-25T12:42:06.809396011+02:00",
"Severity": 9,
"SeverityText": "",
"Body": {
"Type": "String",
"Value": "Alice is rolling the dice"
},
"Attributes": [
{
"Key": "result",
"Value": {
"Type": "Int64",
"Value": 6
}
}
],
"TraceID": "829fb7ceb787403c96eac3caf285c965",
"SpanID": "8b6b408b6c1a35e5",
"TraceFlags": "01",
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "dice"
}
},
{
"Key": "service.version",
"Value": {
"Type": "STRING",
"Value": "0.1.0"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.19.0-rc.1"
}
}
],
"Scope": {
"Name": "rolldice",
"Version": "",
"SchemaURL": ""
},
"DroppedAttributes": 0
}
```

</details>

Refresh the <http://localhost:8080/rolldice/Alice> page a few times, and then
either wait a little or terminate the app and you'll see metrics as in the
console output. You'll see the `dice.rolls` metric emitted to the console, with
separate counts for each roll value, as well as the HTTP metrics generated by
the instrumentation library.
Expand Down Expand Up @@ -832,7 +956,7 @@ the instrumentation library.
"Key": "http.route",
"Value": {
"Type": "STRING",
"Value": "/rolldice"
"Value": "/rolldice/Alice"
}
},
{
Expand Down Expand Up @@ -899,7 +1023,7 @@ the instrumentation library.
"Key": "http.route",
"Value": {
"Type": "STRING",
"Value": "/rolldice"
"Value": "/rolldice/Alice"
}
},
{
Expand Down Expand Up @@ -966,7 +1090,7 @@ the instrumentation library.
"Key": "http.route",
"Value": {
"Type": "STRING",
"Value": "/rolldice"
"Value": "/rolldice/Alice"
}
},
{
Expand Down Expand Up @@ -1041,3 +1165,4 @@ If you'd like to explore a more complex example, take a look at the

[traces]: /docs/concepts/signals/traces/
[metrics]: /docs/concepts/signals/metrics/
[logs]: /docs/concepts/signals/logs/

0 comments on commit c1126f1

Please sign in to comment.