OpenTelemetry-first observability bootstrap and optional LoopBack integration for Sourceloop services.
This package follows a hybrid model:
- Bootstrap is the required startup path Use bootstrap before your application imports go too far, so tracing can start early.
- The LoopBack component is optional
Use
ObservabilityComponentonly when you want DI-bound config, framework bindings, and profile extension-point integration.
That means this package should be thought of as:
bootstrap.ts: core runtime startupcomponent.ts: LoopBack adapter
- Early env-led or override-led bootstrap for observability startup
- DI-bound config via
ObservabilityBindings.config - Built-in profiles for
default,newrelic,signoz, anddatadog - LoopBack extension-point support for custom profiles
- Generic helpers for spans, exception recording, and propagation headers
Call bootstrap in your service entrypoint before application construction.
import {bootstrapObservabilityFromEnv} from '@sourceloop/observability';
bootstrapObservabilityFromEnv();You can also pass explicit startup config for tests or advanced bootstrap flows:
import {bootstrapObservability} from '@sourceloop/observability';
bootstrapObservability({
enabled: true,
profile: 'default',
serviceName: 'audit-service',
});Startup-only instrumentation toggles are also configured here:
bootstrapObservability({
enabled: true,
profile: 'default',
serviceName: 'audit-service',
instrumentations: {
http: true,
express: true,
pg: false,
mysql: true,
redis: false,
kafka: false,
},
});Use the component only if you want framework-native bindings and DI config.
import {
ObservabilityBindings,
ObservabilityComponent,
} from '@sourceloop/observability';
this.bind(ObservabilityBindings.config).to({
serviceVersion: '1.0.0',
environment: process.env.NODE_ENV,
resourceAttributes: {
'deployment.color': 'blue',
},
});
this.component(ObservabilityComponent);Important:
- Bootstrap controls startup-critical config.
- DI config is meant for component-level enrichment, not for replacing early bootstrap.
- Instrumentation toggles and custom instrumentations are bootstrap concerns, not DI concerns.
- If you skip bootstrap and rely only on DI config, early instrumentation will not be enabled.
The package resolves config in two stages.
Resolved by resolveBootstrapConfig().
Used for startup-critical fields such as:
enabledprofileserviceName- exporter endpoint/protocol/headers
- sampler
- instrumentation toggles
Precedence:
- bootstrap overrides
- environment variables
- defaults
Instrumentation toggles can be set either in instrumentations during bootstrap or through environment variables:
OBSERVABILITY_INSTRUMENT_HTTPOBSERVABILITY_INSTRUMENT_EXPRESSOBSERVABILITY_INSTRUMENT_PGOBSERVABILITY_INSTRUMENT_MYSQLOBSERVABILITY_INSTRUMENT_REDISOBSERVABILITY_INSTRUMENT_KAFKA
Set each one to true or false to enable or disable that instrumentation. express requires http to remain enabled.
The same toggles can be set programmatically through bootstrapObservability({...}) using the instrumentations object shown above. That is the preferred non-env path.
You can also attach your own instrumentation instances during bootstrap:
import {
bootstrapObservability,
ObservabilityInstrumentation,
} from '@sourceloop/observability';
const customInstrumentation: ObservabilityInstrumentation = {
enable() {
// initialize your instrumentation
},
disable() {
// clean up your instrumentation
},
setTracerProvider(tracerProvider) {
// optional: keep the tracer provider if your instrumentation needs it
},
};
bootstrapObservability({
enabled: true,
profile: 'default',
serviceName: 'audit-service',
customInstrumentations: [customInstrumentation],
});Use customInstrumentations when you need a package-specific or in-house instrumentation that is not built into @sourceloop/observability.
Resolved by resolveComponentConfig().
Used for LoopBack/application enrichment such as:
serviceVersionenvironment- extra
resourceAttributes
Precedence:
- DI config
- bootstrap-resolved config
Built-in profiles:
defaultnewrelicsignozdatadog
default means plain OTLP behavior with no vendor-specific profile layered on top.
These profiles are implemented by profile classes inside the package. Custom profiles can be added using the LoopBack extension point exposed by the package.
OTLP exporters are bundled as package dependencies because OTLP is the built-in transport path for all current profiles.
There are currently no vendor-native SDK dependencies in the package. The built-in newrelic, signoz, and datadog profiles are OTLP-oriented presets, not native agent integrations.
OpenTelemetry instrumentation libraries are optional peer dependencies so consumers can cherry-pick only the instrumentations they want to use:
@opentelemetry/instrumentation-http@opentelemetry/instrumentation-express@opentelemetry/instrumentation-pg@opentelemetry/instrumentation-redis@opentelemetry/instrumentation-kafkajs@opentelemetry/instrumentation-mysql@opentelemetry/instrumentation-mysql2
If an instrumentation is enabled in config but its package is not installed, bootstrap will fail fast with a clear startup error.
Bootstrap/runtime:
bootstrapObservability()Starts observability using explicit startup overrides. Use this in tests or when startup config needs to be supplied programmatically before the app is constructed.bootstrapObservabilityFromEnv()Starts observability from environment-driven configuration only. This is the standard entrypoint for service bootstrapping.shutdownObservability()Shuts down the active tracer runtime and clears internal singleton state. Use this for graceful shutdown or test cleanup.isObservabilityEnabled()Returns whether observability is currently active in the bootstrapped runtime.
LoopBack:
ObservabilityBindingsProvides LoopBack binding keys for DI-bound observability config, runtime, and resolved config.ObservabilityComponentRegisters the optional LoopBack integration layer, including config bindings and built-in profile bindings.
Tracing helpers:
withSpan()Runs an async function inside a new active span and closes the span automatically when the function completes.addSpanAttributes()Adds attributes to the current active span when one exists.recordException()Records an error on the current span and marks the span status as failed.createPropagationHeaders()Injects the current trace context into a plain header carrier for outbound calls.getTraceContext()Returns the current trace identifiers and propagation headers for correlation or logging.
Config helpers:
resolveBootstrapConfig()Resolves startup-critical config from explicit overrides, environment variables, and defaults.resolveComponentConfig()Resolves the LoopBack/component-level config by layering DI enrichment on top of the bootstrapped config.validateObservabilityConfig()Validates that the resolved observability config is coherent before runtime startup.