Skip to content

Telemetry ​

OpenTelemetry auto-instrumentation and Sentry error tracking.

OpenTelemetry Setup ​

Call init() before other imports to enable auto-instrumentation:

typescript
import { init } from '@zyno-io/dk-server-foundation/telemetry/otel';

init();

// Now import everything else
import { createApp } from '@zyno-io/dk-server-foundation';

init(options?) ​

OptionTypeDescription
instrumentationsInstrumentation[]Additional OpenTelemetry instrumentations
httpIncomingRequestAttributeHook(request) => Record<string, AttributeValue>Add custom attributes to HTTP spans
enableMetricsEndpointbooleanEnable /metrics Prometheus endpoint

Built-in Instrumentations ​

InstrumentationPackageNotes
HTTP@opentelemetry/instrumentation-httpIgnores /healthz and Sentry requests
Undici (fetch)@opentelemetry/instrumentation-undiciIgnores /healthz and Sentry requests
DNS@opentelemetry/instrumentation-dns—
ioredis@opentelemetry/instrumentation-ioredis—
BullMQ@opentelemetry/instrumentation-bullmq—
MariaDBCustomTraces queries and connection pool metrics

Trace Export ​

  • Development: SimpleSpanProcessor (immediate export)
  • Production: BatchSpanProcessor (buffered export)

Metric Export ​

  • Pull: /metrics endpoint (Prometheus format, restricted to private IPs)
  • Push: OTLP endpoint with 10-second interval

Database Transaction Tracing ​

The library automatically wraps Database.prototype.transaction to create spans named sql.transaction.

Tracing Helpers ​

typescript
import { withSpan, withRootSpan, withRemoteSpan, setSpanAttributes } from '@zyno-io/dk-server-foundation';

// Create a child span
const result = await withSpan('processOrder', async () => {
    return await doWork();
});

// With attributes
const result = await withSpan('processOrder', { orderId: '123' }, async () => {
    return await doWork();
});

// Create a root span (ignores current context)
const result = await withRootSpan('backgroundJob', async () => {
    return await doWork();
});

// Continue a trace from a remote context
const result = await withRemoteSpan('handleRequest', { traceparent: '00-abc...' }, undefined, async () => {
    return await doWork();
});

// Add attributes to the active span
setSpanAttributes({ 'user.id': userId, 'order.total': total });

State Inspection ​

typescript
import { isTracingInstalled, getTracer, getActiveSpan, getTraceContext, disableActiveTrace } from '@zyno-io/dk-server-foundation';

if (isTracingInstalled()) {
    const tracer = getTracer();
    const span = getActiveSpan();
    const context = getTraceContext(); // { traceId, spanId, traceFlags }
}

// Suppress tracing for a section
disableActiveTrace();

SpanInfo ​

Remote span context for withRemoteSpan:

typescript
type SpanInfo = { traceId: string; spanId: string; traceFlags?: number } | { traceparent: string } | undefined;

Sentry ​

Sentry functions are available from the telemetry/sentry subpath (not re-exported from the package root):

typescript
import { installSentry, isSentryInstalled, flushSentry } from '@zyno-io/dk-server-foundation/telemetry/sentry';

installSentry({ dsn: 'https://...' });

// Check if installed
if (isSentryInstalled()) {
    /* ... */
}

// Flush pending events (5s timeout)
await flushSentry();

Sentry is automatically installed by createApp() when SENTRY_DSN is configured. It integrates with OpenTelemetry tracing (adds trace context to Sentry events).

Automatic Error Handling ​

createApp() sets up handlers for uncaughtException and unhandledRejection that report to Sentry and flush before exit.

MariaDB Instrumentation ​

Custom OpenTelemetry instrumentation for the mariadb package:

  • Wraps createConnection, createPool, createPoolCluster
  • Creates spans for each SQL query
  • Tracks connection pool metrics via db.client.connections.usage counter
  • Reports idle and used connection states

Metrics Endpoint ​

The /metrics endpoint serves Prometheus-formatted metrics. It is:

  • Restricted to private LAN IPs (10.x, 172.16-31.x, 192.168.x, 127.x, ::1, fc00::/7, fe80::/10)
  • Returns 403 for non-private IPs
  • Returns 503 if the Prometheus exporter is not available

Configuration ​

VariableDescription
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint for traces and metrics
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTLP endpoint for traces only
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTOTLP endpoint for metrics push
OTEL_METRICS_ENDPOINT_ENABLEDEnable /metrics Prometheus endpoint
OTEL_DEBUGEnable debug logging
SENTRY_DSNSentry DSN
APP_ENVEnvironment name sent to Sentry

Resource Attributes ​

Traces and metrics include:

AttributeSource
service.namePackage name
service.versionPackage version
deployment.environment.nameAPP_ENV
host.nameOS hostname
process.pidProcess ID

Released under the MIT License.