OpenTelemetry Support

Overview

The io.Manager Server can be configured to export traces via OpenTelemetry.

By default, the io.Manager Server supports exporting traces to an OpenTelemetry Collector. It's also possible to provide your own custom trace exporter, trace span processor, and trace sampler pointing to a different backend service. Trace sampling is supported and is configurable.

Trace Instrumentation

io.Manager uses instrumentation libraries to enrich the generated traces with more details:

Enabling Traces Exports

Publishing traces is disabled by default. To enable publishing traces, you must enable OpenTelemetry support in the io.Manager Server and explicitly enable the traces feature via the configuration object for initializing the io.Manager Server, or via environment variables, depending on your deployment approach.

Environment Variables

To enable and configure publishing traces, register the following environment variables with the proper values. The API_OTEL_TRACES_ENABLED environment variable must be set to true:

Environment Variable Description
API_OTEL_TRACES_DEFAULT_SAMPLE Specifies the rate to be used by the default trace sampler for sampling all traces that don't match the rules specified in the sampling property of the traces object in the configuration object for initializing the io.Manager Server. Accepts as a value a number greater than 0 and less than or equal to 1 denoting the probability percentage for sampling trace spans (e.g., a value of 0.15 means that all trace spans not matched by any rules will have a 15% probability of being sampled). Ignored when a custom trace sampler is used. Defaults to 1.
API_OTEL_TRACES_ENABLED If true, will enable publishing OpenTelemetry traces. Defaults to false.
API_OTEL_TRACES_PUBLISH_INTERVAL Interval in milliseconds between two consecutive traces exports. Passed as a value to the scheduledDelayMillis property of the BufferConfig constructor parameter when creating a BatchSpanProcessor instance. This is the default span processor used by the io.Manager Server. Ignored when a custom trace span processor is used. Defaults to 5000.
API_OTEL_TRACES_URL URL pointing to an OpenTelemetry Collector where the generated traces will be sent via HTTP. Passed as a value to the url property of the OTLPExporterNodeConfigBase constructor parameter when creating an OTLPTraceExporter instance. This is the default trace exporter used by the io.Manager Server. Required if using the default trace exporter and trace span processor. Ignored when either a custom trace exporter or a custom trace span processor is used.

The following example demonstrates how to enable OpenTelemetry support, how to enable publishing traces, and how to configure the interval for publishing traces:

# Enabling OpenTelemetry support.
API_OTEL_ENABLED=true
API_OTEL_RESOURCE_SERVICE_NAME=io-manager

# Enabling and configuring traces.
API_OTEL_TRACES_ENABLED=true
API_OTEL_TRACES_URL=http://localhost:4318/v1/traces
API_OTEL_TRACES_PUBLISH_INTERVAL=10000

Configuration Object

To enable publishing traces, use the traces property under the otel top-level key of the optional Config object for initializing the io.Manager Server.

The following example demonstrates how to enable OpenTelemetry support, how to enable publishing traces, and how to configure the interval for publishing traces:

import { start } from "@interopio/manager";

const config = {
    // Enabling OpenTelemetry support.
    otel: {
        enabled: true,
        resource: {
            serviceName: "io-manager"
        },
        // Enabling and configuring traces.
        traces: {
            enabled: true,
            url: "http://localhost:4318/v1/traces",
            publishInterval: 10000
        }
    }
};

const server = await start(config);

The traces object has the following properties:

Property Type Description
customExporter object SpanExporter instance of a custom trace exporter to be used instead of the default trace exporter. Ignored when a custom trace span processor is used.
customProcessor object SpanProcessor instance of a custom trace span processor to be used instead of the default span processor.
customSampler object Sampler instance of a custom trace sampler to be used instead of the default trace sampler. When using a custom trace sampler, the settings specified in the sampling and default properties will be ignored.
default object Default trace settings to be applied to all traces not matched by any of the rules specified in the sampling array.
enabled boolean If true, will enable publishing OpenTelemetry traces. Defaults to false.
publishInterval number Interval in milliseconds between two consecutive trace exports. Passed as a value to the scheduledDelayMillis property of the BufferConfig constructor parameter when creating a BatchSpanProcessor instance. This is the default span processor used by the io.Manager Server. Ignored when a custom trace span processor is used. Defaults to 5000.
sampling object[] List of objects each describing rules for matching trace spans. Each object also specifies a rate to be used for sampling the matched trace spans. Ignored when a custom trace sampler is used.
url string URL pointing to an OpenTelemetry Collector where the generated traces will be sent via HTTP. Passed as a value to the url property of the OTLPExporterNodeConfigBase constructor parameter when creating an OTLPTraceExporter instance. This is the default trace exporter used by the io.Manager Server. Required if using the default trace exporter and trace span processor. Ignored when either a custom trace exporter or a custom trace span processor is used.

The default object has the following properties:

Property Type Description
sample number Specifies the rate to be used by the default trace sampler for sampling all trace spans that don't match the rules specified in the sampling array. Accepts as a value a number greater than 0 and less than or equal to 1 denoting the probability percentage for sampling traces (e.g., a value of 0.15 means that all trace spans not matched by any rules will have a 15% probability of being sampled). Ignored when a custom trace sampler is used. Defaults to 1.

Each object in the sampling array has the following properties:

Property Type Description
attributes object Collection of type Record<string, string | number> containing attribute names and values to be used for matching trace spans.
name string String value for matching one or more spans by name. If the string value starts with # it will be treated as a case-insensitive regular expression.
sample number Specifies the rate to be used by the default trace sampler for sampling the matched trace spans. Accepts as a value a number greater than 0 and less than or equal to 1 denoting the probability percentage for sampling a trace (e.g., a value of 0.15 means that all trace spans matched by any of the rules will have a 15% probability of being sampled). Ignored when a custom trace sampler is used.

Trace Sampling

The io.Manager Server provides configurable mechanisms for sampling traces. It's possible to configure the default sampling rate, as well as to provide rules for matching the root spans of traces by name and attributes. This enables you to assign a custom sampling rate to all traces matched by a certain rule.

⚠️ Note that the matching rules are applied only to the root trace spans. If a root span is matched and sampled, the entire trace (i.e., all child spans belonging to the trace) will effectively be sampled.

The default sampling rate is 1 (meaning that 100% of all traces will be sampled) and is applied to all traces not matched by any rules. It can be configured via the API_OTEL_TRACES_DEFAULT_SAMPLE environment variable or via the sample property of the default object under the traces key in the configuration object for initializing the io.Manager Server.

The following example demonstrates defining a default sampling rate of 0.5:

import { start } from "@interopio/manager";

const config = {
    otel: {
        enabled: true,
        resource: {
            serviceName: "io-manager"
        },
        traces: {
            enabled: true,
            url: "http://localhost:4318/v1/traces",
            // Default sampling rate that will be applied
            // to all traces not matched by any rules.
            default: {
                sample: 0.5
            }
        }
    }
};

const server = await start(config);

To specify rules for matching the root spans of traces, use the sampling property of the traces object in the configuration object for initializing the io.Manager Server.

⚠️ Note that it isn't possible to provide sampling rules via environment variables.

The following example demonstrates assigning a custom sample rate of 0.1 to all root spans for HTTP requests sent to a specific route. The root spans are matched by using the supported "http.target" span attribute:

import { start } from "@interopio/manager";

const config = {
    otel: {
        enabled: true,
        resource: {
            serviceName: "io-manager"
        },
        traces: {
            enabled: true,
            url: "http://localhost:4318/v1/traces",
            // Trace sampling rules.
            sampling: [
                {
                    attributes: {
                        // Matching a root span by using a supported attribute as a criteria.
                        "http.target": "/api/apps"
                    },
                    // Assigning a custom sampling rate.
                    sample: 0.1
                }
            ],
            // All traces not matched by the specified rules
            // will be sampled at the default rate.
            default: {
                sample: 0.5
            }
        }
    }
};

const server = await start(config);

The io.Manager Server supports a set of span attributes that can be used to match root spans for HTTP requests. It also emits several other root spans whose well-known names you can use as matching criteria.

