🛟 Don’t hesitate to contact us if you run into
any issues while implementing custom instrumentations. We’re here to help!
Setup
To use AppSignal’s helper functions in your instrumentation, you must first importopentelemetry and define a tracer object. Depending on your instrumentation, you may also need to create additional spans.
Our Example Use Cases demonstrate how you can use tracers, spans, and helpers to create your custom instrumentation.
Import OpenTelemetry and Define Tracer
The AppSignal integration for Node.js uses OpenTelemetry tracer objects. These tracers contain various functions for creating custom instrumentations. The Tracer exposes functions for creating and creating new spans. This documentation will outline how you can use tracers and spans to implement your custom integration. You must first import the trace object from@opentelemetry/api before working with tracers and spans. By invoking the getTracer function on the trace object a new tracer object can be created. You must give your tracer object a name in this function, as seen in the example below, where the getTracer function is used to define a tracer with the name "my interesting app".
Spans
A span is the name of the object that we use to capture data about the performance of your application, any errors and any surrounding context. A span forms part of a broader trace, a hierarchical representation of the flow of data through your application. Spans keep track of the start and end time of an event, along with other information, such as the name or other data related to it. You can read more about spans in the OpenTelemetry Tracing Documentation.Creating an Active Span
New spans can be invoked via the trace object. Code instrumented inside an Express of Koa handler will already be inside a span. You can create new spans by invoking thestartActiveSpan() function on the tracer object. Newly created spans will be the child of the span they were created in, if one exists. You can use child spans to measure the performance of tasks executed from within a parent span.
You should give your span a name that makes its purpose clear. Execute all of the tasks you wish to monitor within the startActiveSpan() function, like in the below example.
span.end()
Example Use Cases
When implementing custom instrumentation, you may be curious to understand the behavior of particular functions, for example, how long it takes for them to execute.Using Helpers
In the below example, we are curious about the performance of our “order-coffee” GET endpoint for different roasts of coffee. To investigate this, we use thesetAttribute function to create a tag called flavor, the value we retrieve from request parameters.
Note: Because this is inside an Express request handler, a root span has already been created.
"picking coffee beans" span defined in the pickCoffeeBeans function.
Once the attribute has been assigned and all functions executed, we .end() the span to ensure AppSignal receives the start and finish time and attributes we’ve assigned:

Active Spans
While tags are helpful to analyse performance differences on the same function, it does not give us insight into the performance of any functions called from within our function. To give us greater insights into what’s happening inside of thepickCoffeeBeans(), we create a new activeSpan and name it “picking coffee beans”. All logic we wish to track is executed from within an async function.
We await the promise returned by retrieveDrinkTypes(), so that we can track it’s performance as a child span of the "picking coffee beans" span we created in pickCoffeeBeans().
pickCoffeeBeans(), which will include the performance data of the retrieveDrinkTypes() function, providing greater insight into what factors are impacting the overall performance of a function.
Helpers
To use helper functions, you must first import them from@appsignal/nodejs. In the example below the namespace the code is being executed in is being reported to AppSignal. All available helper functions are outlined in the below documentation.
Helper Functions
- Namespace
- Tag
- Request Parameters
- Set Session Data
- Request Headers
- Root Name
- Custom Data
- Child Span Helpers:
Namespace
Sets the string value of the root span namespace.Tag
Sets a tag, for example from a request parameter, which can be used as a filter from within the AppSignal application. In the below example we create a tag called color with the value blue. You can configure tags with names relevant to the context of your application.Request Parameters
An object that is serializable to JSON. Incoming request parameters request body and query parameters.Set Session Data
An object that is serializable to JSON.Request Headers
A string containing the header value.Root Name
Allows you to set the name of the trace. Samples are grouped into actions by their trace name.Example Use Case
Your application has an endpoint calledGET /coffee.
GET /coffee, but your endpoint handles multiple actions: coffee?action=buy, and coffee?action=sell.

GET /coffee endpoint, they are conceptually very different and so it would make sense for them to be grouped separately in AppSignal rather than in the same GET /coffee sample. To do this, you can use the setRootName() helper:
setRootName will change the name of the root span, grouping the samples for the requests coffee?action=buy and coffee?action=sell into separate actions:

Custom Data
An object that is serializable to JSON.Child Span Helpers
The following helpers only apply to child spans. To create a child span, you must create a new Active Span. New spans are automatically children of their parent span.Category
A string containing the child span category. The name should use. to express the category’s hierarchical inheritance. For example: cafe.coffee.cupsize
Name
A string containing the child span event timeline title.Body
The span’s body can include additional information about the event, like the HTTP request, the connected host, etc. Be sure to sanitize the information before adding it to the span so no Personal Identifiable Information is sent to AppSignal. This information will be visible for the span when hovering over the event timeline. To store SQL queries in the span’s body, please use thesetSqlBody helper instead.
SQL body
Set a SQL query as the body of the span as it appears in the performance event timeline in the incident sample detail view. This is similar to thesetBody helper, but is specialized for SQL queries. Any SQL query set as the body with this attribute will be sanitized to avoid sending PII (Personal Identifiable Information) data to our servers.
See the setBody helper for more details on how the body attribute works.
When both the setBody and setSqlBody helpers are called on the same span, the setSqlBody helper’s value is leading and the setBody helper’s value will be ignored.