Elastic APM Go Agent

repository·main·Indexed 19 days ago

https://github.com/elastic/apm-agent-go

The official package for instrumenting Go applications with Elastic APM to trace operation execution and send performance metrics and errors to an Elastic APM server. It provides instrumentation for Go kit, GORM (via apmgormv2), and database drivers (via apmsql). The agent collects built-in Go runtime, system, and process metrics and supports configuration via environment variables or Central Configuration. Note: This repository is in maintenance mode; migration to the OpenTelemetry Go API and SDK is recommended.

Tokens
75.2K
Snippets
268
Records
361
Agent score
61%

What's inside elastic-apm-agent-go

  1. Introduction to the Elastic APM Go Agent

    main
    The Elastic APM Go Agent traces the execution of operations in Go applications, sending performance metrics and errors to the Elastic APM server. It provides built-in support for popular frameworks (like Gorilla and Gin) and standard Go libraries (like net/http and database/sql).
  2. Propagate tracing context using Go contexts

    main

    In Go, the context.Context object is the primary mechanism for propagating request-scoped values, including APM transactions and spans, across function calls and goroutines.

    To ensure spans are correctly parented to a transaction or a parent span, you must:

    1. Store the transaction in the context: Use apm.ContextWithTransaction to add a transaction to a context. (Note: Middleware like apmhttp.Wrap does this automatically for HTTP requests).
    2. Pass the context down: Manually pass the context.Context object into subsequent method calls.
    3. Create child spans: Use apm.StartSpan(ctx, ...) which returns a new context containing the newly created span. This new context should be used for any subsequent calls to ensure a proper hierarchy (e.g., Transaction -> Span A -> Span B).

    If a context does not contain a transaction or a span, any spans created with apm.StartSpan using that context will be dropped and not reported to the APM Server.

    // 1. Start a span using the existing context
    // apm.StartSpan returns the new span AND a new context containing that span
    span, ctx := apm.StartSpan(ctx, "operation_name", "span_type")
    defer span.End()
    
    // 2. Pass the NEW context (ctx) to downstream functions to maintain the hierarchy
    err := downstreamFunction(ctx)
  3. Understand Trace Context and propagation

    main

    Trace context is used to correlate events across different services. It is based on the W3C Trace Context standard and contains:

    • The ID for the current transaction or span.
    • The ID of the end-to-end trace.
    • Sampling flags.

    This context is typically propagated between processes via HTTP headers, allowing the APM server to reconstruct a single distributed trace from multiple service calls.

  4. How built-in instrumentation modules work

    main

    The Elastic APM Go agent provides built-in instrumentation modules for various web frameworks and protocols. For each server instrumentation module, a transaction is reported for every handled request.

    This transaction is stored in the request's context. You can retrieve this context using the specific API of your framework (e.g., http.Request.Context() for standard library or gin.Context.Request.Context() for Gin). Once you have the context, you can use it to report custom spans that are linked to the current transaction.

  5. Requirements for Log Correlation

    main

    To correlate logs from your application with transactions captured by the Elastic APM Go Agent, your logs must include specific identifiers. This allows you to navigate between logs and traces in the Elastic observability stack.

    Required Trace Identifiers:

    • transaction.id
    • trace.id
    • span.id

    Required Service Metadata: To correlate logs to the correct service and environment, logs should also contain:

    • service.name
    • service.version
    • service.environment
  6. How duration and size formats work

    main

    Certain configuration options (like timeouts or buffer sizes) require specific unit formats. Units must be provided as a suffix directly after the number without whitespace.

    Duration Format

    Used for timeouts. Supported units:

    • ms (milliseconds)
    • s (seconds)
    • m (minutes)

    Example: 5ms

    Size Format

    Used for maximum buffer sizes. The agent uses the power-of-two convention (e.g., 1KB = 1024B). Supported units:

    • B (bytes)
    • KB (kilobytes)
    • MB (megabytes)
    • GB (gigabytes)

    Example: 10KB

  7. How the Elastic APM Go Agent works

    main

    The agent uses instrumentation modules to record events via middleware or wrappers.

    Data Collection Mechanisms

    • Incoming HTTP Requests: Install router middleware for supported web frameworks. These are recorded as transactions and include related panics or errors.
    • Outgoing HTTP Requests: Instrument an http.Client or http.Transport using the module/apmhttp module.
    • Database Queries: Use the module/apmsql module, which provides instrumentation for well-known database drivers.
    • Metrics: The agent automatically starts a background goroutine upon initialization to collect system and application metrics at regular intervals.

    Distributed Tracing and Context Propagation

    To connect transactions with related spans and errors, and to propagate traces between services (distributed tracing), the agent relies on Go's built-in context package. Transactions and spans are stored within context objects. For incoming HTTP requests, trace data is recorded in the context object accessible via net/http.Context.

  8. Mix Native Elastic APM and OpenTracing APIs

    main

    When apmot is imported, transactions and spans created with the native Elastic APM API are made available as OpenTracing spans. This allows you to interleave both APIs in a single trace.

    Important Note on Span Wrappers: When using opentracing.SpanFromContext to retrieve a span created by the native API, the returned opentracing.Span is a wrapper intended only for context propagation. The following methods on these specific wrapper objects are no-ops:

    • Finish()
    • Log*()
    • Tracer()
    // Transaction created through native API.
    transaction := apm.DefaultTracer().StartTransaction("GET /", "request")
    ctx := apm.ContextWithTransaction(context.Background(), transaction)
    
    // Span created through OpenTracing API will be a child of the transaction.
    otSpan, ctx := opentracing.StartSpanFromContext(ctx, "ot-span")
    
    // Span created through the native API will be a child of the span created
    // above via the OpenTracing API.
    apmSpan, ctx := apm.StartSpan(ctx, "apm-span", "apm-span")
  9. Enable Log Correlation in Elastic APM Go Agent

    main

    The Elastic APM Go Agent provides Log Correlation, which automatically injects correlation IDs into your application logs. These IDs enable seamless navigation between logs, traces, and services within the Elastic Observability stack.

    To benefit from this, you can use one of two approaches:

    1. Framework Integrations: Use one of the agent's built-in integrations for popular logging frameworks. These integrations automatically inject trace ID fields into your log records.
    2. Manual Injection: If your logging framework is not supported, you can manually inject trace IDs into your log records to achieve correlation.