✍️ Manual instrumentation

Incorporate custom spans into your instrumentation to get the desired granularity you need.

Using Helios OpenTelemetry SDK enables users to benefit from automatic instrumentation, which provides a good level of visibility across the board. In some cases though a user may wish to have access to additional details of a certain operation (span), instrument specific parts of the code, or even suppress tracing altogether. This can be done by leveraging OpenTelemetry's standard manual instrumentation mechanism.

🚧

Manual instrumentation is supported in services that already have Helios OpenTelemetry SDK installed.

Custom spans with Helios

To create custom spans, use the code snippets below.

const { createCustomSpan } = require('@heliosphere/opentelemetry-sdk');

const spanName = 'my custom span';
const spanAttributes = { 'my_custom_attribute_key': 'my_value' }; 
const wrappedFunction = () => { return 5; };

createCustomSpan(spanName, spanAttributes, wrappedFunction);

// Attributes and function are not mandatory, can also be used in the following ways
createCustomSpan(spanName);
createCustomSpan(spanName, spanAttributes);
createCustomSpan(spanName, {}, wrappedFunction);
const { createCustomSpan } = require('@heliosphere/web-sdk');

const spanName = 'my custom span';
const spanAttributes = { 'my_custom_attribute_key': 'my_value' }; 
const wrappedFunction = () => { return 5; };

createCustomSpan(spanName, spanAttributes, wrappedFunction);

// Attributes and function are not mandatory, can also be used in the following ways
createCustomSpan(spanName);
createCustomSpan(spanName, spanAttributes);
createCustomSpan(spanName, {}, wrappedFunction);
import { createCustomSpan } from '@heliosphere/opentelemetry-sdk';

const spanName = 'my custom span';
const spanAttributes = { 'my_custom_attribute_key': 'my_value' }; 
const wrappedFunction = () => { return 5; };

createCustomSpan(spanName, spanAttributes, wrappedFunction);

// Attributes and function are not mandatory, can also be used in the following ways
createCustomSpan(spanName);
createCustomSpan(spanName, spanAttributes);
createCustomSpan(spanName, {}, wrappedFunction);
from helios import create_custom_span

span_name = 'my custom span'
attr_key = 'key1'
attr_value = 'val1'

def wrapped_function():
   return 5

create_custom_span(span_name, {attr_key: attr_value}, wrapped_function)

# Attributes and wrapped function are not mandatory, can also be used in the following ways:

create_custom_span(span_name)
create_custom_span(span_name, {attr_key: attr_value})
create_custom_span(span_name, None, wrapped_function)

# Wrapped function can receive parameters with a closure
val = 'abcd1234'
def wrapped_function_with_parameters():
    print(val)

create_custom_span(span_name, None, wrapped_function_with_parameters)
import (
   "github.com/helios/go-sdk/sdk"
   "go.opentelemetry.io/otel/attribute"
)


spanAttributes := []attribute.KeyValue{{Key: "key", Value: attribute.StringValue("value")}}
sdk.CreateCustomSpan(context, "myCustomSpan", spanAttributes, func() {
   // Do something
})

// Function can be nil
sdk.CreateCustomSpan(context, spanName, []attribute.KeyValue{}, nil);

It needs to be used once in every flow that will use this code.

Note that attribute values need to be a primitive type or an array of primitive type values, as disclosed in the OpenTelemetry specifications.

Once custom attributes are instrumented, they are visible in trace visualization when inspecting custom spans - as well as in the trace filter as custom fields.

Example

Below you can see an example of trace visualization in Helios - a trace instrumented automatically using the Helios OpenTelemetry SDK - before and after manual instrumentation is used for the getUserDetails operation.

26482648

Visualization of a trace automatically instrumented in Helios - before and after manual instrumentation is used

In this example, the custom span in the Node.js service was created using this code:

const user = await fetchUserByEmail(userEmail);
const user = await createCustomSpan('getUserDetails', { 'user': userEmail }, async () => {
    return await fetchUserByEmail(userEmail);
});

Suppressing tracing

In some cases users may wish to prevent specific pieces of the code from being instrumented. To do so, leverage Helios' tracing suppression functionality in the code snippet below:

const { suppressTracing } = require('@opentelemetry/core');
const { context } = require('@opentelemetry/api');

context.with(suppressTracing(context.active()), () => {
    // No OpenTelemetry data is collected here
})
import { suppressTracing } from '@opentelemetry/core';
import { context } from '@opentelemetry/api';

context.with(suppressTracing(context.active()), () => {
    // No OpenTelemetry data is collected here
})
from helios import SuppressTracing
​
# Data from transaction is collected
redis_client.get(key)
​
with SuppressTracing():
    # Data is not collected
    redis_client.get(key)
​
# Data is collected again
redis_client.get(key)

📘

Node.js support for tracing suppression coming soon.

Useful how-to's

How to add information into trace visualization

Custom spans provide a simple and standard way to add specific attributes and data to a trace, and specifically trace visualization. Once manual instrumentation is used in a specific part of the code, that data will show up in a new span (that is also visually indicated as 'manual').

How to tag specific attributes for search purposes

Manual instrumentation can be leveraged not only to change the structure of a trace, but also to tag specific attributes in a way that will make them easily accessible for searching and filtering purposes later in Helios. Once a specific attribute is manually instrumented, it appears as a new trace filtering option in the under 'Custom attributes'.

How to alter trace visualization so that a few spans show up together

Manual instrumentation can also be useful when attempting to group together a few spans that otherwise would have appeared separate. By wrapping them together in a custom span, users can see their related flow easily in trace visualization.


Did this page help you?