Supported Span Attributes

The following attributes can be used for matching root trace spans for HTTP requests:

Attribute Description
"http.flavor" Version of the HTTP protocol used (e.g., "1.1.").
"http.host" The value of the HTTP host header (e.g., "localhost:4356").
"http.method" HTTP request method (e.g., "GET").
"http.scheme" The URI scheme identifying the used protocol (e.g., "http").
"http.target" The full request target as passed in an HTTP request line or equivalent (e.g, "/api/apps").
"http.url" Full HTTP request URL in the form scheme://host[:port]/path?query[#fragment] (e.g., "http://localhost:4356/api/apps").
"http.user_agent" Value of the HTTP User-Agent header sent by the client (e.g., "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36").
"net.host.name" Local hostname or similar (e.g., "localhost").
"net.transport" Transport protocol used (e.g.,"ip_tcp").

The following example demonstrates how to configure the io.Manager Server to use the "http.target" attribute to match and sample root spans for requests to route /api/apps at a rate of 0.1 (10%). All other root spans will be sampled at a rate of 1 (100%):

import { start } from "@interopio/manager";

const config = {
    otel: {
        enabled: true,
        resource: {
            serviceName: "io-manager"
        },
        traces: {
            enabled: true,
            url: "http://localhost:4318/v1/traces",
            sampling: [
                {
                    attributes: {
                      "http.target": "/api/apps"
                    },
                    sample: 0.1
                }
            ],
            default: {
                sample: 1
            }
        }
    }
};

const server = await start(config);

Supported Span Names

The io.Manager Server emits the following root spans whose names you can use in the rules for matching root trace spans:

Span Name Description
store.init Emitted when the io.Manager Server starts.
store.stop Emitted when the io.Manager Server stops.
cron-task.purge Emitted when the periodic purge task runs.
cron-task.otel-active-sessions-export Emitted when the periodic task for exporting the "io_manager.active_sessions" metric runs.

The following example demonstrates how to configure the io.Manager Server to use the "store.init" span name to match and sample database initialization spans at a rate of 1 (100%). All other root spans will be sampled at a rate of 0.1 (10%):

import { start } from "@interopio/manager";

const config = {
    otel: {
        enabled: true,
        resource: {
            serviceName: "io-manager"
        },
        traces: {
            enabled: true,
            url: "http://localhost:4318/v1/traces",
            sampling: [
                {
                    name: "store.init",
                    sample: 1
                }
            ],
            default: {
                sample: 0.1
            }
        }
    }
};

const server = await start(config);

Customization

Trace Exporter

The io.Manager Server provides an out-of-the-box implementation of an OTLPTraceExporter for sending traces to an OpenTelemetry Collector via HTTP.

For more advanced scenarios, it's possible to provide an instance of a custom trace exporter by using the customExporter property of the traces object in the configuration object for initializing the io.Manager Server.

⚠️ Note that it isn't possible to provide a custom trace exporter via environment variables.

For a complete example, see the OpenTelemetry Custom Trace Exporter example on GitHub.

Trace Span Processor

The io.Manager Server provides an out-of-the-box implementation of a BatchSpanProcessor for exporting traces periodically.

For more advanced scenarios, it's possible to provide an instance of a custom trace span processor by using the customProcessor property of the traces object in the configuration object for initializing the io.Manager Server.

⚠️ Note that it isn't possible to provide a custom trace span processor via environment variables.

For a complete example, see the OpenTelemetry Custom Trace Processor example on GitHub.

Trace Sampler

The io.Manager Server provides an out-of-the-box implementation of a default trace sampler that uses the rules defined in the sampling array and the default sampling rate defined in the sample property of the default object (or via the API_OTEL_TRACES_DEFAULT_SAMPLE environment variable) to sample trace spans.

For more advanced scenarios, it's possible to provide an instance of a custom trace sampler by using the customSampler property of the traces object in the configuration object for initializing the io.Manager Server.

⚠️ Note that it isn't possible to provide a custom trace sampler via environment variables.

For a complete example, see the OpenTelemetry Custom Trace Sampler example on GitHub.