/utils/telemetry 🔭

The telemetry module traces the XYZ process with OpenTelemetry.

Tracing is disabled unless an exporter is configured with the standard OTEL_* process environment variables.

The lightweight @opentelemetry/api is a dependency and always loaded. The API is a no-op until a tracer provider is registered.

The OpenTelemetry SDK and OTLP exporter are optional dependencies. These packages are installed and deployed but only loaded into the process with a dynamic import when tracing is enabled. A process without tracing does not pay the cold start and memory cost of loading the SDK.

The span helpers call the wrapped method directly without creating a span while tracing is disabled.

# Export spans to an OTLP/HTTP collector, eg. Jaeger, SigNoz, Grafana Tempo.
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer 🤫

# Log one span tree object per request to the console instead.
OTEL_TRACES_EXPORTER=console

# Only log requests which take 500ms or longer to the console.
OTEL_CONSOLE_MIN_DURATION=500

# Write the most recent console traces to an HTML report in a local process.
OTEL_CONSOLE_HTML=.traces/local.html

# Only write the HTML report without logging to the console.
# The report path defaults to .traces/local.html.
OTEL_TRACES_EXPORTER=html

# Optional
OTEL_SERVICE_NAME=xyz
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=dev
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
OTEL_SDK_DISABLED=true

The optional environment variables are read by the OpenTelemetry SDK. Please refer to the SDK configuration documentation for all available variables. The OTEL_TRACES_EXPORTER is read by the register method and only supports the otlp, console, html, and none values. The OTEL_CONSOLE_MIN_DURATION and OTEL_CONSOLE_HTML are specific to XYZ and only apply to the console and html exporters. The OTEL_CONSOLE_HTML is ignored in a Vercel deployment, where the html exporter logs to the console like the console exporter.

Every request which is not served as a static file is traced with a root span from the requestSpan middleware. The root span records the route, response status, process memory, and whether the request was the first request of the process (faas.coldstart).

Spans are flushed with the Vercel waitUntil method at the end of each request in a Vercel deployment since the function may be frozen once the response is sent.

Requires

  • module:@opentelemetry/api
  • module:node:crypto
  • module:node:fs
  • module:node:path

Methods

(inner) activeSpan() → {Span}

Returns the active span or a non-recording span if no span is active.

Returns:

The active span.

Type: 
Span

(inner) flushAfter(promise)

Keeps a Vercel function alive until the promise settles and flushes the spans afterwards. The response is not delayed.

The request span is flushed when the response is closed. A span which ends after the response, eg. a nonblocking query, would not be exported if the function is frozen before the next flush.

The method is a no-op unless tracing is enabled in a Vercel deployment. It must be called within the request, eg. when the nonblocking query is started.

Parameters:
NameTypeDescription
promisePromise

The promise of a span which may end after the response.

(inner) processAttributes() → {Object}

Returns the process metadata to be assigned as resource attributes on every span.

Returns:

Resource attributes.

Type: 
Object

(async, inner) register()

The register method creates and registers a NodeTracerProvider if the OTEL_TRACES_EXPORTER or an OTEL_EXPORTER_OTLP endpoint is configured in the process environment.

The method returns before the SDK packages are dynamically imported if no exporter is configured or OTEL_SDK_DISABLED is true.

The process metadata is assigned as resource attributes. Resource attributes from the OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME process environment take precedence.

Optional dependencies are skipped by an install with the --no-optional flag. Tracing remains disabled with a warning if an exporter is configured but the SDK packages cannot be imported.

(inner) registerTracerProvider(provider)

Enables tracing with a tracer from the provided tracer provider. The method is used to test spans with an in-memory exporter.

Parameters:
NameTypeDescription
providerTracerProvider

A registered tracer provider.

(inner) requestSpan(req, res, next)

The requestSpan middleware creates a root span for the request. The root span is set as the active span for the remaining middleware and route handler.

The span name and http.route attribute are assigned from the matched express route once the response is closed.

The faas.coldstart attribute is true for the first request of the process.

Parameters:
NameTypeDescription
reqreq

HTTP request.

resres

HTTP response.

nextfunction

Next middleware.

(inner) setRequestAttributes(attributes)

Assigns attributes to the root span of the current request. Attributes on the root span allow requests to be grouped by eg. the query template or workspace key.

Parameters:
NameTypeDescription
attributesObject

Span attributes.

(inner) srcAttribute(src) → {String}

Returns the src reference without query string to prevent keys and signatures being recorded in span attributes.

Parameters:
NameTypeDescription
srcString

Source reference.

Returns:

Source reference without query string.

Type: 
String

(inner) waitUntil(promise)

Keeps a Vercel function alive until the promise settles, after the response has been sent.

The method is an inline copy of the waitUntil method from the @vercel/functions package (v3.9). The Vercel runtime exposes the request context on the global @vercel/request-context symbol. This is an undocumented implementation detail of the Vercel runtime.

If Vercel changes how the request context is exposed, spans will silently no longer be flushed in Vercel deployments. The @vercel/functions dependency must then be added and its waitUntil method imported in place of this method.

The method is a no-op outside of a Vercel request context.

Parameters:
NameTypeDescription
promisePromise

The promise to wait for.

(inner) withSpan(name, attributesopt, fn, optionsopt) → {Promise}

The withSpan method calls the fn method within an active span. Spans created within the fn method are children of the span.

The span is ended when the fn method resolves. The span status is set to error if the fn method throws or resolves to an Error. The XYZ API commonly returns rather than throws errors.

The error message and exception are not recorded if options.errorMessage is false, eg. for database errors whose message may contain query parameter values. The error code or name is recorded as the error.type attribute instead. The caller must log the error, since tracing is optional and traces may be sampled.

The fn method is called with a non-recording span if tracing is disabled.

Parameters:
NameTypeAttributesDescription
nameString

The span name.

attributesObject<optional>

Span attributes.

fnfunction

The method to call within the span. The span is provided as argument.

optionsObject<optional>
Properties
NameTypeAttributesDefaultDescription
options.errorMessageBoolean<optional>
true

Record the error message and exception.

Returns:

The fn method result.

Type: 
Promise