> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go Custom Instrumentation

AppSignal is compatible with OpenTelemetry instrumentation packages.
Some of these [instrumentation packages](/go/instrumentations) may require additional setup.

This does not always include the information you need to debug issues.
For more fine-grained reporting, you can add custom instrumentation.

We support [OpenTelemetry tracing][manual] as laid out in the OpenTelemetry documentation.
It's possible to add more data to span using OpenTelemetry span attributes.

There are also AppSignal span attributes that can change how traces are grouped and some attributes that allow for filtering out sensitive data.

## Setup

When adding custom instrumentation, first import the OpenTelemetry trace package in the file you want to add the instrumentation to.

<CodeGroup>
  ```go Go theme={null}
  import (
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/attribute"
  	"go.opentelemetry.io/otel/trace"
  )
  ```
</CodeGroup>

## Creating a new span

Using the tracer initialized during the [installation](/go/installation), create a new span.

<CodeGroup>
  ```go Go theme={null}
  var tracer = otel.Tracer("my-tracer-name")

  func httpHandler(w http.ResponseWriter, r *http.Request) {
  	// Create a new span from the parent context
  	ctx, span := tracer.Start(r.Context(), "hello-span")
  	// Defer closing the span to the end of this function
  	defer span.End()

  	// Set attributes
  }
  ```
</CodeGroup>

*Note: In these examples we're relying on the context from the HTTP request, given by `r.Context()`.*
*Receiving the context may be different in your application.*

## Get the current span

You can also fetch the current span using the tracer initialized during the [installation](/go/installation):

<CodeGroup>
  ```go Go theme={null}
  func httpHandler(w http.ResponseWriter, r *http.Request) {
  	ctx := r.Context()
      span := trace.SpanFromContext(ctx)

  	// Set attributes
  }
  ```
</CodeGroup>

*Note: This will only return a span if one is already active.*

More ways to create and get spans are documented on the [OpenTelemetry Go Instrumentation page][manual].

## AppSignal attributes

Once you have created, or fetched, a span, you can set certain attributes that are specific to AppSignal to customize how the data arrives in AppSignal.

<CodeGroup>
  ```go Go theme={null}
  span = // Create a new span or fetch the current span
  span.SetAttributes(attribute.String("attribute_name", "attribute value"))
  ```
</CodeGroup>

See our guides for more information on what custom AppSignal attributes are supported:

* [Tagging guide](/guides/tagging)
* [Data customization guide](/guides/custom-data)

[manual]: https://opentelemetry.io/docs/languages/go/instrumentation/
