OpenTelemetry instrumentation for Node.js HTTP and HTTPS modules enabling automatic telemetry collection for client and server operations
npx @tessl/cli install tessl/npm-opentelemetry--instrumentation-http@0.204.0OpenTelemetry HTTP Instrumentation provides automatic telemetry collection for Node.js http and https modules. It captures distributed tracing data for both client requests and server operations, enabling comprehensive observability for HTTP communications with extensive configuration options.
npm install @opentelemetry/instrumentation-httpimport { HttpInstrumentation } from "@opentelemetry/instrumentation-http";For CommonJS:
const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");For configuration types:
import {
HttpInstrumentation,
type HttpInstrumentationConfig,
type HttpCustomAttributeFunction,
type IgnoreIncomingRequestFunction,
type IgnoreOutgoingRequestFunction
} from "@opentelemetry/instrumentation-http";import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
// Basic setup with default configuration
registerInstrumentations({
instrumentations: [
new HttpInstrumentation()
],
});
// With custom configuration
registerInstrumentations({
instrumentations: [
new HttpInstrumentation({
// Ignore health check endpoints
ignoreIncomingRequestHook: (req) => {
return req.url?.includes('/health') === true;
},
// Add custom attributes to spans
requestHook: (span, request) => {
span.setAttribute('custom.user_agent',
request.headers['user-agent'] || 'unknown');
},
// Capture specific headers as span attributes
headersToSpanAttributes: {
client: {
requestHeaders: ['authorization', 'content-type'],
responseHeaders: ['content-type', 'server']
},
server: {
requestHeaders: ['user-agent', 'referer'],
responseHeaders: ['content-type']
}
}
})
],
});OpenTelemetry HTTP Instrumentation operates by monkey-patching Node.js built-in HTTP modules to automatically inject telemetry collection:
http and https modules at the Node.js levelMain instrumentation class that handles automatic HTTP telemetry collection for both client and server operations.
class HttpInstrumentation extends InstrumentationBase<HttpInstrumentationConfig> {
constructor(config?: HttpInstrumentationConfig);
}Comprehensive configuration interface for customizing HTTP instrumentation behavior including request filtering, custom attributes, and telemetry options.
interface HttpInstrumentationConfig extends InstrumentationConfig {
ignoreIncomingRequestHook?: IgnoreIncomingRequestFunction;
ignoreOutgoingRequestHook?: IgnoreOutgoingRequestFunction;
disableIncomingRequestInstrumentation?: boolean;
disableOutgoingRequestInstrumentation?: boolean;
applyCustomAttributesOnSpan?: HttpCustomAttributeFunction;
requestHook?: HttpRequestCustomAttributeFunction;
responseHook?: HttpResponseCustomAttributeFunction;
startIncomingSpanHook?: StartIncomingSpanCustomAttributeFunction;
startOutgoingSpanHook?: StartOutgoingSpanCustomAttributeFunction;
serverName?: string;
requireParentforOutgoingSpans?: boolean;
requireParentforIncomingSpans?: boolean;
headersToSpanAttributes?: {
client?: { requestHeaders?: string[]; responseHeaders?: string[] };
server?: { requestHeaders?: string[]; responseHeaders?: string[] };
};
enableSyntheticSourceDetection?: boolean;
redactedQueryParams?: string[];
}Custom function interfaces for filtering requests and adding custom attributes during HTTP instrumentation lifecycle events.
interface IgnoreIncomingRequestFunction {
(request: IncomingMessage): boolean;
}
interface IgnoreOutgoingRequestFunction {
(request: RequestOptions): boolean;
}
interface HttpCustomAttributeFunction {
(
span: Span,
request: ClientRequest | IncomingMessage,
response: IncomingMessage | ServerResponse
): void;
}The following types are from external modules used in the API signatures:
// From @opentelemetry/api
interface Span {
setAttribute(key: string, value: string | number | boolean | Array<string | number | boolean>): this;
setStatus(status: { code: SpanStatusCode; message?: string }): this;
recordException(exception: Exception): void;
end(endTime?: TimeInput): void;
startTime: [number, number];
}
enum SpanStatusCode {
UNSET = 0,
OK = 1,
ERROR = 2
}
type Exception = Error | string;
type TimeInput = [number, number] | number | Date;
interface Attributes {
[key: string]: string | number | boolean | Array<string | number | boolean> | null | undefined;
}
// From @opentelemetry/instrumentation
class InstrumentationBase<T = any> {
constructor(instrumentationName: string, instrumentationVersion: string, config?: T);
enable(): void;
disable(): void;
setConfig(config: T): void;
getConfig(): T;
init(): InstrumentationNodeModuleDefinition[];
}
interface InstrumentationConfig {
enabled?: boolean;
}
interface InstrumentationNodeModuleDefinition {
name: string;
moduleExports?: any;
moduleVersion?: string;
patch?: Function;
unpatch?: Function;
}
// From Node.js 'http' module
interface IncomingMessage {
headers: { [key: string]: string | string[] | undefined };
method?: string;
url?: string;
statusCode?: number;
httpVersion: string;
socket: {
remoteAddress?: string;
remotePort?: number;
};
}
interface ServerResponse {
statusCode?: number;
statusMessage?: string;
headers: { [key: string]: string | string[] | undefined };
writeHead(statusCode: number, headers?: { [key: string]: string | string[] }): this;
end(chunk?: any, encoding?: BufferEncoding, cb?: () => void): void;
}
interface ClientRequest {
method?: string;
path?: string;
host?: string;
headers: { [key: string]: string | string[] | undefined };
timeout?: number;
}
interface RequestOptions {
hostname?: string;
host?: string;
port?: number;
method?: string;
path?: string;
headers?: { [key: string]: string | string[] | undefined };
timeout?: number;
}interface HttpInstrumentationConfig extends InstrumentationConfig {
ignoreIncomingRequestHook?: IgnoreIncomingRequestFunction;
ignoreOutgoingRequestHook?: IgnoreOutgoingRequestFunction;
disableIncomingRequestInstrumentation?: boolean;
disableOutgoingRequestInstrumentation?: boolean;
applyCustomAttributesOnSpan?: HttpCustomAttributeFunction;
requestHook?: HttpRequestCustomAttributeFunction;
responseHook?: HttpResponseCustomAttributeFunction;
startIncomingSpanHook?: StartIncomingSpanCustomAttributeFunction;
startOutgoingSpanHook?: StartOutgoingSpanCustomAttributeFunction;
serverName?: string;
requireParentforOutgoingSpans?: boolean;
requireParentforIncomingSpans?: boolean;
headersToSpanAttributes?: {
client?: { requestHeaders?: string[]; responseHeaders?: string[] };
server?: { requestHeaders?: string[]; responseHeaders?: string[] };
};
enableSyntheticSourceDetection?: boolean;
redactedQueryParams?: string[];
}
interface IgnoreIncomingRequestFunction {
(request: IncomingMessage): boolean;
}
interface IgnoreOutgoingRequestFunction {
(request: RequestOptions): boolean;
}
interface HttpCustomAttributeFunction {
(
span: Span,
request: ClientRequest | IncomingMessage,
response: IncomingMessage | ServerResponse
): void;
}
interface HttpRequestCustomAttributeFunction {
(span: Span, request: ClientRequest | IncomingMessage): void;
}
interface HttpResponseCustomAttributeFunction {
(span: Span, response: IncomingMessage | ServerResponse): void;
}
interface StartIncomingSpanCustomAttributeFunction {
(request: IncomingMessage): Attributes;
}
interface StartOutgoingSpanCustomAttributeFunction {
(request: RequestOptions): Attributes;
}