diff --git a/docs/shipping/Code/go.md b/docs/shipping/Code/go.md index 864b80d9..fd7d695d 100644 --- a/docs/shipping/Code/go.md +++ b/docs/shipping/Code/go.md @@ -112,6 +112,7 @@ if err != nil { l.Stop() // Drains the log buffer ``` + ## Metrics :::note @@ -502,185 +503,121 @@ Encounter an issue? See our [log shipping troubleshooting](https://docs.logz.io/ + ## Traces -Deploy this integration to enable instrumentation of your Go application using OpenTelemetry. - -### Manual configuration - -This integration includes: - -* Installing the OpenTelemetry Go instrumentation packages on your application host -* Installing the OpenTelemetry collector with Logz.io exporter -* Running your Go application in conjunction with the OpenTelemetry instrumentation - -On deployment, the Go instrumentation automatically captures spans from your application and forwards them to the collector, which exports the data to your Logz.io account. - - +### Auto Instrumentation +Deploy this integration to enable instrumentation of your Go application using OpenTelemetry. -#### Setup instrumentation for your locally hosted Go application and send traces to Logz.io **Before you begin, you'll need**: - * A Go application without instrumentation * An active Logz.io account * Port `4318` available on your host system * A name defined for your tracing service. You will need it to identify the traces in Logz.io. - -:::note -This integration uses OpenTelemetry Collector Contrib, not the OpenTelemetry Collector Core. -::: - - - - -##### Download the general instrumentation packages - -These packages are required to enable instrumentation for your code regardless of the type of application that you need to instrument. - -To download these packages, run the following command from the application directory: +#### Install dependencies ```shell go get -u go.opentelemetry.io/otel -go get -u go.opentelemetry.io/otel/exporters/otlp -go get -u go.opentelemetry.io/otel -go get -u go.opentelemetry.io/otel/attribute -go get -u go.opentelemetry.io/otel/baggage go get -u go.opentelemetry.io/otel/propagation go get -u go.opentelemetry.io/otel/sdk/resource -go get -u go.opentelemetry.io/otel/sdk/trace -go get -u go.opentelemetry.io/otel/semconv/v1.4.0 -go get -u go.opentelemetry.io/otel/trace go get -u go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp +go get -u go.opentelemetry.io/otel/sdk/trace +go get -u go.opentelemetry.io/otel/semconv/v1.26.0 ``` +#### Setup Tracer Provider +Create a new file `otel.go` and place the below code in it: :::note -We recommend sending OTLP traces using HTTP. This is why we import the `otlptracehttp` package. +Change `<>` to your own service name. ::: -##### Download the application specific instrumentation packages - -Depending on the type of your application, you need to download instrumentation packages specific to your application. For example, if your application is a HTTP server, you will need the `opentelemetry.io/contrib/instrumentation/net/http/otelhttp` package. The full list of all available packages can be found in the [OpenTelemetry contrib directory](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/v0.22.0/instrumentation). - -The example below is given for a HTTP server application: - -```shell -go get -u go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp -``` - -##### Add the instrumentation to the `import` function - -Add all the packages downloaded in the previous steps to the `import` function of your application. - -The example below is given for a HTTP server application: - ```go import ( "context" - "io" - "log" - "net/http" - - "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/baggage" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" - "go.opentelemetry.io/otel/trace" + "log" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" ) -``` - -##### Add the `initProvider` function - - -Add the `initProvider` function to the application code as follows: - -```go -func initProvider() func() { - ctx := context.Background() - res, err := resource.New(ctx, - resource.WithAttributes( - semconv.ServiceNameKey.String("test-service"), +func newTraceProvider() (*sdktrace.TracerProvider, error) { + // Ensure default SDK resources and the required service name are set. + r, err := resource.Merge( + resource.Default(), + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName("<>"), ), ) - handleErr(err, "failed to create resource") + if err != nil { + return nil, err + } - traceExporter, err := otlptracehttp.New(ctx, - otlptracehttp.WithInsecure(), + exp, _ := otlptracehttp.New(context.Background(), otlptracehttp.WithEndpoint("localhost:4318"), - ) - handleErr(err, "failed to create trace exporter") + otlptracehttp.WithInsecure()) - bsp := sdktrace.NewBatchSpanProcessor(traceExporter) - tracerProvider := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithResource(res), - sdktrace.WithSpanProcessor(bsp), - ) - otel.SetTracerProvider(tracerProvider) - otel.SetTextMapPropagator(propagation.TraceContext{}) - return func() { - handleErr(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider") - } + return sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exp), + sdktrace.WithResource(r), + ), nil } -``` -##### Instrument the code in the `main` function +// setupOTelSDK bootstraps the OpenTelemetry logging pipeline. +func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, err error) { + // setup trace provider + traceProvider, err := newTraceProvider() + if err != nil { + return nil, err + } -In the `main` function of your application, add the following code: + otel.SetTracerProvider(traceProvider) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( + propagation.TraceContext{}, propagation.Baggage{})) + + // Return a shutdown function + shutdown = func(ctx context.Context) error { + err := traceProvider.Shutdown(ctx) + if err != nil { + log.Printf("Error during tracer provider shutdown: %v", err) + } + return err + } -```go - shutdown := initProvider() - defer shutdown() + return shutdown, nil +} ``` -After this, you need to declare the instrumentation according to your application. The example below is given for a HTTP server application. The HTTP handler instructs the tracer to create spans on each request. +#### Call Tracer Provider from main function +Make sure the application will setup the instrumentation by calling `setupOTelSDK()` that was created in the previous step from your main function. ```go -uk := attribute.Key("username") - - helloHandler := func(w http.ResponseWriter, req *http.Request) { - ctx := req.Context() - span := trace.SpanFromContext(ctx) - bag := baggage.FromContext(ctx) - span.AddEvent("handling this...", trace.WithAttributes(uk.String(bag.Member("username").Value()))) - - _, _ = io.WriteString(w, "Hello, world!\n") - } - - otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello") - - http.Handle("/hello", otelHandler) - err := http.ListenAndServe(":7777", nil) - if err != nil { - panic(err) - } +// Set up OpenTelemetry. +otelShutdown, err := setupOTelSDK(ctx) +if err != nil { + return } -func handleErr(err error, message string) { - if err != nil { - log.Fatalf("%s: %v", message, err) - } +// Handle shutdown properly so nothing leaks. +defer func() { + err = errors.Join(err, otelShutdown(context.Background())) +}() ``` +#### Setup OpenTelemetry Collector -##### Download and configure OpenTelemetry collector - -Create a dedicated directory on the host of your Go application and download the [OpenTelemetry collector](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.70.0) that is relevant to the operating system of your host. - - +Create a dedicated directory on the host of your Go application and download the [OpenTelemetry collector](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.116.0) that is relevant to the operating system of your host. After downloading the collector, create a configuration file `config.yaml` with the following parameters: @@ -689,8 +626,7 @@ After downloading the collector, create a configuration file `config.yaml` with {@include: ../../_include/tracing-shipping/replace-tracing-token.html} -##### Start the collector - +#### Start OpenTelemetry Collector Run the following command from the directory of your application file: ```shell @@ -699,18 +635,17 @@ Run the following command from the directory of your application file: * Replace `` with the path to the directory where you downloaded the collector. * Replace `` with the version name of the collector applicable to your system, e.g. `otelcontribcol_darwin_amd64`. -##### Run the application -Run the application to generate traces: +##### Check Logz.io for your traces -```shell -go run .go -``` +Run the application after building it with the new Instrumentation. +Give your traces some time to get from your system to ours, and then open [Tracing](https://app.logz.io/#/dashboard/jaeger). -##### Check Logz.io for your traces +### Manual Instrumentation + +If you're using specific libararies and want to be specific or precise with instrumentation, you can opt to[instrument your code manually](https://opentelemetry.io/docs/languages/go/instrumentation/#traces). -Give your traces some time to get from your system to ours, and then open [Tracing](https://app.logz.io/#/dashboard/jaeger).