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 APIopen in new window and OpenTelemetry Go Metrics APIopen in new window.

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.devopen in new window.

OptionDescription
WithDSNA data source that specifies Uptrace project credentials. For example, https://<token>@uptrace.dev/<project_id>.
WithServiceNameservice.name resource attribute. For example, myservice.
WithServiceVersionservice.version resource attribute. For example, 1.0.0.
WithDeploymentEnvironmentdeployment.environment resource attribute. For example, production.
WithResourceAttributesAny other resource attributes.
WithResourceDetectorsConfigures additional resource detectors, for example, EC2 detector or GCE detector.
WithResourceResource 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 varDescription
UPTRACE_DSNA data source that is used to connect to uptrace.dev. For example, https://<token>@uptrace.dev/<project_id>.
OTEL_RESOURCE_ATTRIBUTESKey-value pairs to be used as resource attributes. For example, service.name=myservice,service.version=1.0.0.
OTEL_PROPAGATORSPropagators 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.

go get github.com/uptrace/uptrace-go
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))
}
go run main.go
trace: https://uptrace.dev/traces/<trace_id>
  • Step 4. Follow the link to view the trace:

Basic trace

Serverless

AWS Lambda

See OpenTelemetry AWS Lambda Goopen in new window.

Vercel

On Vercelopen in new window, 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 samplingopen in new window:

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 detectorsopen in new window.

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 detectorsopen in new window.

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?

Tutorials:

Last Updated: