OpenTelemetry Go distro for Uptrace
This document explains how to configure OpenTelemetry Go SDK to export spans and metrics to Uptrace using OTLP/gRPC.
To learn about OpenTelemetry API, see OpenTelemetry Go Tracing API and OpenTelemetry Go Metrics API.
OpenTelemetry Go
To install uptrace-go:
go get github.com/uptrace/uptrace-go
Configuration
You can configure Uptrace client using a DSN (Data Source Name, e.g. https://<token>@uptrace.dev/<project_id>
) from the project settings page.
import "github.com/uptrace/uptrace-go/uptrace"
uptrace.ConfigureOpentelemetry(
// copy your project DSN here or use UPTRACE_DSN env var
//uptrace.WithDSN("https://<token>@uptrace.dev/<project_id>"),
uptrace.WithServiceName("myservice"),
uptrace.WithServiceVersion("v1.0.0"),
uptrace.WithDeploymentEnvironment("production"),
)
You can find the full list of available options at pkg.go.dev.
Option | Description |
---|---|
WithDSN | A data source that specifies Uptrace project credentials. For example, https://<token>@uptrace.dev/<project_id> . |
WithServiceName | service.name resource attribute. For example, myservice . |
WithServiceVersion | service.version resource attribute. For example, 1.0.0 . |
WithDeploymentEnvironment | deployment.environment resource attribute. For example, production . |
WithResourceAttributes | Any other resource attributes. |
WithResourceDetectors | Configures additional resource detectors, for example, EC2 detector or GCE detector. |
WithResource | Resource contains attributes representing an entity that produces telemetry. Resource attributes are copied to all spans and events. |
You can also use environment variables to configure the client:
Env var | Description |
---|---|
UPTRACE_DSN | A data source that is used to connect to uptrace.dev. For example, https://<token>@uptrace.dev/<project_id> . |
OTEL_RESOURCE_ATTRIBUTES | Key-value pairs to be used as resource attributes. For example, service.name=myservice,service.version=1.0.0 . |
OTEL_PROPAGATORS | Propagators to be used as a comma separated list. The default is tracecontext,baggage . |
Getting started
Install OpenTelemetry distro, generate your first trace, and click the link in your terminal to open Uptrace. All it takes is a minute of your time.
Step 0. Create an Uptrace project to obtain a DSN (connection string), for example,
https://<token>@uptrace.dev/<project_id>
.Step 1. Install uptrace-go:
go get github.com/uptrace/uptrace-go
- Step 2. Copy the code to
main.go
replacing the<dsn>
:
package main
import (
"context"
"errors"
"fmt"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"github.com/uptrace/uptrace-go/uptrace"
)
func main() {
ctx := context.Background()
// Configure OpenTelemetry with sensible defaults.
uptrace.ConfigureOpentelemetry(
// copy your project DSN here or use UPTRACE_DSN env var
//uptrace.WithDSN("https://<token>@uptrace.dev/<project_id>"),
uptrace.WithServiceName("myservice"),
uptrace.WithServiceVersion("1.0.0"),
)
// Send buffered spans and free resources.
defer uptrace.Shutdown(ctx)
// Create a tracer. Usually, tracer is a global variable.
tracer := otel.Tracer("app_or_package_name")
// Create a root span (a trace) to measure some operation.
ctx, main := tracer.Start(ctx, "main-operation")
// End the span when the operation we are measuring is done.
defer main.End()
// We pass the main (parent) span in the ctx so we can reconstruct a trace later.
_, child1 := tracer.Start(ctx, "child1-of-main")
child1.SetAttributes(attribute.String("key1", "value1"))
child1.RecordError(errors.New("error1"))
child1.End()
_, child2 := tracer.Start(ctx, "child2-of-main")
child2.SetAttributes(attribute.Int("key2", 42), attribute.Float64("key3", 123.456))
child2.End()
fmt.Printf("trace: %s\n", uptrace.TraceURL(main))
}
- Step 3. Run the example to get a link for the generated trace:
go run main.go
trace: https://uptrace.dev/traces/<trace_id>
- Step 4. Follow the link to view the trace:
Serverless
AWS Lambda
See OpenTelemetry AWS Lambda Go.
Vercel
On Vercel, you need to configure OpenTelemetry in the init
function and ForceFlush
spans when the Vercel handler exits.
package handler
import (
"fmt"
"net/http"
"go.opentelemetry.io/otel"
"github.com/uptrace/uptrace-go/uptrace"
)
var tracer = otel.Tracer("app_or_package_name")
func init() {
uptrace.ConfigureOpentelemetry(...)
}
func Handler(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
// Flush buffered spans.
defer uptrace.ForceFlush(ctx)
ctx, span := tracer.Start(ctx, "handler-name")
defer span.End()
fmt.Fprintf(w, "<h1>Hello from Go!</h1>")
}
Sampling
You can reduce the number of created (sampled) spans by configuring head-based sampling:
import "go.opentelemetry.io/contrib/samplers/probability/consistent"
sampler := consistent.ParentProbabilityBased(
consistent.ProbabilityBased(0.5), // sample 50% of traces
)
uptrace.ConfigureOpentelemetry(
uptrace.WithTraceSampler(sampler),
// Other options
)
By default, uptrace-go samples all spans.
Resource detectors
By default, uptrace-go uses host and environment resource detectors, but you can configure it to use additional detectors, for example:
import (
"github.com/uptrace/uptrace-go/uptrace"
"go.opentelemetry.io/contrib/detectors/aws/ec2"
)
uptrace.ConfigureOpentelemetry(
// copy your project DSN here or use UPTRACE_DSN env var
//uptrace.WithDSN("https://<token>@uptrace.dev/<project_id>"),
uptrace.WithServiceName("myservice"),
uptrace.WithServiceVersion("1.0.0"),
uptrace.WithResourceDetectors(ec2.NewResourceDetector()),
)
AWS
See AWS detectors.
EC2
import "go.opentelemetry.io/contrib/detectors/aws/ec2"
ec2ResourceDetector := ec2.NewResourceDetector()
ECS
import "go.opentelemetry.io/contrib/detectors/aws/ecs"
ecsResourceDetector := ecs.NewResourceDetector()
EKS
import "go.opentelemetry.io/contrib/detectors/aws/eks"
eksResourceDetector := eks.NewResourceDetector()
Google Cloud
See GCP detectors.
Cloud Run
import "go.opentelemetry.io/contrib/detectors/gcp"
cloudRunResourceDetector := gcp.NewCloudRun()
GCE
import "go.opentelemetry.io/contrib/detectors/gcp"
gceResourceDetector := gcp.GCE{}
GKE
import "go.opentelemetry.io/contrib/detectors/gcp"
gkeResourceDetector := gcp.GKE{}
What's next?
- Look for instrumentations, for example, net/http or gRPC.
- Learn about OpenTelemetry Tracing API and Metrics API to create your own instrumentations.
Tutorials: