Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@opentelemetry/instrumentation-http

Package Overview
Dependencies
Maintainers
3
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opentelemetry/instrumentation-http - npm Package Compare versions

Comparing version 0.54.2 to 0.55.0

build/src/internal-types.d.ts

11

build/src/http.d.ts

@@ -1,5 +0,2 @@

/// <reference types="node" />
import type * as http from 'http';
import * as url from 'url';
import { Func, HttpInstrumentationConfig, HttpRequestArgs } from './types';
import { HttpInstrumentationConfig } from './types';
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';

@@ -32,3 +29,3 @@ /**

*/
protected _getPatchIncomingRequestFunction(component: 'http' | 'https'): (original: (event: string, ...args: unknown[]) => boolean) => (this: unknown, event: string, ...args: unknown[]) => boolean;
private _getPatchIncomingRequestFunction;
/**

@@ -38,4 +35,4 @@ * Creates spans for outgoing requests, sending spans' context for distributed

*/
protected _getPatchOutgoingRequestFunction(component: 'http' | 'https'): (original: Func<http.ClientRequest>) => Func<http.ClientRequest>;
protected _getPatchOutgoingGetFunction(clientRequest: (options: http.RequestOptions | string | url.URL, ...args: HttpRequestArgs) => http.ClientRequest): (_original: Func<http.ClientRequest>) => Func<http.ClientRequest>;
private _getPatchOutgoingRequestFunction;
private _getPatchOutgoingGetFunction;
/** Patches HTTPS outgoing requests */

@@ -42,0 +39,0 @@ private _getPatchHttpsOutgoingRequestFunction;

@@ -39,3 +39,3 @@ "use strict";

this._headerCapture = this._createHeaderCapture();
for (const entry in (0, core_2.getEnv)().OTEL_SEMCONV_STABILITY_OPT_IN) {
for (const entry of (0, core_2.getEnv)().OTEL_SEMCONV_STABILITY_OPT_IN) {
if (entry.toLowerCase() === 'http/dup') {

@@ -369,3 +369,3 @@ // http/dup takes highest precedence. If it is found, there is no need to read the rest of the list

semconvStability: instrumentation._semconvStability,
});
}, instrumentation._diag);
const spanOptions = {

@@ -435,3 +435,3 @@ kind: api_1.SpanKind.SERVER,

: undefined;
const { method, optionsParsed } = (0, utils_1.getRequestInfo)(options, extraOptions);
const { method, invalidUrl, optionsParsed } = (0, utils_1.getRequestInfo)(instrumentation._diag, options, extraOptions);
/**

@@ -508,3 +508,13 @@ * Node 8's https module directly call the http one so to avoid creating

}
const request = (0, instrumentation_1.safeExecuteInTheMiddle)(() => original.apply(this, [optionsParsed, ...args]), error => {
const request = (0, instrumentation_1.safeExecuteInTheMiddle)(() => {
if (invalidUrl) {
// we know that the url is invalid, there's no point in injecting context as it will fail validation.
// Passing in what the user provided will give the user an error that matches what they'd see without
// the instrumentation.
return original.apply(this, [options, ...args]);
}
else {
return original.apply(this, [optionsParsed, ...args]);
}
}, error => {
if (error) {

@@ -511,0 +521,0 @@ (0, utils_1.setSpanWithError)(span, error, instrumentation._semconvStability);

export { HttpInstrumentation } from './http';
export { Err, Func, GetFunction, Http, HttpCallback, HttpCallbackOptional, HttpCustomAttributeFunction, HttpInstrumentationConfig, HttpRequestArgs, HttpRequestCustomAttributeFunction, HttpResponseCustomAttributeFunction, Https, IgnoreIncomingRequestFunction, IgnoreMatcher, IgnoreOutgoingRequestFunction, ParsedRequestOptions, RequestFunction, RequestSignature, StartIncomingSpanCustomAttributeFunction, StartOutgoingSpanCustomAttributeFunction, } from './types';
export { extractHostnameAndPort, getAbsoluteUrl, getIncomingRequestAttributes, getIncomingRequestAttributesOnResponse, getIncomingRequestMetricAttributes, getIncomingRequestMetricAttributesOnResponse, getOutgoingRequestAttributes, getOutgoingRequestAttributesOnResponse, getOutgoingRequestMetricAttributes, getOutgoingRequestMetricAttributesOnResponse, getRequestInfo, headerCapture, isCompressed, isValidOptionsType, parseResponseStatus, satisfiesPattern, setAttributesFromHttpKind, setRequestContentLengthAttribute, setResponseContentLengthAttribute, setSpanWithError, } from './utils';
export { HttpCustomAttributeFunction, HttpInstrumentationConfig, HttpRequestCustomAttributeFunction, HttpResponseCustomAttributeFunction, IgnoreIncomingRequestFunction, IgnoreOutgoingRequestFunction, StartIncomingSpanCustomAttributeFunction, StartOutgoingSpanCustomAttributeFunction, } from './types';
//# sourceMappingURL=index.d.ts.map

@@ -18,26 +18,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.setSpanWithError = exports.setResponseContentLengthAttribute = exports.setRequestContentLengthAttribute = exports.setAttributesFromHttpKind = exports.satisfiesPattern = exports.parseResponseStatus = exports.isValidOptionsType = exports.isCompressed = exports.headerCapture = exports.getRequestInfo = exports.getOutgoingRequestMetricAttributesOnResponse = exports.getOutgoingRequestMetricAttributes = exports.getOutgoingRequestAttributesOnResponse = exports.getOutgoingRequestAttributes = exports.getIncomingRequestMetricAttributesOnResponse = exports.getIncomingRequestMetricAttributes = exports.getIncomingRequestAttributesOnResponse = exports.getIncomingRequestAttributes = exports.getAbsoluteUrl = exports.extractHostnameAndPort = exports.HttpInstrumentation = void 0;
exports.HttpInstrumentation = void 0;
var http_1 = require("./http");
Object.defineProperty(exports, "HttpInstrumentation", { enumerable: true, get: function () { return http_1.HttpInstrumentation; } });
var utils_1 = require("./utils");
Object.defineProperty(exports, "extractHostnameAndPort", { enumerable: true, get: function () { return utils_1.extractHostnameAndPort; } });
Object.defineProperty(exports, "getAbsoluteUrl", { enumerable: true, get: function () { return utils_1.getAbsoluteUrl; } });
Object.defineProperty(exports, "getIncomingRequestAttributes", { enumerable: true, get: function () { return utils_1.getIncomingRequestAttributes; } });
Object.defineProperty(exports, "getIncomingRequestAttributesOnResponse", { enumerable: true, get: function () { return utils_1.getIncomingRequestAttributesOnResponse; } });
Object.defineProperty(exports, "getIncomingRequestMetricAttributes", { enumerable: true, get: function () { return utils_1.getIncomingRequestMetricAttributes; } });
Object.defineProperty(exports, "getIncomingRequestMetricAttributesOnResponse", { enumerable: true, get: function () { return utils_1.getIncomingRequestMetricAttributesOnResponse; } });
Object.defineProperty(exports, "getOutgoingRequestAttributes", { enumerable: true, get: function () { return utils_1.getOutgoingRequestAttributes; } });
Object.defineProperty(exports, "getOutgoingRequestAttributesOnResponse", { enumerable: true, get: function () { return utils_1.getOutgoingRequestAttributesOnResponse; } });
Object.defineProperty(exports, "getOutgoingRequestMetricAttributes", { enumerable: true, get: function () { return utils_1.getOutgoingRequestMetricAttributes; } });
Object.defineProperty(exports, "getOutgoingRequestMetricAttributesOnResponse", { enumerable: true, get: function () { return utils_1.getOutgoingRequestMetricAttributesOnResponse; } });
Object.defineProperty(exports, "getRequestInfo", { enumerable: true, get: function () { return utils_1.getRequestInfo; } });
Object.defineProperty(exports, "headerCapture", { enumerable: true, get: function () { return utils_1.headerCapture; } });
Object.defineProperty(exports, "isCompressed", { enumerable: true, get: function () { return utils_1.isCompressed; } });
Object.defineProperty(exports, "isValidOptionsType", { enumerable: true, get: function () { return utils_1.isValidOptionsType; } });
Object.defineProperty(exports, "parseResponseStatus", { enumerable: true, get: function () { return utils_1.parseResponseStatus; } });
Object.defineProperty(exports, "satisfiesPattern", { enumerable: true, get: function () { return utils_1.satisfiesPattern; } });
Object.defineProperty(exports, "setAttributesFromHttpKind", { enumerable: true, get: function () { return utils_1.setAttributesFromHttpKind; } });
Object.defineProperty(exports, "setRequestContentLengthAttribute", { enumerable: true, get: function () { return utils_1.setRequestContentLengthAttribute; } });
Object.defineProperty(exports, "setResponseContentLengthAttribute", { enumerable: true, get: function () { return utils_1.setResponseContentLengthAttribute; } });
Object.defineProperty(exports, "setSpanWithError", { enumerable: true, get: function () { return utils_1.setSpanWithError; } });
//# sourceMappingURL=index.js.map
/// <reference types="node" />
import { Span, Attributes } from '@opentelemetry/api';
import type * as http from 'http';
import type * as https from 'https';
import { ClientRequest, get, IncomingMessage, request, ServerResponse, RequestOptions } from 'http';
import * as url from 'url';
import { ClientRequest, IncomingMessage, ServerResponse, RequestOptions } from 'http';
import { InstrumentationConfig } from '@opentelemetry/instrumentation';
export declare type IgnoreMatcher = string | RegExp | ((url: string) => boolean);
export declare type HttpCallback = (res: IncomingMessage) => void;
export declare type RequestFunction = typeof request;
export declare type GetFunction = typeof get;
export declare type HttpCallbackOptional = HttpCallback | undefined;
export declare type RequestSignature = [http.RequestOptions, HttpCallbackOptional] & HttpCallback;
export declare type HttpRequestArgs = Array<HttpCallbackOptional | RequestSignature>;
export declare type ParsedRequestOptions = (http.RequestOptions & Partial<url.UrlWithParsedQuery>) | http.RequestOptions;
export declare type Http = typeof http;
export declare type Https = typeof https;
export declare type Func<T> = (...args: any[]) => T;
export interface HttpCustomAttributeFunction {

@@ -80,23 +66,2 @@ (span: Span, request: ClientRequest | IncomingMessage, response: IncomingMessage | ServerResponse): void;

}
export interface Err extends Error {
errno?: number;
code?: string;
path?: string;
syscall?: string;
stack?: string;
}
/**
* Tracks whether this instrumentation emits old experimental,
* new stable, or both semantic conventions.
*
* Enum values chosen such that the enum may be used as a bitmask.
*/
export declare const enum SemconvStability {
/** Emit only stable semantic conventions */
STABLE = 1,
/** Emit only old semantic convetions */
OLD = 2,
/** Emit both stable and old semantic convetions */
DUPLICATE = 3
}
//# sourceMappingURL=types.d.ts.map
/// <reference types="node" />
import { Attributes, SpanStatusCode, Span, SpanKind } from '@opentelemetry/api';
import { Attributes, SpanStatusCode, Span, SpanKind, DiagLogger } from '@opentelemetry/api';
import { IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders, RequestOptions, ServerResponse } from 'http';
import * as url from 'url';
import { Err, IgnoreMatcher, ParsedRequestOptions, SemconvStability } from './types';
import { Err, IgnoreMatcher, ParsedRequestOptions, SemconvStability } from './internal-types';
/**

@@ -45,9 +45,11 @@ * Get an absolute url

* return an object with default value and parsed options
* @param logger component logger
* @param options original options for the request
* @param [extraOptions] additional options for the request
*/
export declare const getRequestInfo: (options: url.URL | RequestOptions | string, extraOptions?: RequestOptions | undefined) => {
export declare const getRequestInfo: (logger: DiagLogger, options: url.URL | RequestOptions | string, extraOptions?: RequestOptions | undefined) => {
origin: string;
pathname: string;
method: string;
invalidUrl: boolean;
optionsParsed: RequestOptions;

@@ -113,3 +115,3 @@ };

semconvStability: SemconvStability;
}) => Attributes;
}, logger: DiagLogger) => Attributes;
/**

@@ -116,0 +118,0 @@ * Returns incoming request Metric attributes scoped to the request data

@@ -150,14 +150,61 @@ "use strict";

/**
* Mimics Node.js conversion of URL strings to RequestOptions expected by
* `http.request` and `https.request` APIs.
*
* See https://github.com/nodejs/node/blob/2505e217bba05fc581b572c685c5cf280a16c5a3/lib/internal/url.js#L1415-L1437
*
* @param stringUrl
* @throws TypeError if the URL is not valid.
*/
function stringUrlToHttpOptions(stringUrl) {
// This is heavily inspired by Node.js handling of the same situation, trying
// to follow it as closely as possible while keeping in mind that we only
// deal with string URLs, not URL objects.
const { hostname, pathname, port, username, password, search, protocol, hash, href, origin, host, } = new URL(stringUrl);
const options = {
protocol: protocol,
hostname: hostname && hostname[0] === '[' ? hostname.slice(1, -1) : hostname,
hash: hash,
search: search,
pathname: pathname,
path: `${pathname || ''}${search || ''}`,
href: href,
origin: origin,
host: host,
};
if (port !== '') {
options.port = Number(port);
}
if (username || password) {
options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}`;
}
return options;
}
/**
* Makes sure options is an url object
* return an object with default value and parsed options
* @param logger component logger
* @param options original options for the request
* @param [extraOptions] additional options for the request
*/
const getRequestInfo = (options, extraOptions) => {
let pathname = '/';
let origin = '';
const getRequestInfo = (logger, options, extraOptions) => {
let pathname;
let origin;
let optionsParsed;
let invalidUrl = false;
if (typeof options === 'string') {
optionsParsed = url.parse(options);
pathname = optionsParsed.pathname || '/';
try {
const convertedOptions = stringUrlToHttpOptions(options);
optionsParsed = convertedOptions;
pathname = convertedOptions.pathname || '/';
}
catch (e) {
invalidUrl = true;
logger.verbose('Unable to parse URL provided to HTTP request, using fallback to determine path. Original error:', e);
// for backward compatibility with how url.parse() behaved.
optionsParsed = {
path: options,
};
pathname = optionsParsed.path || '/';
}
origin = `${optionsParsed.protocol || 'http:'}//${optionsParsed.host}`;

@@ -190,6 +237,2 @@ if (extraOptions !== undefined) {

optionsParsed = Object.assign({ protocol: options.host ? 'http:' : undefined }, options);
pathname = options.pathname;
if (!pathname && optionsParsed.path) {
pathname = url.parse(optionsParsed.path).pathname || '/';
}
const hostname = optionsParsed.host ||

@@ -200,2 +243,12 @@ (optionsParsed.port != null

origin = `${optionsParsed.protocol || 'http:'}//${hostname}`;
pathname = options.pathname;
if (!pathname && optionsParsed.path) {
try {
const parsedUrl = new URL(optionsParsed.path, origin);
pathname = parsedUrl.pathname || '/';
}
catch (e) {
pathname = '/';
}
}
}

@@ -207,3 +260,3 @@ // some packages return method in lowercase..

: 'GET';
return { origin, pathname, method, optionsParsed };
return { origin, pathname, method, optionsParsed, invalidUrl };
};

@@ -483,2 +536,31 @@ exports.getRequestInfo = getRequestInfo;

exports.getRemoteClientAddress = getRemoteClientAddress;
function getInfoFromIncomingMessage(component, request, logger) {
var _a, _b;
try {
if (request.headers.host) {
return new URL((_a = request.url) !== null && _a !== void 0 ? _a : '/', `${component}://${request.headers.host}`);
}
else {
const unsafeParsedUrl = new URL((_b = request.url) !== null && _b !== void 0 ? _b : '/',
// using localhost as a workaround to still use the URL constructor for parsing
`${component}://localhost`);
// since we use localhost as a workaround, ensure we hide the rest of the properties to avoid
// our workaround leaking though.
return {
pathname: unsafeParsedUrl.pathname,
search: unsafeParsedUrl.search,
toString: function () {
// we cannot use the result of unsafeParsedUrl.toString as it's potentially wrong.
return unsafeParsedUrl.pathname + unsafeParsedUrl.search;
},
};
}
}
catch (e) {
// something is wrong, use undefined - this *should* never happen, logging
// for troubleshooting in case it does happen.
logger.verbose('Unable to get URL from request', e);
return {};
}
}
/**

@@ -490,3 +572,3 @@ * Returns incoming request attributes scoped to the request data

*/
const getIncomingRequestAttributes = (request, options) => {
const getIncomingRequestAttributes = (request, options, logger) => {
const headers = request.headers;

@@ -496,7 +578,4 @@ const userAgent = headers['user-agent'];

const httpVersion = request.httpVersion;
const requestUrl = request.url ? url.parse(request.url) : null;
const host = (requestUrl === null || requestUrl === void 0 ? void 0 : requestUrl.host) || headers.host;
const hostname = (requestUrl === null || requestUrl === void 0 ? void 0 : requestUrl.hostname) ||
(host === null || host === void 0 ? void 0 : host.replace(/^(.*)(:[0-9]{1,5})/, '$1')) ||
'localhost';
const host = headers.host;
const hostname = (host === null || host === void 0 ? void 0 : host.replace(/^(.*)(:[0-9]{1,5})/, '$1')) || 'localhost';
const method = request.method;

@@ -516,4 +595,5 @@ const normalizedMethod = normalizeMethod(method);

};
if ((requestUrl === null || requestUrl === void 0 ? void 0 : requestUrl.pathname) != null) {
newAttributes[semantic_conventions_1.ATTR_URL_PATH] = requestUrl.pathname;
const parsedUrl = getInfoFromIncomingMessage(options.component, request, logger);
if ((parsedUrl === null || parsedUrl === void 0 ? void 0 : parsedUrl.pathname) != null) {
newAttributes[semantic_conventions_1.ATTR_URL_PATH] = parsedUrl.pathname;
}

@@ -531,3 +611,3 @@ if (remoteClientAddress != null) {

const oldAttributes = {
[semantic_conventions_1.SEMATTRS_HTTP_URL]: (0, exports.getAbsoluteUrl)(requestUrl, headers, `${options.component}:`),
[semantic_conventions_1.SEMATTRS_HTTP_URL]: parsedUrl.toString(),
[semantic_conventions_1.SEMATTRS_HTTP_HOST]: host,

@@ -544,4 +624,5 @@ [semantic_conventions_1.SEMATTRS_NET_HOST_NAME]: hostname,

}
if (requestUrl) {
oldAttributes[semantic_conventions_1.SEMATTRS_HTTP_TARGET] = requestUrl.path || '/';
if (parsedUrl === null || parsedUrl === void 0 ? void 0 : parsedUrl.pathname) {
oldAttributes[semantic_conventions_1.SEMATTRS_HTTP_TARGET] =
(parsedUrl === null || parsedUrl === void 0 ? void 0 : parsedUrl.pathname) + (parsedUrl === null || parsedUrl === void 0 ? void 0 : parsedUrl.search) || '/';
}

@@ -548,0 +629,0 @@ if (userAgent !== undefined) {

@@ -1,2 +0,2 @@

export declare const VERSION = "0.54.2";
export declare const VERSION = "0.55.0";
//# sourceMappingURL=version.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

// this is autogenerated file, see scripts/version-update.js
exports.VERSION = '0.54.2';
exports.VERSION = '0.55.0';
//# sourceMappingURL=version.js.map
{
"name": "@opentelemetry/instrumentation-http",
"version": "0.54.2",
"version": "0.55.0",
"description": "OpenTelemetry instrumentation for `node:http` and `node:https` http client and server modules",

@@ -52,7 +52,7 @@ "main": "build/src/index.js",

"@opentelemetry/api": "1.9.0",
"@opentelemetry/context-async-hooks": "1.27.0",
"@opentelemetry/sdk-metrics": "1.27.0",
"@opentelemetry/sdk-trace-base": "1.27.0",
"@opentelemetry/sdk-trace-node": "1.27.0",
"@types/mocha": "10.0.8",
"@opentelemetry/context-async-hooks": "1.28.0",
"@opentelemetry/sdk-metrics": "1.28.0",
"@opentelemetry/sdk-trace-base": "1.28.0",
"@opentelemetry/sdk-trace-node": "1.28.0",
"@types/mocha": "10.0.9",
"@types/node": "18.6.5",

@@ -66,3 +66,3 @@ "@types/request-promise-native": "1.0.21",

"lerna": "6.6.2",
"mocha": "10.7.3",
"mocha": "10.8.2",
"nock": "13.3.8",

@@ -80,4 +80,4 @@ "nyc": "15.1.0",

"dependencies": {
"@opentelemetry/core": "1.27.0",
"@opentelemetry/instrumentation": "0.54.2",
"@opentelemetry/core": "1.28.0",
"@opentelemetry/instrumentation": "0.55.0",
"@opentelemetry/semantic-conventions": "1.27.0",

@@ -89,3 +89,3 @@ "forwarded-parse": "2.1.2",

"sideEffects": false,
"gitHead": "72c9af91983e4b7aade98c901bd45c6cefee0da4"
"gitHead": "4b1ad3fda0cde58907e30fab25c3c767546708e5"
}

@@ -38,5 +38,6 @@ # OpenTelemetry HTTP and HTTPS Instrumentation for Node.js

const provider = new NodeTracerProvider();
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]
});
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.register();

@@ -43,0 +44,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc