From 245f13baaccd2cfb729b5bbc074c3b72b72a7f45 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Thu, 23 Dec 2021 09:18:08 -0800 Subject: [PATCH] Add section in docs for initializing a tracer (#2481) * Add section in docs for initializing a tracer * Apply suggestions from code review Co-authored-by: Anthony Mirabella * Change weird incomplete sentence * update some of the bullets to be a tad less opinionated * Rename section so it's open to different ways to acquire a tracer * Remove guidance as it is orthogonal * Apply suggestions from code review Co-authored-by: Tyler Yahn Co-authored-by: Anthony Mirabella Co-authored-by: Tyler Yahn --- website_docs/manual.md | 76 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/website_docs/manual.md b/website_docs/manual.md index 2b17e075a..825a68f46 100644 --- a/website_docs/manual.md +++ b/website_docs/manual.md @@ -7,9 +7,83 @@ aliases: [/docs/instrumentation/go/instrumentation, /docs/instrumentation/go/man Instrumentation is the process of adding observability code to your application. There are two general types of instrumentation - automatic, and manual - and you should be familiar with both in order to effectively instrument your software. +## Getting a Tracer + +To create spans, you'll need to acquire or initialize a tracer first. + +### Initiallizing a new tracer + +Ensure you have the right packages installed: + +``` +go get go.opentelemetry.io/otel \ + go.opentelemetry.io/otel/trace \ + go.opentelemetry.io/otel/sdk \ +``` + +Then initialize an exporter, resources, tracer provider, and finally a tracer. + +```go +package app + +import ( + "context" + "fmt" + "log" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "go.opentelemetry.io/otel/trace" +) + +var tracer trace.Tracer + +func newExporter(ctx context.Context) /* (someExporter.Exporter, error) */ { + // Your preferred exporter: console, jaeger, zipkin, OTLP, etc. +} + +func newTraceProvider(exp sdktrace.SpanExporter) *sdktrace.TracerProvider { + // The service.name attribute is required. + resource := resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("ExampleService"), + ) + + return sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exp), + sdktrace.WithResource(resource), + ) +} + +func main() { + ctx := context.Background() + + exp, err := newExporter(ctx) + if err != nil { + log.Fatalf("failed to initialize exporter: %v", err) + } + + // Create a new tracer provider with a batch span processor and the given exporter. + tp := newTraceProvider(exp) + + // Handle shutdown properly so nothing leaks. + defer func() { _ = tp.Shutdown(ctx) }() + + otel.SetTracerProvider(tp) + + // Finally, set the tracer that can be used for this package. + tracer = tp.Tracer("ExampleService") +} +``` + +You can now access `tracer` to manually instrument your code. + ## Creating Spans -Spans are created by tracers, which can be acquired from a Tracer Provider. Typically a tracer is instantiated at the module level. +Spans are created by tracers. If you don't have one initialized, you'll need to do that. To create a span with a tracer, you'll also need a handle on a `context.Context` instance. These will typically come from things like a request object and may already contain a parent span from an [instrumentation library][].