feat: Complete zCode CLI X with Telegram bot integration

- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
This commit is contained in:
admin
2026-05-05 09:01:26 +00:00
Unverified
parent 4a7035dd92
commit 875c7f9b91
24688 changed files with 3224957 additions and 221 deletions

View File

@@ -0,0 +1,15 @@
import type { ExportResult } from '@opentelemetry/core';
import type { IOtlpExportDelegate } from './otlp-export-delegate';
export declare class OTLPExporterBase<Internal> {
private _delegate;
constructor(delegate: IOtlpExportDelegate<Internal>);
/**
* Export items.
* @param items
* @param resultCallback
*/
export(items: Internal, resultCallback: (result: ExportResult) => void): void;
forceFlush(): Promise<void>;
shutdown(): Promise<void>;
}
//# sourceMappingURL=OTLPExporterBase.d.ts.map

View File

@@ -0,0 +1,29 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.OTLPExporterBase = void 0;
class OTLPExporterBase {
_delegate;
constructor(delegate) {
this._delegate = delegate;
}
/**
* Export items.
* @param items
* @param resultCallback
*/
export(items, resultCallback) {
this._delegate.export(items, resultCallback);
}
forceFlush() {
return this._delegate.forceFlush();
}
shutdown() {
return this._delegate.shutdown();
}
}
exports.OTLPExporterBase = OTLPExporterBase;
//# sourceMappingURL=OTLPExporterBase.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"OTLPExporterBase.js","sourceRoot":"","sources":["../../src/OTLPExporterBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAKH,MAAa,gBAAgB;IACnB,SAAS,CAAgC;IACjD,YAAY,QAAuC;QACjD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,MAAM,CACJ,KAAe,EACf,cAA8C;QAE9C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC/C,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;IACrC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC;CACF;AAzBD,4CAyBC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ExportResult } from '@opentelemetry/core';\nimport type { IOtlpExportDelegate } from './otlp-export-delegate';\n\nexport class OTLPExporterBase<Internal> {\n private _delegate: IOtlpExportDelegate<Internal>;\n constructor(delegate: IOtlpExportDelegate<Internal>) {\n this._delegate = delegate;\n }\n\n /**\n * Export items.\n * @param items\n * @param resultCallback\n */\n export(\n items: Internal,\n resultCallback: (result: ExportResult) => void\n ): void {\n this._delegate.export(items, resultCallback);\n }\n\n forceFlush(): Promise<void> {\n return this._delegate.forceFlush();\n }\n\n shutdown(): Promise<void> {\n return this._delegate.shutdown();\n }\n}\n"]}

View File

@@ -0,0 +1,13 @@
export interface IExportPromiseHandler {
pushPromise(promise: Promise<void>): void;
hasReachedLimit(): boolean;
awaitAll(): Promise<void>;
}
/**
* Promise queue for keeping track of export promises. Finished promises will be auto-dequeued.
* Allows for awaiting all promises in the queue.
*/
export declare function createBoundedQueueExportPromiseHandler(options: {
concurrencyLimit: number;
}): IExportPromiseHandler;
//# sourceMappingURL=bounded-queue-export-promise-handler.d.ts.map

View File

@@ -0,0 +1,43 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBoundedQueueExportPromiseHandler = void 0;
class BoundedQueueExportPromiseHandler {
_concurrencyLimit;
_sendingPromises = [];
/**
* @param concurrencyLimit maximum promises allowed in a queue at the same time.
*/
constructor(concurrencyLimit) {
this._concurrencyLimit = concurrencyLimit;
}
pushPromise(promise) {
if (this.hasReachedLimit()) {
throw new Error('Concurrency Limit reached');
}
this._sendingPromises.push(promise);
const popPromise = () => {
const index = this._sendingPromises.indexOf(promise);
void this._sendingPromises.splice(index, 1);
};
promise.then(popPromise, popPromise);
}
hasReachedLimit() {
return this._sendingPromises.length >= this._concurrencyLimit;
}
async awaitAll() {
await Promise.all(this._sendingPromises);
}
}
/**
* Promise queue for keeping track of export promises. Finished promises will be auto-dequeued.
* Allows for awaiting all promises in the queue.
*/
function createBoundedQueueExportPromiseHandler(options) {
return new BoundedQueueExportPromiseHandler(options.concurrencyLimit);
}
exports.createBoundedQueueExportPromiseHandler = createBoundedQueueExportPromiseHandler;
//# sourceMappingURL=bounded-queue-export-promise-handler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"bounded-queue-export-promise-handler.js","sourceRoot":"","sources":["../../src/bounded-queue-export-promise-handler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,MAAM,gCAAgC;IACnB,iBAAiB,CAAS;IACnC,gBAAgB,GAAuB,EAAE,CAAC;IAElD;;OAEG;IACH,YAAY,gBAAwB;QAClC,IAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;IAC5C,CAAC;IAEM,WAAW,CAAC,OAAsB;QACvC,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;SAC9C;QAED,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrD,KAAK,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,IAAI,CAAC,iBAAiB,CAAC;IAChE,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC;CACF;AAED;;;GAGG;AACH,SAAgB,sCAAsC,CAAC,OAEtD;IACC,OAAO,IAAI,gCAAgC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;AACxE,CAAC;AAJD,wFAIC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface IExportPromiseHandler {\n pushPromise(promise: Promise<void>): void;\n hasReachedLimit(): boolean;\n awaitAll(): Promise<void>;\n}\n\nclass BoundedQueueExportPromiseHandler implements IExportPromiseHandler {\n private readonly _concurrencyLimit: number;\n private _sendingPromises: Promise<unknown>[] = [];\n\n /**\n * @param concurrencyLimit maximum promises allowed in a queue at the same time.\n */\n constructor(concurrencyLimit: number) {\n this._concurrencyLimit = concurrencyLimit;\n }\n\n public pushPromise(promise: Promise<void>): void {\n if (this.hasReachedLimit()) {\n throw new Error('Concurrency Limit reached');\n }\n\n this._sendingPromises.push(promise);\n const popPromise = () => {\n const index = this._sendingPromises.indexOf(promise);\n void this._sendingPromises.splice(index, 1);\n };\n promise.then(popPromise, popPromise);\n }\n\n public hasReachedLimit(): boolean {\n return this._sendingPromises.length >= this._concurrencyLimit;\n }\n\n public async awaitAll(): Promise<void> {\n await Promise.all(this._sendingPromises);\n }\n}\n\n/**\n * Promise queue for keeping track of export promises. Finished promises will be auto-dequeued.\n * Allows for awaiting all promises in the queue.\n */\nexport function createBoundedQueueExportPromiseHandler(options: {\n concurrencyLimit: number;\n}): IExportPromiseHandler {\n return new BoundedQueueExportPromiseHandler(options.concurrencyLimit);\n}\n"]}

View File

@@ -0,0 +1,11 @@
import type { OtlpHttpConfiguration } from './otlp-http-configuration';
import type { OTLPExporterNodeConfigBase } from './legacy-node-configuration';
/**
* @deprecated this will be removed in 2.0
*
* @param config
* @param signalResourcePath
* @param requiredHeaders
*/
export declare function convertLegacyBrowserHttpOptions(config: OTLPExporterNodeConfigBase, signalResourcePath: string, requiredHeaders: Record<string, string>): OtlpHttpConfiguration;
//# sourceMappingURL=convert-legacy-browser-http-options.d.ts.map

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertLegacyBrowserHttpOptions = void 0;
const otlp_http_configuration_1 = require("./otlp-http-configuration");
const convert_legacy_http_options_1 = require("./convert-legacy-http-options");
/**
* @deprecated this will be removed in 2.0
*
* @param config
* @param signalResourcePath
* @param requiredHeaders
*/
function convertLegacyBrowserHttpOptions(config, signalResourcePath, requiredHeaders) {
return (0, otlp_http_configuration_1.mergeOtlpHttpConfigurationWithDefaults)({
url: config.url,
timeoutMillis: config.timeoutMillis,
headers: (0, convert_legacy_http_options_1.convertLegacyHeaders)(config),
concurrencyLimit: config.concurrencyLimit,
}, {}, // no fallback for browser case
(0, otlp_http_configuration_1.getHttpConfigurationDefaults)(requiredHeaders, signalResourcePath));
}
exports.convertLegacyBrowserHttpOptions = convertLegacyBrowserHttpOptions;
//# sourceMappingURL=convert-legacy-browser-http-options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"convert-legacy-browser-http-options.js","sourceRoot":"","sources":["../../../src/configuration/convert-legacy-browser-http-options.ts"],"names":[],"mappings":";;;AAKA,uEAGmC;AAEnC,+EAAqE;AAErE;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAC7C,MAAkC,EAClC,kBAA0B,EAC1B,eAAuC;IAEvC,OAAO,IAAA,gEAAsC,EAC3C;QACE,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,OAAO,EAAE,IAAA,kDAAoB,EAAC,MAAM,CAAC;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,EACD,EAAE,EAAE,+BAA+B;IACnC,IAAA,sDAA4B,EAAC,eAAe,EAAE,kBAAkB,CAAC,CAClE,CAAC;AACJ,CAAC;AAfD,0EAeC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { OtlpHttpConfiguration } from './otlp-http-configuration';\nimport {\n getHttpConfigurationDefaults,\n mergeOtlpHttpConfigurationWithDefaults,\n} from './otlp-http-configuration';\nimport type { OTLPExporterNodeConfigBase } from './legacy-node-configuration';\nimport { convertLegacyHeaders } from './convert-legacy-http-options';\n\n/**\n * @deprecated this will be removed in 2.0\n *\n * @param config\n * @param signalResourcePath\n * @param requiredHeaders\n */\nexport function convertLegacyBrowserHttpOptions(\n config: OTLPExporterNodeConfigBase,\n signalResourcePath: string,\n requiredHeaders: Record<string, string>\n): OtlpHttpConfiguration {\n return mergeOtlpHttpConfigurationWithDefaults(\n {\n url: config.url,\n timeoutMillis: config.timeoutMillis,\n headers: convertLegacyHeaders(config),\n concurrencyLimit: config.concurrencyLimit,\n },\n {}, // no fallback for browser case\n getHttpConfigurationDefaults(requiredHeaders, signalResourcePath)\n );\n}\n"]}

View File

@@ -0,0 +1,4 @@
import type { OTLPExporterConfigBase } from './legacy-base-configuration';
import type { HeadersFactory } from './otlp-http-configuration';
export declare function convertLegacyHeaders(config: OTLPExporterConfigBase): HeadersFactory | undefined;
//# sourceMappingURL=convert-legacy-http-options.d.ts.map

View File

@@ -0,0 +1,16 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertLegacyHeaders = void 0;
const shared_configuration_1 = require("./shared-configuration");
function convertLegacyHeaders(config) {
if (typeof config.headers === 'function') {
return config.headers;
}
return (0, shared_configuration_1.wrapStaticHeadersInFunction)(config.headers);
}
exports.convertLegacyHeaders = convertLegacyHeaders;
//# sourceMappingURL=convert-legacy-http-options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"convert-legacy-http-options.js","sourceRoot":"","sources":["../../../src/configuration/convert-legacy-http-options.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iEAAqE;AAGrE,SAAgB,oBAAoB,CAClC,MAA8B;IAE9B,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE;QACxC,OAAO,MAAM,CAAC,OAAO,CAAC;KACvB;IACD,OAAO,IAAA,kDAA2B,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACrD,CAAC;AAPD,oDAOC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { OTLPExporterConfigBase } from './legacy-base-configuration';\nimport { wrapStaticHeadersInFunction } from './shared-configuration';\nimport type { HeadersFactory } from './otlp-http-configuration';\n\nexport function convertLegacyHeaders(\n config: OTLPExporterConfigBase\n): HeadersFactory | undefined {\n if (typeof config.headers === 'function') {\n return config.headers;\n }\n return wrapStaticHeadersInFunction(config.headers);\n}\n"]}

View File

@@ -0,0 +1,11 @@
import type { OTLPExporterNodeConfigBase } from './legacy-node-configuration';
import type { OtlpNodeHttpConfiguration } from './otlp-node-http-configuration';
/**
* @deprecated this will be removed in 2.0
* @param config
* @param signalIdentifier
* @param signalResourcePath
* @param requiredHeaders
*/
export declare function convertLegacyHttpOptions(config: OTLPExporterNodeConfigBase, signalIdentifier: string, signalResourcePath: string, requiredHeaders: Record<string, string>): OtlpNodeHttpConfiguration;
//# sourceMappingURL=convert-legacy-node-http-options.d.ts.map

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertLegacyHttpOptions = void 0;
const api_1 = require("@opentelemetry/api");
const otlp_node_http_configuration_1 = require("./otlp-node-http-configuration");
const index_node_http_1 = require("../index-node-http");
const otlp_node_http_env_configuration_1 = require("./otlp-node-http-env-configuration");
const convert_legacy_http_options_1 = require("./convert-legacy-http-options");
function convertLegacyAgentOptions(config) {
if (typeof config.httpAgentOptions === 'function') {
return config.httpAgentOptions;
}
let legacy = config.httpAgentOptions;
if (config.keepAlive != null) {
legacy = { keepAlive: config.keepAlive, ...legacy };
}
if (legacy != null) {
return (0, index_node_http_1.httpAgentFactoryFromOptions)(legacy);
}
else {
return undefined;
}
}
/**
* @deprecated this will be removed in 2.0
* @param config
* @param signalIdentifier
* @param signalResourcePath
* @param requiredHeaders
*/
function convertLegacyHttpOptions(config, signalIdentifier, signalResourcePath, requiredHeaders) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (config.metadata) {
api_1.diag.warn('Metadata cannot be set when using http');
}
return (0, otlp_node_http_configuration_1.mergeOtlpNodeHttpConfigurationWithDefaults)({
url: config.url,
headers: (0, convert_legacy_http_options_1.convertLegacyHeaders)(config),
concurrencyLimit: config.concurrencyLimit,
timeoutMillis: config.timeoutMillis,
compression: config.compression,
agentFactory: convertLegacyAgentOptions(config),
userAgent: config.userAgent,
}, (0, otlp_node_http_env_configuration_1.getNodeHttpConfigurationFromEnvironment)(signalIdentifier, signalResourcePath), (0, otlp_node_http_configuration_1.getNodeHttpConfigurationDefaults)(requiredHeaders, signalResourcePath));
}
exports.convertLegacyHttpOptions = convertLegacyHttpOptions;
//# sourceMappingURL=convert-legacy-node-http-options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"convert-legacy-node-http-options.js","sourceRoot":"","sources":["../../../src/configuration/convert-legacy-node-http-options.ts"],"names":[],"mappings":";;;AAKA,4CAA0C;AAK1C,iFAGwC;AACxC,wDAAiE;AACjE,yFAA6F;AAC7F,+EAAqE;AAErE,SAAS,yBAAyB,CAChC,MAAkC;IAElC,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,UAAU,EAAE;QACjD,OAAO,MAAM,CAAC,gBAAgB,CAAC;KAChC;IAED,IAAI,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACrC,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE;QAC5B,MAAM,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC;KACrD;IAED,IAAI,MAAM,IAAI,IAAI,EAAE;QAClB,OAAO,IAAA,6CAA2B,EAAC,MAAM,CAAC,CAAC;KAC5C;SAAM;QACL,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,wBAAwB,CACtC,MAAkC,EAClC,gBAAwB,EACxB,kBAA0B,EAC1B,eAAuC;IAEvC,8DAA8D;IAC9D,IAAK,MAAc,CAAC,QAAQ,EAAE;QAC5B,UAAI,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;KACrD;IAED,OAAO,IAAA,yEAA0C,EAC/C;QACE,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,OAAO,EAAE,IAAA,kDAAoB,EAAC,MAAM,CAAC;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,YAAY,EAAE,yBAAyB,CAAC,MAAM,CAAC;QAC/C,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,EACD,IAAA,0EAAuC,EACrC,gBAAgB,EAChB,kBAAkB,CACnB,EACD,IAAA,+DAAgC,EAAC,eAAe,EAAE,kBAAkB,CAAC,CACtE,CAAC;AACJ,CAAC;AA3BD,4DA2BC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { OTLPExporterNodeConfigBase } from './legacy-node-configuration';\nimport { diag } from '@opentelemetry/api';\nimport type {\n HttpAgentFactory,\n OtlpNodeHttpConfiguration,\n} from './otlp-node-http-configuration';\nimport {\n getNodeHttpConfigurationDefaults,\n mergeOtlpNodeHttpConfigurationWithDefaults,\n} from './otlp-node-http-configuration';\nimport { httpAgentFactoryFromOptions } from '../index-node-http';\nimport { getNodeHttpConfigurationFromEnvironment } from './otlp-node-http-env-configuration';\nimport { convertLegacyHeaders } from './convert-legacy-http-options';\n\nfunction convertLegacyAgentOptions(\n config: OTLPExporterNodeConfigBase\n): HttpAgentFactory | undefined {\n if (typeof config.httpAgentOptions === 'function') {\n return config.httpAgentOptions;\n }\n\n let legacy = config.httpAgentOptions;\n if (config.keepAlive != null) {\n legacy = { keepAlive: config.keepAlive, ...legacy };\n }\n\n if (legacy != null) {\n return httpAgentFactoryFromOptions(legacy);\n } else {\n return undefined;\n }\n}\n\n/**\n * @deprecated this will be removed in 2.0\n * @param config\n * @param signalIdentifier\n * @param signalResourcePath\n * @param requiredHeaders\n */\nexport function convertLegacyHttpOptions(\n config: OTLPExporterNodeConfigBase,\n signalIdentifier: string,\n signalResourcePath: string,\n requiredHeaders: Record<string, string>\n): OtlpNodeHttpConfiguration {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((config as any).metadata) {\n diag.warn('Metadata cannot be set when using http');\n }\n\n return mergeOtlpNodeHttpConfigurationWithDefaults(\n {\n url: config.url,\n headers: convertLegacyHeaders(config),\n concurrencyLimit: config.concurrencyLimit,\n timeoutMillis: config.timeoutMillis,\n compression: config.compression,\n agentFactory: convertLegacyAgentOptions(config),\n userAgent: config.userAgent,\n },\n getNodeHttpConfigurationFromEnvironment(\n signalIdentifier,\n signalResourcePath\n ),\n getNodeHttpConfigurationDefaults(requiredHeaders, signalResourcePath)\n );\n}\n"]}

View File

@@ -0,0 +1,12 @@
import type { ISerializer } from '@opentelemetry/otlp-transformer';
import type { IOtlpExportDelegate } from '../otlp-export-delegate';
import type { OTLPExporterConfigBase } from './legacy-base-configuration';
/**
* @deprecated
* @param config
* @param serializer
* @param signalResourcePath
* @param requiredHeaders
*/
export declare function createLegacyOtlpBrowserExportDelegate<Internal, Response>(config: OTLPExporterConfigBase, serializer: ISerializer<Internal, Response>, signalResourcePath: string, requiredHeaders: Record<string, string>): IOtlpExportDelegate<Internal>;
//# sourceMappingURL=create-legacy-browser-delegate.d.ts.map

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLegacyOtlpBrowserExportDelegate = void 0;
const otlp_browser_http_export_delegate_1 = require("../otlp-browser-http-export-delegate");
const convert_legacy_browser_http_options_1 = require("./convert-legacy-browser-http-options");
/**
* @deprecated
* @param config
* @param serializer
* @param signalResourcePath
* @param requiredHeaders
*/
function createLegacyOtlpBrowserExportDelegate(config, serializer, signalResourcePath, requiredHeaders) {
const options = (0, convert_legacy_browser_http_options_1.convertLegacyBrowserHttpOptions)(config, signalResourcePath, requiredHeaders);
return (0, otlp_browser_http_export_delegate_1.createOtlpFetchExportDelegate)(options, serializer);
}
exports.createLegacyOtlpBrowserExportDelegate = createLegacyOtlpBrowserExportDelegate;
//# sourceMappingURL=create-legacy-browser-delegate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"create-legacy-browser-delegate.js","sourceRoot":"","sources":["../../../src/configuration/create-legacy-browser-delegate.ts"],"names":[],"mappings":";;;AAKA,4FAAqF;AACrF,+FAAwF;AAIxF;;;;;;GAMG;AACH,SAAgB,qCAAqC,CACnD,MAA8B,EAC9B,UAA2C,EAC3C,kBAA0B,EAC1B,eAAuC;IAEvC,MAAM,OAAO,GAAG,IAAA,qEAA+B,EAC7C,MAAM,EACN,kBAAkB,EAClB,eAAe,CAChB,CAAC;IAEF,OAAO,IAAA,iEAA6B,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC5D,CAAC;AAbD,sFAaC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { ISerializer } from '@opentelemetry/otlp-transformer';\nimport { createOtlpFetchExportDelegate } from '../otlp-browser-http-export-delegate';\nimport { convertLegacyBrowserHttpOptions } from './convert-legacy-browser-http-options';\nimport type { IOtlpExportDelegate } from '../otlp-export-delegate';\nimport type { OTLPExporterConfigBase } from './legacy-base-configuration';\n\n/**\n * @deprecated\n * @param config\n * @param serializer\n * @param signalResourcePath\n * @param requiredHeaders\n */\nexport function createLegacyOtlpBrowserExportDelegate<Internal, Response>(\n config: OTLPExporterConfigBase,\n serializer: ISerializer<Internal, Response>,\n signalResourcePath: string,\n requiredHeaders: Record<string, string>\n): IOtlpExportDelegate<Internal> {\n const options = convertLegacyBrowserHttpOptions(\n config,\n signalResourcePath,\n requiredHeaders\n );\n\n return createOtlpFetchExportDelegate(options, serializer);\n}\n"]}

View File

@@ -0,0 +1,34 @@
import type { HeadersFactory } from './otlp-http-configuration';
export interface OTLPExporterConfigBase {
/**
* Custom headers that will be attached to the HTTP request that's sent to the endpoint.
*
* @remarks
* Prefer using a plain object over a factory function wherever possible.
* If using a factory function (`HttpAgentFactory`), **do not import `http` or `https` at the top of the file**
* Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`
* module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.
*
* Functions passed to the exporter MUST NOT throw errors.
*
* @example <caption> Using headers options directly: </caption>
* headers: {
* Authorization: "Api-Token my-secret-token",
* }
*
* @example <caption> Using a custom factory function </caption>
* headers: async () => {
* // ... do whatever you need to obtain the headers, ensuring you `await import('your-library')` to avoid breaking instrumentations ...
* return {
* Authorization: `Bearer ${token}`,
* };
* };
*/
headers?: Record<string, string> | HeadersFactory;
url?: string;
concurrencyLimit?: number;
/** Maximum time the OTLP exporter will wait for each batch export.
* The default value is 10000ms. */
timeoutMillis?: number;
}
//# sourceMappingURL=legacy-base-configuration.d.ts.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=legacy-base-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"legacy-base-configuration.js","sourceRoot":"","sources":["../../../src/configuration/legacy-base-configuration.ts"],"names":[],"mappings":"","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { HeadersFactory } from './otlp-http-configuration';\n\nexport interface OTLPExporterConfigBase {\n /**\n * Custom headers that will be attached to the HTTP request that's sent to the endpoint.\n *\n * @remarks\n * Prefer using a plain object over a factory function wherever possible.\n * If using a factory function (`HttpAgentFactory`), **do not import `http` or `https` at the top of the file**\n * Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`\n * module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.\n *\n * Functions passed to the exporter MUST NOT throw errors.\n *\n * @example <caption> Using headers options directly: </caption>\n * headers: {\n * Authorization: \"Api-Token my-secret-token\",\n * }\n *\n * @example <caption> Using a custom factory function </caption>\n * headers: async () => {\n * // ... do whatever you need to obtain the headers, ensuring you `await import('your-library')` to avoid breaking instrumentations ...\n * return {\n * Authorization: `Bearer ${token}`,\n * };\n * };\n */\n headers?: Record<string, string> | HeadersFactory;\n url?: string;\n concurrencyLimit?: number;\n /** Maximum time the OTLP exporter will wait for each batch export.\n * The default value is 10000ms. */\n timeoutMillis?: number;\n}\n"]}

View File

@@ -0,0 +1,47 @@
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'http';
import type * as https from 'https';
import type { OTLPExporterConfigBase } from './legacy-base-configuration';
import type { HttpAgentFactory } from './otlp-node-http-configuration';
/**
* Collector Exporter node base config
*/
export interface OTLPExporterNodeConfigBase extends OTLPExporterConfigBase {
keepAlive?: boolean;
compression?: CompressionAlgorithm;
/**
* Custom HTTP agent options or a factory function for creating agents.
*
* @remarks
* Prefer using `http.AgentOptions` or `https.AgentOptions` over a factory function wherever possible.
* If using a factory function (`HttpAgentFactory`), **do not import `http.Agent` or `https.Agent`
* statically at the top of the file**.
* Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`
* module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.
*
* @example <caption> Using agent options directly: </caption>
* httpAgentOptions: {
* keepAlive: true,
* maxSockets: 10
* }
*
* @example <caption> Using a factory with dynamic import: </caption>
* httpAgentOptions: async (protocol) => {
* const module = protocol === 'http:' ? await import('http') : await import('https');
* return new module.Agent({ keepAlive: true });
* }
*/
httpAgentOptions?: http.AgentOptions | https.AgentOptions | HttpAgentFactory;
/**
* User agent header string to be prepended to the exporter's default value.
* Availablie since v1.49.0 of the spec.
* Ref: https://opentelemetry.io/docs/specs/otel/protocol/exporter/#user-agent
*/
userAgent?: string;
}
export declare enum CompressionAlgorithm {
NONE = "none",
GZIP = "gzip"
}
//# sourceMappingURL=legacy-node-configuration.d.ts.map

View File

@@ -0,0 +1,13 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompressionAlgorithm = void 0;
var CompressionAlgorithm;
(function (CompressionAlgorithm) {
CompressionAlgorithm["NONE"] = "none";
CompressionAlgorithm["GZIP"] = "gzip";
})(CompressionAlgorithm = exports.CompressionAlgorithm || (exports.CompressionAlgorithm = {}));
//# sourceMappingURL=legacy-node-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"legacy-node-configuration.js","sourceRoot":"","sources":["../../../src/configuration/legacy-node-configuration.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA8CH,IAAY,oBAGX;AAHD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,qCAAa,CAAA;AACf,CAAC,EAHW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAG/B","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// NOTE: do not change these imports to be actual imports, otherwise they WILL break `@opentelemetry/instrumentation-http`\nimport type * as http from 'http';\nimport type * as https from 'https';\n\nimport type { OTLPExporterConfigBase } from './legacy-base-configuration';\nimport type { HttpAgentFactory } from './otlp-node-http-configuration';\n\n/**\n * Collector Exporter node base config\n */\nexport interface OTLPExporterNodeConfigBase extends OTLPExporterConfigBase {\n keepAlive?: boolean;\n compression?: CompressionAlgorithm;\n /**\n * Custom HTTP agent options or a factory function for creating agents.\n *\n * @remarks\n * Prefer using `http.AgentOptions` or `https.AgentOptions` over a factory function wherever possible.\n * If using a factory function (`HttpAgentFactory`), **do not import `http.Agent` or `https.Agent`\n * statically at the top of the file**.\n * Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`\n * module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.\n *\n * @example <caption> Using agent options directly: </caption>\n * httpAgentOptions: {\n * keepAlive: true,\n * maxSockets: 10\n * }\n *\n * @example <caption> Using a factory with dynamic import: </caption>\n * httpAgentOptions: async (protocol) => {\n * const module = protocol === 'http:' ? await import('http') : await import('https');\n * return new module.Agent({ keepAlive: true });\n * }\n */\n httpAgentOptions?: http.AgentOptions | https.AgentOptions | HttpAgentFactory;\n /**\n * User agent header string to be prepended to the exporter's default value.\n * Availablie since v1.49.0 of the spec.\n * Ref: https://opentelemetry.io/docs/specs/otel/protocol/exporter/#user-agent\n */\n userAgent?: string;\n}\n\nexport enum CompressionAlgorithm {\n NONE = 'none',\n GZIP = 'gzip',\n}\n"]}

View File

@@ -0,0 +1,14 @@
import type { OtlpSharedConfiguration } from './shared-configuration';
export type HeadersFactory = () => Promise<Record<string, string>>;
export interface OtlpHttpConfiguration extends OtlpSharedConfiguration {
url: string;
headers: HeadersFactory;
}
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
export declare function mergeOtlpHttpConfigurationWithDefaults(userProvidedConfiguration: Partial<OtlpHttpConfiguration>, fallbackConfiguration: Partial<OtlpHttpConfiguration>, defaultConfiguration: OtlpHttpConfiguration): OtlpHttpConfiguration;
export declare function getHttpConfigurationDefaults(requiredHeaders: Record<string, string>, signalResourcePath: string): OtlpHttpConfiguration;
//# sourceMappingURL=otlp-http-configuration.d.ts.map

View File

@@ -0,0 +1,64 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHttpConfigurationDefaults = exports.mergeOtlpHttpConfigurationWithDefaults = void 0;
const shared_configuration_1 = require("./shared-configuration");
const util_1 = require("../util");
function mergeHeaders(userProvidedHeaders, fallbackHeaders, defaultHeaders) {
return async () => {
const requiredHeaders = {
...(await defaultHeaders()),
};
const headers = {};
// add fallback ones first
if (fallbackHeaders != null) {
Object.assign(headers, await fallbackHeaders());
}
// override with user-provided ones
if (userProvidedHeaders != null) {
Object.assign(headers, (0, util_1.validateAndNormalizeHeaders)(await userProvidedHeaders()));
}
// override required ones.
return Object.assign(headers, requiredHeaders);
};
}
function validateUserProvidedUrl(url) {
if (url == null) {
return undefined;
}
try {
// NOTE: In non-browser environments, `globalThis.location` will be `undefined`.
const base = globalThis.location?.href;
return new URL(url, base).href;
}
catch {
throw new Error(`Configuration: Could not parse user-provided export URL: '${url}'`);
}
}
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
function mergeOtlpHttpConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
return {
...(0, shared_configuration_1.mergeOtlpSharedConfigurationWithDefaults)(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration),
headers: mergeHeaders(userProvidedConfiguration.headers, fallbackConfiguration.headers, defaultConfiguration.headers),
url: validateUserProvidedUrl(userProvidedConfiguration.url) ??
fallbackConfiguration.url ??
defaultConfiguration.url,
};
}
exports.mergeOtlpHttpConfigurationWithDefaults = mergeOtlpHttpConfigurationWithDefaults;
function getHttpConfigurationDefaults(requiredHeaders, signalResourcePath) {
return {
...(0, shared_configuration_1.getSharedConfigurationDefaults)(),
headers: async () => requiredHeaders,
url: 'http://localhost:4318/' + signalResourcePath,
};
}
exports.getHttpConfigurationDefaults = getHttpConfigurationDefaults;
//# sourceMappingURL=otlp-http-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"otlp-http-configuration.js","sourceRoot":"","sources":["../../../src/configuration/otlp-http-configuration.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iEAGgC;AAChC,kCAAsD;AAStD,SAAS,YAAY,CACnB,mBAAsD,EACtD,eAAkD,EAClD,cAA8B;IAE9B,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,eAAe,GAAG;YACtB,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC;SAC5B,CAAC;QACF,MAAM,OAAO,GAAG,EAAE,CAAC;QAEnB,0BAA0B;QAC1B,IAAI,eAAe,IAAI,IAAI,EAAE;YAC3B,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,eAAe,EAAE,CAAC,CAAC;SACjD;QAED,mCAAmC;QACnC,IAAI,mBAAmB,IAAI,IAAI,EAAE;YAC/B,MAAM,CAAC,MAAM,CACX,OAAO,EACP,IAAA,kCAA2B,EAAC,MAAM,mBAAmB,EAAE,CAAC,CACzD,CAAC;SACH;QAED,0BAA0B;QAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAuB;IACtD,IAAI,GAAG,IAAI,IAAI,EAAE;QACf,OAAO,SAAS,CAAC;KAClB;IACD,IAAI;QACF,gFAAgF;QAChF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC;QACvC,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;KAChC;IAAC,MAAM;QACN,MAAM,IAAI,KAAK,CACb,6DAA6D,GAAG,GAAG,CACpE,CAAC;KACH;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,sCAAsC,CACpD,yBAAyD,EACzD,qBAAqD,EACrD,oBAA2C;IAE3C,OAAO;QACL,GAAG,IAAA,+DAAwC,EACzC,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,CACrB;QACD,OAAO,EAAE,YAAY,CACnB,yBAAyB,CAAC,OAAO,EACjC,qBAAqB,CAAC,OAAO,EAC7B,oBAAoB,CAAC,OAAO,CAC7B;QACD,GAAG,EACD,uBAAuB,CAAC,yBAAyB,CAAC,GAAG,CAAC;YACtD,qBAAqB,CAAC,GAAG;YACzB,oBAAoB,CAAC,GAAG;KAC3B,CAAC;AACJ,CAAC;AArBD,wFAqBC;AAED,SAAgB,4BAA4B,CAC1C,eAAuC,EACvC,kBAA0B;IAE1B,OAAO;QACL,GAAG,IAAA,qDAA8B,GAAE;QACnC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,eAAe;QACpC,GAAG,EAAE,wBAAwB,GAAG,kBAAkB;KACnD,CAAC;AACJ,CAAC;AATD,oEASC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { OtlpSharedConfiguration } from './shared-configuration';\nimport {\n getSharedConfigurationDefaults,\n mergeOtlpSharedConfigurationWithDefaults,\n} from './shared-configuration';\nimport { validateAndNormalizeHeaders } from '../util';\n\nexport type HeadersFactory = () => Promise<Record<string, string>>;\n\nexport interface OtlpHttpConfiguration extends OtlpSharedConfiguration {\n url: string;\n headers: HeadersFactory;\n}\n\nfunction mergeHeaders(\n userProvidedHeaders: HeadersFactory | undefined | null,\n fallbackHeaders: HeadersFactory | undefined | null,\n defaultHeaders: HeadersFactory\n): HeadersFactory {\n return async () => {\n const requiredHeaders = {\n ...(await defaultHeaders()),\n };\n const headers = {};\n\n // add fallback ones first\n if (fallbackHeaders != null) {\n Object.assign(headers, await fallbackHeaders());\n }\n\n // override with user-provided ones\n if (userProvidedHeaders != null) {\n Object.assign(\n headers,\n validateAndNormalizeHeaders(await userProvidedHeaders())\n );\n }\n\n // override required ones.\n return Object.assign(headers, requiredHeaders);\n };\n}\n\nfunction validateUserProvidedUrl(url: string | undefined): string | undefined {\n if (url == null) {\n return undefined;\n }\n try {\n // NOTE: In non-browser environments, `globalThis.location` will be `undefined`.\n const base = globalThis.location?.href;\n return new URL(url, base).href;\n } catch {\n throw new Error(\n `Configuration: Could not parse user-provided export URL: '${url}'`\n );\n }\n}\n\n/**\n * @param userProvidedConfiguration Configuration options provided by the user in code.\n * @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.\n * @param defaultConfiguration The defaults as defined by the exporter specification\n */\nexport function mergeOtlpHttpConfigurationWithDefaults(\n userProvidedConfiguration: Partial<OtlpHttpConfiguration>,\n fallbackConfiguration: Partial<OtlpHttpConfiguration>,\n defaultConfiguration: OtlpHttpConfiguration\n): OtlpHttpConfiguration {\n return {\n ...mergeOtlpSharedConfigurationWithDefaults(\n userProvidedConfiguration,\n fallbackConfiguration,\n defaultConfiguration\n ),\n headers: mergeHeaders(\n userProvidedConfiguration.headers,\n fallbackConfiguration.headers,\n defaultConfiguration.headers\n ),\n url:\n validateUserProvidedUrl(userProvidedConfiguration.url) ??\n fallbackConfiguration.url ??\n defaultConfiguration.url,\n };\n}\n\nexport function getHttpConfigurationDefaults(\n requiredHeaders: Record<string, string>,\n signalResourcePath: string\n): OtlpHttpConfiguration {\n return {\n ...getSharedConfigurationDefaults(),\n headers: async () => requiredHeaders,\n url: 'http://localhost:4318/' + signalResourcePath,\n };\n}\n"]}

View File

@@ -0,0 +1,34 @@
/// <reference types="node" />
/// <reference types="node" />
import type { OtlpHttpConfiguration } from './otlp-http-configuration';
import type * as http from 'http';
import type * as https from 'https';
export type HttpAgentFactory = (protocol: string) => http.Agent | https.Agent | Promise<http.Agent> | Promise<https.Agent>;
export interface OtlpNodeHttpConfiguration extends OtlpHttpConfiguration {
/**
* Factory function for creating agents.
*
* @remarks
* Prefer using {@link httpAgentFactoryFromOptions} over manually writing a factory function wherever possible.
* If using a factory function (`HttpAgentFactory`), **do not import `http.Agent` or `https.Agent`
* statically at the top of the file**.
* Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`
* module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.
*/
agentFactory: HttpAgentFactory;
/**
* User agent header string to be appended to the exporter's value as a prefix.
* Availablie since v1.49.0 of the spec.
* Ref: https://opentelemetry.io/docs/specs/otel/protocol/exporter/#user-agent
*/
userAgent?: string;
}
export declare function httpAgentFactoryFromOptions(options: http.AgentOptions | https.AgentOptions): HttpAgentFactory;
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
export declare function mergeOtlpNodeHttpConfigurationWithDefaults(userProvidedConfiguration: Partial<OtlpNodeHttpConfiguration>, fallbackConfiguration: Partial<OtlpNodeHttpConfiguration>, defaultConfiguration: OtlpNodeHttpConfiguration): OtlpNodeHttpConfiguration;
export declare function getNodeHttpConfigurationDefaults(requiredHeaders: Record<string, string>, signalResourcePath: string): OtlpNodeHttpConfiguration;
//# sourceMappingURL=otlp-node-http-configuration.d.ts.map

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNodeHttpConfigurationDefaults = exports.mergeOtlpNodeHttpConfigurationWithDefaults = exports.httpAgentFactoryFromOptions = void 0;
const otlp_http_configuration_1 = require("./otlp-http-configuration");
function httpAgentFactoryFromOptions(options) {
return async (protocol) => {
const isInsecure = protocol === 'http:';
const module = isInsecure ? import('http') : import('https');
const { Agent } = await module;
if (isInsecure) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- these props should not be used in agent options
const { ca, cert, key, ...insecureOptions } = options;
return new Agent(insecureOptions);
}
return new Agent(options);
};
}
exports.httpAgentFactoryFromOptions = httpAgentFactoryFromOptions;
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
function mergeOtlpNodeHttpConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
return {
...(0, otlp_http_configuration_1.mergeOtlpHttpConfigurationWithDefaults)(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration),
agentFactory: userProvidedConfiguration.agentFactory ??
fallbackConfiguration.agentFactory ??
defaultConfiguration.agentFactory,
userAgent: userProvidedConfiguration.userAgent,
};
}
exports.mergeOtlpNodeHttpConfigurationWithDefaults = mergeOtlpNodeHttpConfigurationWithDefaults;
function getNodeHttpConfigurationDefaults(requiredHeaders, signalResourcePath) {
return {
...(0, otlp_http_configuration_1.getHttpConfigurationDefaults)(requiredHeaders, signalResourcePath),
agentFactory: httpAgentFactoryFromOptions({ keepAlive: true }),
};
}
exports.getNodeHttpConfigurationDefaults = getNodeHttpConfigurationDefaults;
//# sourceMappingURL=otlp-node-http-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"otlp-node-http-configuration.js","sourceRoot":"","sources":["../../../src/configuration/otlp-node-http-configuration.ts"],"names":[],"mappings":";;;AAKA,uEAGmC;AA8BnC,SAAgB,2BAA2B,CACzC,OAA+C;IAE/C,OAAO,KAAK,EAAC,QAAQ,EAAC,EAAE;QACtB,MAAM,UAAU,GAAG,QAAQ,KAAK,OAAO,CAAC;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC;QAE/B,IAAI,UAAU,EAAE;YACd,gHAAgH;YAChH,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,eAAe,EAAE,GACzC,OAA6B,CAAC;YAChC,OAAO,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;SACnC;QACD,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC;AAhBD,kEAgBC;AAED;;;;GAIG;AACH,SAAgB,0CAA0C,CACxD,yBAA6D,EAC7D,qBAAyD,EACzD,oBAA+C;IAE/C,OAAO;QACL,GAAG,IAAA,gEAAsC,EACvC,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,CACrB;QACD,YAAY,EACV,yBAAyB,CAAC,YAAY;YACtC,qBAAqB,CAAC,YAAY;YAClC,oBAAoB,CAAC,YAAY;QACnC,SAAS,EAAE,yBAAyB,CAAC,SAAS;KAC/C,CAAC;AACJ,CAAC;AAjBD,gGAiBC;AAED,SAAgB,gCAAgC,CAC9C,eAAuC,EACvC,kBAA0B;IAE1B,OAAO;QACL,GAAG,IAAA,sDAA4B,EAAC,eAAe,EAAE,kBAAkB,CAAC;QACpE,YAAY,EAAE,2BAA2B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AARD,4EAQC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { OtlpHttpConfiguration } from './otlp-http-configuration';\nimport {\n getHttpConfigurationDefaults,\n mergeOtlpHttpConfigurationWithDefaults,\n} from './otlp-http-configuration';\n\n// NOTE: do not change these imports to be actual imports, otherwise they WILL break `@opentelemetry/instrumentation-http`\nimport type * as http from 'http';\nimport type * as https from 'https';\n\nexport type HttpAgentFactory = (\n protocol: string\n) => http.Agent | https.Agent | Promise<http.Agent> | Promise<https.Agent>;\n\nexport interface OtlpNodeHttpConfiguration extends OtlpHttpConfiguration {\n /**\n * Factory function for creating agents.\n *\n * @remarks\n * Prefer using {@link httpAgentFactoryFromOptions} over manually writing a factory function wherever possible.\n * If using a factory function (`HttpAgentFactory`), **do not import `http.Agent` or `https.Agent`\n * statically at the top of the file**.\n * Instead, use dynamic `import()` or `require()` to load the module. This ensures that the `http` or `https`\n * module is not loaded before `@opentelemetry/instrumentation-http` can instrument it.\n */\n agentFactory: HttpAgentFactory;\n /**\n * User agent header string to be appended to the exporter's value as a prefix.\n * Availablie since v1.49.0 of the spec.\n * Ref: https://opentelemetry.io/docs/specs/otel/protocol/exporter/#user-agent\n */\n userAgent?: string;\n}\n\nexport function httpAgentFactoryFromOptions(\n options: http.AgentOptions | https.AgentOptions\n): HttpAgentFactory {\n return async protocol => {\n const isInsecure = protocol === 'http:';\n const module = isInsecure ? import('http') : import('https');\n const { Agent } = await module;\n\n if (isInsecure) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- these props should not be used in agent options\n const { ca, cert, key, ...insecureOptions } =\n options as https.AgentOptions;\n return new Agent(insecureOptions);\n }\n return new Agent(options);\n };\n}\n\n/**\n * @param userProvidedConfiguration Configuration options provided by the user in code.\n * @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.\n * @param defaultConfiguration The defaults as defined by the exporter specification\n */\nexport function mergeOtlpNodeHttpConfigurationWithDefaults(\n userProvidedConfiguration: Partial<OtlpNodeHttpConfiguration>,\n fallbackConfiguration: Partial<OtlpNodeHttpConfiguration>,\n defaultConfiguration: OtlpNodeHttpConfiguration\n): OtlpNodeHttpConfiguration {\n return {\n ...mergeOtlpHttpConfigurationWithDefaults(\n userProvidedConfiguration,\n fallbackConfiguration,\n defaultConfiguration\n ),\n agentFactory:\n userProvidedConfiguration.agentFactory ??\n fallbackConfiguration.agentFactory ??\n defaultConfiguration.agentFactory,\n userAgent: userProvidedConfiguration.userAgent,\n };\n}\n\nexport function getNodeHttpConfigurationDefaults(\n requiredHeaders: Record<string, string>,\n signalResourcePath: string\n): OtlpNodeHttpConfiguration {\n return {\n ...getHttpConfigurationDefaults(requiredHeaders, signalResourcePath),\n agentFactory: httpAgentFactoryFromOptions({ keepAlive: true }),\n };\n}\n"]}

View File

@@ -0,0 +1,9 @@
import type { OtlpNodeHttpConfiguration } from './otlp-node-http-configuration';
/**
* Reads and returns configuration from the environment
*
* @param signalIdentifier all caps part in environment variables that identifies the signal (e.g.: METRICS, TRACES, LOGS)
* @param signalResourcePath signal resource path to append if necessary (e.g.: v1/metrics, v1/traces, v1/logs)
*/
export declare function getNodeHttpConfigurationFromEnvironment(signalIdentifier: string, signalResourcePath: string): Partial<OtlpNodeHttpConfiguration>;
//# sourceMappingURL=otlp-node-http-env-configuration.d.ts.map

View File

@@ -0,0 +1,123 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNodeHttpConfigurationFromEnvironment = void 0;
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
const fs = require("fs");
const path = require("path");
const core_1 = require("@opentelemetry/core");
const api_1 = require("@opentelemetry/api");
const shared_env_configuration_1 = require("./shared-env-configuration");
const shared_configuration_1 = require("./shared-configuration");
const otlp_node_http_configuration_1 = require("./otlp-node-http-configuration");
function getStaticHeadersFromEnv(signalIdentifier) {
const signalSpecificRawHeaders = (0, core_1.getStringFromEnv)(`OTEL_EXPORTER_OTLP_${signalIdentifier}_HEADERS`);
const nonSignalSpecificRawHeaders = (0, core_1.getStringFromEnv)('OTEL_EXPORTER_OTLP_HEADERS');
const signalSpecificHeaders = (0, core_1.parseKeyPairsIntoRecord)(signalSpecificRawHeaders);
const nonSignalSpecificHeaders = (0, core_1.parseKeyPairsIntoRecord)(nonSignalSpecificRawHeaders);
if (Object.keys(signalSpecificHeaders).length === 0 &&
Object.keys(nonSignalSpecificHeaders).length === 0) {
return undefined;
}
// headers are combined instead of overwritten, with the specific headers taking precedence over
// the non-specific ones.
return Object.assign({}, (0, core_1.parseKeyPairsIntoRecord)(nonSignalSpecificRawHeaders), (0, core_1.parseKeyPairsIntoRecord)(signalSpecificRawHeaders));
}
function appendRootPathToUrlIfNeeded(url) {
try {
const parsedUrl = new URL(url);
// This will automatically append '/' if there's no root path.
return parsedUrl.toString();
}
catch {
api_1.diag.warn(`Configuration: Could not parse environment-provided export URL: '${url}', falling back to undefined`);
return undefined;
}
}
function appendResourcePathToUrl(url, path) {
try {
// just try to parse, if it fails we catch and warn.
new URL(url);
}
catch {
api_1.diag.warn(`Configuration: Could not parse environment-provided export URL: '${url}', falling back to undefined`);
return undefined;
}
if (!url.endsWith('/')) {
url = url + '/';
}
url += path;
try {
// just try to parse, if it fails we catch and warn.
new URL(url);
}
catch {
api_1.diag.warn(`Configuration: Provided URL appended with '${path}' is not a valid URL, using 'undefined' instead of '${url}'`);
return undefined;
}
return url;
}
function getNonSpecificUrlFromEnv(signalResourcePath) {
const envUrl = (0, core_1.getStringFromEnv)('OTEL_EXPORTER_OTLP_ENDPOINT');
if (envUrl === undefined) {
return undefined;
}
return appendResourcePathToUrl(envUrl, signalResourcePath);
}
function getSpecificUrlFromEnv(signalIdentifier) {
const envUrl = (0, core_1.getStringFromEnv)(`OTEL_EXPORTER_OTLP_${signalIdentifier}_ENDPOINT`);
if (envUrl === undefined) {
return undefined;
}
return appendRootPathToUrlIfNeeded(envUrl);
}
function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningMessage) {
const signalSpecificPath = (0, core_1.getStringFromEnv)(signalSpecificEnvVar);
const nonSignalSpecificPath = (0, core_1.getStringFromEnv)(nonSignalSpecificEnvVar);
const filePath = signalSpecificPath ?? nonSignalSpecificPath;
if (filePath != null) {
try {
return fs.readFileSync(path.resolve(process.cwd(), filePath));
}
catch {
api_1.diag.warn(warningMessage);
return undefined;
}
}
else {
return undefined;
}
}
function getClientCertificateFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_CERTIFICATE`, 'OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE', 'Failed to read client certificate chain file');
}
function getClientKeyFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_KEY`, 'OTEL_EXPORTER_OTLP_CLIENT_KEY', 'Failed to read client certificate private key file');
}
function getRootCertificateFromEnv(signalIdentifier) {
return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CERTIFICATE`, 'OTEL_EXPORTER_OTLP_CERTIFICATE', 'Failed to read root certificate file');
}
/**
* Reads and returns configuration from the environment
*
* @param signalIdentifier all caps part in environment variables that identifies the signal (e.g.: METRICS, TRACES, LOGS)
* @param signalResourcePath signal resource path to append if necessary (e.g.: v1/metrics, v1/traces, v1/logs)
*/
function getNodeHttpConfigurationFromEnvironment(signalIdentifier, signalResourcePath) {
return {
...(0, shared_env_configuration_1.getSharedConfigurationFromEnvironment)(signalIdentifier),
url: getSpecificUrlFromEnv(signalIdentifier) ??
getNonSpecificUrlFromEnv(signalResourcePath),
headers: (0, shared_configuration_1.wrapStaticHeadersInFunction)(getStaticHeadersFromEnv(signalIdentifier)),
agentFactory: (0, otlp_node_http_configuration_1.httpAgentFactoryFromOptions)({
keepAlive: true,
ca: getRootCertificateFromEnv(signalIdentifier),
cert: getClientCertificateFromEnv(signalIdentifier),
key: getClientKeyFromEnv(signalIdentifier),
}),
};
}
exports.getNodeHttpConfigurationFromEnvironment = getNodeHttpConfigurationFromEnvironment;
//# sourceMappingURL=otlp-node-http-env-configuration.js.map

View File

@@ -0,0 +1,24 @@
import type { HeadersFactory } from './otlp-http-configuration';
/**
* Configuration shared across all OTLP exporters
*
* Implementation note: anything added here MUST be
* - platform-agnostic
* - signal-agnostic
* - transport-agnostic
*/
export interface OtlpSharedConfiguration {
timeoutMillis: number;
concurrencyLimit: number;
compression: 'gzip' | 'none';
}
export declare function validateTimeoutMillis(timeoutMillis: number): number;
export declare function wrapStaticHeadersInFunction(headers: Record<string, string> | undefined): HeadersFactory | undefined;
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
export declare function mergeOtlpSharedConfigurationWithDefaults(userProvidedConfiguration: Partial<OtlpSharedConfiguration>, fallbackConfiguration: Partial<OtlpSharedConfiguration>, defaultConfiguration: OtlpSharedConfiguration): OtlpSharedConfiguration;
export declare function getSharedConfigurationDefaults(): OtlpSharedConfiguration;
//# sourceMappingURL=shared-configuration.d.ts.map

View File

@@ -0,0 +1,49 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSharedConfigurationDefaults = exports.mergeOtlpSharedConfigurationWithDefaults = exports.wrapStaticHeadersInFunction = exports.validateTimeoutMillis = void 0;
function validateTimeoutMillis(timeoutMillis) {
if (Number.isFinite(timeoutMillis) && timeoutMillis > 0) {
return timeoutMillis;
}
throw new Error(`Configuration: timeoutMillis is invalid, expected number greater than 0 (actual: '${timeoutMillis}')`);
}
exports.validateTimeoutMillis = validateTimeoutMillis;
function wrapStaticHeadersInFunction(headers) {
if (headers == null) {
return undefined;
}
return async () => headers;
}
exports.wrapStaticHeadersInFunction = wrapStaticHeadersInFunction;
/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
* @param defaultConfiguration The defaults as defined by the exporter specification
*/
function mergeOtlpSharedConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
return {
timeoutMillis: validateTimeoutMillis(userProvidedConfiguration.timeoutMillis ??
fallbackConfiguration.timeoutMillis ??
defaultConfiguration.timeoutMillis),
concurrencyLimit: userProvidedConfiguration.concurrencyLimit ??
fallbackConfiguration.concurrencyLimit ??
defaultConfiguration.concurrencyLimit,
compression: userProvidedConfiguration.compression ??
fallbackConfiguration.compression ??
defaultConfiguration.compression,
};
}
exports.mergeOtlpSharedConfigurationWithDefaults = mergeOtlpSharedConfigurationWithDefaults;
function getSharedConfigurationDefaults() {
return {
timeoutMillis: 10000,
concurrencyLimit: 30,
compression: 'none',
};
}
exports.getSharedConfigurationDefaults = getSharedConfigurationDefaults;
//# sourceMappingURL=shared-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"shared-configuration.js","sourceRoot":"","sources":["../../../src/configuration/shared-configuration.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkBH,SAAgB,qBAAqB,CAAC,aAAqB;IACzD,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,EAAE;QACvD,OAAO,aAAa,CAAC;KACtB;IACD,MAAM,IAAI,KAAK,CACb,qFAAqF,aAAa,IAAI,CACvG,CAAC;AACJ,CAAC;AAPD,sDAOC;AAED,SAAgB,2BAA2B,CACzC,OAA2C;IAE3C,IAAI,OAAO,IAAI,IAAI,EAAE;QACnB,OAAO,SAAS,CAAC;KAClB;IAED,OAAO,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC;AAC7B,CAAC;AARD,kEAQC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CACtD,yBAA2D,EAC3D,qBAAuD,EACvD,oBAA6C;IAE7C,OAAO;QACL,aAAa,EAAE,qBAAqB,CAClC,yBAAyB,CAAC,aAAa;YACrC,qBAAqB,CAAC,aAAa;YACnC,oBAAoB,CAAC,aAAa,CACrC;QACD,gBAAgB,EACd,yBAAyB,CAAC,gBAAgB;YAC1C,qBAAqB,CAAC,gBAAgB;YACtC,oBAAoB,CAAC,gBAAgB;QACvC,WAAW,EACT,yBAAyB,CAAC,WAAW;YACrC,qBAAqB,CAAC,WAAW;YACjC,oBAAoB,CAAC,WAAW;KACnC,CAAC;AACJ,CAAC;AApBD,4FAoBC;AAED,SAAgB,8BAA8B;IAC5C,OAAO;QACL,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC;AAND,wEAMC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HeadersFactory } from './otlp-http-configuration';\n\n/**\n * Configuration shared across all OTLP exporters\n *\n * Implementation note: anything added here MUST be\n * - platform-agnostic\n * - signal-agnostic\n * - transport-agnostic\n */\nexport interface OtlpSharedConfiguration {\n timeoutMillis: number;\n concurrencyLimit: number;\n compression: 'gzip' | 'none';\n}\n\nexport function validateTimeoutMillis(timeoutMillis: number) {\n if (Number.isFinite(timeoutMillis) && timeoutMillis > 0) {\n return timeoutMillis;\n }\n throw new Error(\n `Configuration: timeoutMillis is invalid, expected number greater than 0 (actual: '${timeoutMillis}')`\n );\n}\n\nexport function wrapStaticHeadersInFunction(\n headers: Record<string, string> | undefined\n): HeadersFactory | undefined {\n if (headers == null) {\n return undefined;\n }\n\n return async () => headers;\n}\n\n/**\n * @param userProvidedConfiguration Configuration options provided by the user in code.\n * @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.\n * @param defaultConfiguration The defaults as defined by the exporter specification\n */\nexport function mergeOtlpSharedConfigurationWithDefaults(\n userProvidedConfiguration: Partial<OtlpSharedConfiguration>,\n fallbackConfiguration: Partial<OtlpSharedConfiguration>,\n defaultConfiguration: OtlpSharedConfiguration\n): OtlpSharedConfiguration {\n return {\n timeoutMillis: validateTimeoutMillis(\n userProvidedConfiguration.timeoutMillis ??\n fallbackConfiguration.timeoutMillis ??\n defaultConfiguration.timeoutMillis\n ),\n concurrencyLimit:\n userProvidedConfiguration.concurrencyLimit ??\n fallbackConfiguration.concurrencyLimit ??\n defaultConfiguration.concurrencyLimit,\n compression:\n userProvidedConfiguration.compression ??\n fallbackConfiguration.compression ??\n defaultConfiguration.compression,\n };\n}\n\nexport function getSharedConfigurationDefaults(): OtlpSharedConfiguration {\n return {\n timeoutMillis: 10000,\n concurrencyLimit: 30,\n compression: 'none',\n };\n}\n"]}

View File

@@ -0,0 +1,3 @@
import type { OtlpSharedConfiguration } from './shared-configuration';
export declare function getSharedConfigurationFromEnvironment(signalIdentifier: string): Partial<OtlpSharedConfiguration>;
//# sourceMappingURL=shared-env-configuration.d.ts.map

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSharedConfigurationFromEnvironment = void 0;
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
const core_1 = require("@opentelemetry/core");
const api_1 = require("@opentelemetry/api");
function parseAndValidateTimeoutFromEnv(timeoutEnvVar) {
const envTimeout = (0, core_1.getNumberFromEnv)(timeoutEnvVar);
if (envTimeout != null) {
if (Number.isFinite(envTimeout) && envTimeout > 0) {
return envTimeout;
}
api_1.diag.warn(`Configuration: ${timeoutEnvVar} is invalid, expected number greater than 0 (actual: ${envTimeout})`);
}
return undefined;
}
function getTimeoutFromEnv(signalIdentifier) {
const specificTimeout = parseAndValidateTimeoutFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_TIMEOUT`);
const nonSpecificTimeout = parseAndValidateTimeoutFromEnv('OTEL_EXPORTER_OTLP_TIMEOUT');
return specificTimeout ?? nonSpecificTimeout;
}
function parseAndValidateCompressionFromEnv(compressionEnvVar) {
const compression = (0, core_1.getStringFromEnv)(compressionEnvVar)?.trim();
if (compression == null || compression === 'none' || compression === 'gzip') {
return compression;
}
api_1.diag.warn(`Configuration: ${compressionEnvVar} is invalid, expected 'none' or 'gzip' (actual: '${compression}')`);
return undefined;
}
function getCompressionFromEnv(signalIdentifier) {
const specificCompression = parseAndValidateCompressionFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_COMPRESSION`);
const nonSpecificCompression = parseAndValidateCompressionFromEnv('OTEL_EXPORTER_OTLP_COMPRESSION');
return specificCompression ?? nonSpecificCompression;
}
function getSharedConfigurationFromEnvironment(signalIdentifier) {
return {
timeoutMillis: getTimeoutFromEnv(signalIdentifier),
compression: getCompressionFromEnv(signalIdentifier),
};
}
exports.getSharedConfigurationFromEnvironment = getSharedConfigurationFromEnvironment;
//# sourceMappingURL=shared-env-configuration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"shared-env-configuration.js","sourceRoot":"","sources":["../../../src/configuration/shared-env-configuration.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,8CAAyE;AAEzE,4CAA0C;AAE1C,SAAS,8BAA8B,CACrC,aAAqB;IAErB,MAAM,UAAU,GAAG,IAAA,uBAAgB,EAAC,aAAa,CAAC,CAAC;IACnD,IAAI,UAAU,IAAI,IAAI,EAAE;QACtB,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE;YACjD,OAAO,UAAU,CAAC;SACnB;QACD,UAAI,CAAC,IAAI,CACP,kBAAkB,aAAa,wDAAwD,UAAU,GAAG,CACrG,CAAC;KACH;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CAAC,gBAAwB;IACjD,MAAM,eAAe,GAAG,8BAA8B,CACpD,sBAAsB,gBAAgB,UAAU,CACjD,CAAC;IACF,MAAM,kBAAkB,GAAG,8BAA8B,CACvD,4BAA4B,CAC7B,CAAC;IAEF,OAAO,eAAe,IAAI,kBAAkB,CAAC;AAC/C,CAAC;AAED,SAAS,kCAAkC,CACzC,iBAAyB;IAEzB,MAAM,WAAW,GAAG,IAAA,uBAAgB,EAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC;IAEhE,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,KAAK,MAAM,IAAI,WAAW,KAAK,MAAM,EAAE;QAC3E,OAAO,WAAW,CAAC;KACpB;IAED,UAAI,CAAC,IAAI,CACP,kBAAkB,iBAAiB,oDAAoD,WAAW,IAAI,CACvG,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAC5B,gBAAwB;IAExB,MAAM,mBAAmB,GAAG,kCAAkC,CAC5D,sBAAsB,gBAAgB,cAAc,CACrD,CAAC;IACF,MAAM,sBAAsB,GAAG,kCAAkC,CAC/D,gCAAgC,CACjC,CAAC;IAEF,OAAO,mBAAmB,IAAI,sBAAsB,CAAC;AACvD,CAAC;AAED,SAAgB,qCAAqC,CACnD,gBAAwB;IAExB,OAAO;QACL,aAAa,EAAE,iBAAiB,CAAC,gBAAgB,CAAC;QAClD,WAAW,EAAE,qBAAqB,CAAC,gBAAgB,CAAC;KACrD,CAAC;AACJ,CAAC;AAPD,sFAOC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { getNumberFromEnv, getStringFromEnv } from '@opentelemetry/core';\nimport type { OtlpSharedConfiguration } from './shared-configuration';\nimport { diag } from '@opentelemetry/api';\n\nfunction parseAndValidateTimeoutFromEnv(\n timeoutEnvVar: string\n): number | undefined {\n const envTimeout = getNumberFromEnv(timeoutEnvVar);\n if (envTimeout != null) {\n if (Number.isFinite(envTimeout) && envTimeout > 0) {\n return envTimeout;\n }\n diag.warn(\n `Configuration: ${timeoutEnvVar} is invalid, expected number greater than 0 (actual: ${envTimeout})`\n );\n }\n\n return undefined;\n}\n\nfunction getTimeoutFromEnv(signalIdentifier: string) {\n const specificTimeout = parseAndValidateTimeoutFromEnv(\n `OTEL_EXPORTER_OTLP_${signalIdentifier}_TIMEOUT`\n );\n const nonSpecificTimeout = parseAndValidateTimeoutFromEnv(\n 'OTEL_EXPORTER_OTLP_TIMEOUT'\n );\n\n return specificTimeout ?? nonSpecificTimeout;\n}\n\nfunction parseAndValidateCompressionFromEnv(\n compressionEnvVar: string\n): 'none' | 'gzip' | undefined {\n const compression = getStringFromEnv(compressionEnvVar)?.trim();\n\n if (compression == null || compression === 'none' || compression === 'gzip') {\n return compression;\n }\n\n diag.warn(\n `Configuration: ${compressionEnvVar} is invalid, expected 'none' or 'gzip' (actual: '${compression}')`\n );\n return undefined;\n}\n\nfunction getCompressionFromEnv(\n signalIdentifier: string\n): 'none' | 'gzip' | undefined {\n const specificCompression = parseAndValidateCompressionFromEnv(\n `OTEL_EXPORTER_OTLP_${signalIdentifier}_COMPRESSION`\n );\n const nonSpecificCompression = parseAndValidateCompressionFromEnv(\n 'OTEL_EXPORTER_OTLP_COMPRESSION'\n );\n\n return specificCompression ?? nonSpecificCompression;\n}\n\nexport function getSharedConfigurationFromEnvironment(\n signalIdentifier: string\n): Partial<OtlpSharedConfiguration> {\n return {\n timeoutMillis: getTimeoutFromEnv(signalIdentifier),\n compression: getCompressionFromEnv(signalIdentifier),\n };\n}\n"]}

View File

@@ -0,0 +1,15 @@
export interface ExportResponseSuccess {
status: 'success';
data?: Uint8Array;
}
export interface ExportResponseFailure {
status: 'failure';
error: Error;
}
export interface ExportResponseRetryable {
status: 'retryable';
retryInMillis?: number;
error?: Error;
}
export type ExportResponse = ExportResponseSuccess | ExportResponseFailure | ExportResponseRetryable;
//# sourceMappingURL=export-response.d.ts.map

View File

@@ -0,0 +1,7 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=export-response.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"export-response.js","sourceRoot":"","sources":["../../src/export-response.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface ExportResponseSuccess {\n status: 'success';\n data?: Uint8Array;\n}\n\nexport interface ExportResponseFailure {\n status: 'failure';\n error: Error;\n}\n\nexport interface ExportResponseRetryable {\n status: 'retryable';\n retryInMillis?: number;\n error?: Error;\n}\n\nexport type ExportResponse =\n | ExportResponseSuccess\n | ExportResponseFailure\n | ExportResponseRetryable;\n"]}

View File

@@ -0,0 +1,6 @@
import type { ExportResponse } from './export-response';
export interface IExporterTransport {
send(data: Uint8Array, timeoutMillis: number): Promise<ExportResponse>;
shutdown(): void;
}
//# sourceMappingURL=exporter-transport.d.ts.map

View File

@@ -0,0 +1,7 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=exporter-transport.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exporter-transport.js","sourceRoot":"","sources":["../../src/exporter-transport.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ExportResponse } from './export-response';\n\nexport interface IExporterTransport {\n send(data: Uint8Array, timeoutMillis: number): Promise<ExportResponse>;\n shutdown(): void;\n}\n"]}

View File

@@ -0,0 +1,7 @@
/**
* @deprecated Use `createOtlpFetchExportDelegate` instead.
*/
export { createOtlpSendBeaconExportDelegate } from './otlp-browser-http-export-delegate';
export { convertLegacyBrowserHttpOptions } from './configuration/convert-legacy-browser-http-options';
export { createLegacyOtlpBrowserExportDelegate } from './configuration/create-legacy-browser-delegate';
//# sourceMappingURL=index-browser-http.d.ts.map

View File

@@ -0,0 +1,17 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLegacyOtlpBrowserExportDelegate = exports.convertLegacyBrowserHttpOptions = exports.createOtlpSendBeaconExportDelegate = void 0;
/**
* @deprecated Use `createOtlpFetchExportDelegate` instead.
*/
var otlp_browser_http_export_delegate_1 = require("./otlp-browser-http-export-delegate");
Object.defineProperty(exports, "createOtlpSendBeaconExportDelegate", { enumerable: true, get: function () { return otlp_browser_http_export_delegate_1.createOtlpSendBeaconExportDelegate; } });
var convert_legacy_browser_http_options_1 = require("./configuration/convert-legacy-browser-http-options");
Object.defineProperty(exports, "convertLegacyBrowserHttpOptions", { enumerable: true, get: function () { return convert_legacy_browser_http_options_1.convertLegacyBrowserHttpOptions; } });
var create_legacy_browser_delegate_1 = require("./configuration/create-legacy-browser-delegate");
Object.defineProperty(exports, "createLegacyOtlpBrowserExportDelegate", { enumerable: true, get: function () { return create_legacy_browser_delegate_1.createLegacyOtlpBrowserExportDelegate; } });
//# sourceMappingURL=index-browser-http.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index-browser-http.js","sourceRoot":"","sources":["../../src/index-browser-http.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,yFAAyF;AAAhF,uJAAA,kCAAkC,OAAA;AAE3C,2GAAsG;AAA7F,sJAAA,+BAA+B,OAAA;AACxC,iGAAuG;AAA9F,uJAAA,qCAAqC,OAAA","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @deprecated Use `createOtlpFetchExportDelegate` instead.\n */\nexport { createOtlpSendBeaconExportDelegate } from './otlp-browser-http-export-delegate';\n\nexport { convertLegacyBrowserHttpOptions } from './configuration/convert-legacy-browser-http-options';\nexport { createLegacyOtlpBrowserExportDelegate } from './configuration/create-legacy-browser-delegate';\n"]}

View File

@@ -0,0 +1,5 @@
export { httpAgentFactoryFromOptions } from './configuration/otlp-node-http-configuration';
export { createOtlpHttpExportDelegate } from './otlp-http-export-delegate';
export { getSharedConfigurationFromEnvironment } from './configuration/shared-env-configuration';
export { convertLegacyHttpOptions } from './configuration/convert-legacy-node-http-options';
//# sourceMappingURL=index-node-http.d.ts.map

View File

@@ -0,0 +1,16 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertLegacyHttpOptions = exports.getSharedConfigurationFromEnvironment = exports.createOtlpHttpExportDelegate = exports.httpAgentFactoryFromOptions = void 0;
var otlp_node_http_configuration_1 = require("./configuration/otlp-node-http-configuration");
Object.defineProperty(exports, "httpAgentFactoryFromOptions", { enumerable: true, get: function () { return otlp_node_http_configuration_1.httpAgentFactoryFromOptions; } });
var otlp_http_export_delegate_1 = require("./otlp-http-export-delegate");
Object.defineProperty(exports, "createOtlpHttpExportDelegate", { enumerable: true, get: function () { return otlp_http_export_delegate_1.createOtlpHttpExportDelegate; } });
var shared_env_configuration_1 = require("./configuration/shared-env-configuration");
Object.defineProperty(exports, "getSharedConfigurationFromEnvironment", { enumerable: true, get: function () { return shared_env_configuration_1.getSharedConfigurationFromEnvironment; } });
var convert_legacy_node_http_options_1 = require("./configuration/convert-legacy-node-http-options");
Object.defineProperty(exports, "convertLegacyHttpOptions", { enumerable: true, get: function () { return convert_legacy_node_http_options_1.convertLegacyHttpOptions; } });
//# sourceMappingURL=index-node-http.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index-node-http.js","sourceRoot":"","sources":["../../src/index-node-http.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6FAA2F;AAAlF,2IAAA,2BAA2B,OAAA;AACpC,yEAA2E;AAAlE,yIAAA,4BAA4B,OAAA;AACrC,qFAAiG;AAAxF,iJAAA,qCAAqC,OAAA;AAC9C,qGAA4F;AAAnF,4IAAA,wBAAwB,OAAA","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { httpAgentFactoryFromOptions } from './configuration/otlp-node-http-configuration';\nexport { createOtlpHttpExportDelegate } from './otlp-http-export-delegate';\nexport { getSharedConfigurationFromEnvironment } from './configuration/shared-env-configuration';\nexport { convertLegacyHttpOptions } from './configuration/convert-legacy-node-http-options';\n"]}

View File

@@ -0,0 +1,12 @@
export { OTLPExporterBase } from './OTLPExporterBase';
export { OTLPExporterError } from './types';
export type { ExportResponse, ExportResponseFailure, ExportResponseSuccess, ExportResponseRetryable, } from './export-response';
export type { IExporterTransport } from './exporter-transport';
export { mergeOtlpSharedConfigurationWithDefaults, getSharedConfigurationDefaults, } from './configuration/shared-configuration';
export type { OtlpSharedConfiguration } from './configuration/shared-configuration';
export { CompressionAlgorithm } from './configuration/legacy-node-configuration';
export type { OTLPExporterNodeConfigBase } from './configuration/legacy-node-configuration';
export type { OTLPExporterConfigBase } from './configuration/legacy-base-configuration';
export type { IOtlpExportDelegate } from './otlp-export-delegate';
export { createOtlpNetworkExportDelegate } from './otlp-network-export-delegate';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,19 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOtlpNetworkExportDelegate = exports.CompressionAlgorithm = exports.getSharedConfigurationDefaults = exports.mergeOtlpSharedConfigurationWithDefaults = exports.OTLPExporterError = exports.OTLPExporterBase = void 0;
var OTLPExporterBase_1 = require("./OTLPExporterBase");
Object.defineProperty(exports, "OTLPExporterBase", { enumerable: true, get: function () { return OTLPExporterBase_1.OTLPExporterBase; } });
var types_1 = require("./types");
Object.defineProperty(exports, "OTLPExporterError", { enumerable: true, get: function () { return types_1.OTLPExporterError; } });
var shared_configuration_1 = require("./configuration/shared-configuration");
Object.defineProperty(exports, "mergeOtlpSharedConfigurationWithDefaults", { enumerable: true, get: function () { return shared_configuration_1.mergeOtlpSharedConfigurationWithDefaults; } });
Object.defineProperty(exports, "getSharedConfigurationDefaults", { enumerable: true, get: function () { return shared_configuration_1.getSharedConfigurationDefaults; } });
var legacy_node_configuration_1 = require("./configuration/legacy-node-configuration");
Object.defineProperty(exports, "CompressionAlgorithm", { enumerable: true, get: function () { return legacy_node_configuration_1.CompressionAlgorithm; } });
var otlp_network_export_delegate_1 = require("./otlp-network-export-delegate");
Object.defineProperty(exports, "createOtlpNetworkExportDelegate", { enumerable: true, get: function () { return otlp_network_export_delegate_1.createOtlpNetworkExportDelegate; } });
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,iCAA4C;AAAnC,0GAAA,iBAAiB,OAAA;AAW1B,6EAG8C;AAF5C,gJAAA,wCAAwC,OAAA;AACxC,sIAAA,8BAA8B,OAAA;AAIhC,uFAAiF;AAAxE,iIAAA,oBAAoB,OAAA;AAI7B,+EAAiF;AAAxE,+IAAA,+BAA+B,OAAA","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { OTLPExporterBase } from './OTLPExporterBase';\nexport { OTLPExporterError } from './types';\n\nexport type {\n ExportResponse,\n ExportResponseFailure,\n ExportResponseSuccess,\n ExportResponseRetryable,\n} from './export-response';\n\nexport type { IExporterTransport } from './exporter-transport';\n\nexport {\n mergeOtlpSharedConfigurationWithDefaults,\n getSharedConfigurationDefaults,\n} from './configuration/shared-configuration';\nexport type { OtlpSharedConfiguration } from './configuration/shared-configuration';\n\nexport { CompressionAlgorithm } from './configuration/legacy-node-configuration';\nexport type { OTLPExporterNodeConfigBase } from './configuration/legacy-node-configuration';\nexport type { OTLPExporterConfigBase } from './configuration/legacy-base-configuration';\nexport type { IOtlpExportDelegate } from './otlp-export-delegate';\nexport { createOtlpNetworkExportDelegate } from './otlp-network-export-delegate';\n"]}

View File

@@ -0,0 +1,3 @@
export declare function isExportHTTPErrorRetryable(statusCode: number): boolean;
export declare function parseRetryAfterToMills(retryAfter?: string | undefined | null): number | undefined;
//# sourceMappingURL=is-export-retryable.d.ts.map

View File

@@ -0,0 +1,31 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseRetryAfterToMills = exports.isExportHTTPErrorRetryable = void 0;
function isExportHTTPErrorRetryable(statusCode) {
return (statusCode === 429 ||
statusCode === 502 ||
statusCode === 503 ||
statusCode === 504);
}
exports.isExportHTTPErrorRetryable = isExportHTTPErrorRetryable;
function parseRetryAfterToMills(retryAfter) {
if (retryAfter == null) {
return undefined;
}
const seconds = Number.parseInt(retryAfter, 10);
if (Number.isInteger(seconds)) {
return seconds > 0 ? seconds * 1000 : -1;
}
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#directives
const delay = new Date(retryAfter).getTime() - Date.now();
if (delay >= 0) {
return delay;
}
return 0;
}
exports.parseRetryAfterToMills = parseRetryAfterToMills;
//# sourceMappingURL=is-export-retryable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-export-retryable.js","sourceRoot":"","sources":["../../src/is-export-retryable.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,SAAgB,0BAA0B,CAAC,UAAkB;IAC3D,OAAO,CACL,UAAU,KAAK,GAAG;QAClB,UAAU,KAAK,GAAG;QAClB,UAAU,KAAK,GAAG;QAClB,UAAU,KAAK,GAAG,CACnB,CAAC;AACJ,CAAC;AAPD,gEAOC;AAED,SAAgB,sBAAsB,CACpC,UAAsC;IAEtC,IAAI,UAAU,IAAI,IAAI,EAAE;QACtB,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;QAC7B,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC1C;IACD,mFAAmF;IACnF,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE1D,IAAI,KAAK,IAAI,CAAC,EAAE;QACd,OAAO,KAAK,CAAC;KACd;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAlBD,wDAkBC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport function isExportHTTPErrorRetryable(statusCode: number): boolean {\n return (\n statusCode === 429 ||\n statusCode === 502 ||\n statusCode === 503 ||\n statusCode === 504\n );\n}\n\nexport function parseRetryAfterToMills(\n retryAfter?: string | undefined | null\n): number | undefined {\n if (retryAfter == null) {\n return undefined;\n }\n\n const seconds = Number.parseInt(retryAfter, 10);\n if (Number.isInteger(seconds)) {\n return seconds > 0 ? seconds * 1000 : -1;\n }\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#directives\n const delay = new Date(retryAfter).getTime() - Date.now();\n\n if (delay >= 0) {\n return delay;\n }\n return 0;\n}\n"]}

View File

@@ -0,0 +1,6 @@
import type { IOtlpResponseHandler } from './response-handler';
/**
* Default response handler that logs a partial success to the console.
*/
export declare function createLoggingPartialSuccessResponseHandler<T>(): IOtlpResponseHandler<T>;
//# sourceMappingURL=logging-response-handler.d.ts.map

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLoggingPartialSuccessResponseHandler = void 0;
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
const api_1 = require("@opentelemetry/api");
function isPartialSuccessResponse(response) {
return Object.prototype.hasOwnProperty.call(response, 'partialSuccess');
}
/**
* Default response handler that logs a partial success to the console.
*/
function createLoggingPartialSuccessResponseHandler() {
return {
handleResponse(response) {
// Partial success MUST never be an empty object according the specification
// see https://opentelemetry.io/docs/specs/otlp/#partial-success
if (response == null ||
!isPartialSuccessResponse(response) ||
response.partialSuccess == null ||
Object.keys(response.partialSuccess).length === 0) {
return;
}
api_1.diag.warn('Received Partial Success response:', JSON.stringify(response.partialSuccess));
},
};
}
exports.createLoggingPartialSuccessResponseHandler = createLoggingPartialSuccessResponseHandler;
//# sourceMappingURL=logging-response-handler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"logging-response-handler.js","sourceRoot":"","sources":["../../src/logging-response-handler.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,4CAA0C;AAG1C,SAAS,wBAAwB,CAC/B,QAAiB;IAEjB,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,SAAgB,0CAA0C;IAGxD,OAAO;QACL,cAAc,CAAC,QAAW;YACxB,4EAA4E;YAC5E,gEAAgE;YAChE,IACE,QAAQ,IAAI,IAAI;gBAChB,CAAC,wBAAwB,CAAC,QAAQ,CAAC;gBACnC,QAAQ,CAAC,cAAc,IAAI,IAAI;gBAC/B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,KAAK,CAAC,EACjD;gBACA,OAAO;aACR;YACD,UAAI,CAAC,IAAI,CACP,oCAAoC,EACpC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,CACxC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AArBD,gGAqBC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { diag } from '@opentelemetry/api';\nimport type { IOtlpResponseHandler } from './response-handler';\n\nfunction isPartialSuccessResponse(\n response: unknown\n): response is { partialSuccess: never } {\n return Object.prototype.hasOwnProperty.call(response, 'partialSuccess');\n}\n\n/**\n * Default response handler that logs a partial success to the console.\n */\nexport function createLoggingPartialSuccessResponseHandler<\n T,\n>(): IOtlpResponseHandler<T> {\n return {\n handleResponse(response: T) {\n // Partial success MUST never be an empty object according the specification\n // see https://opentelemetry.io/docs/specs/otlp/#partial-success\n if (\n response == null ||\n !isPartialSuccessResponse(response) ||\n response.partialSuccess == null ||\n Object.keys(response.partialSuccess).length === 0\n ) {\n return;\n }\n diag.warn(\n 'Received Partial Success response:',\n JSON.stringify(response.partialSuccess)\n );\n },\n };\n}\n"]}

View File

@@ -0,0 +1,9 @@
import type { OtlpHttpConfiguration } from './configuration/otlp-http-configuration';
import type { ISerializer } from '@opentelemetry/otlp-transformer';
import type { IOtlpExportDelegate } from './otlp-export-delegate';
export declare function createOtlpFetchExportDelegate<Internal, Response>(options: OtlpHttpConfiguration, serializer: ISerializer<Internal, Response>): IOtlpExportDelegate<Internal>;
/**
* @deprecated Use {@link createOtlpFetchExportDelegate} instead. Modern browsers use `fetch` with `keepAlive: true` when `sendBeacon` is used. Use a `fetch` polyfill that mimics this behavior to keep using `sendBeacon`.
*/
export declare function createOtlpSendBeaconExportDelegate<Internal, Response>(options: OtlpHttpConfiguration, serializer: ISerializer<Internal, Response>): IOtlpExportDelegate<Internal>;
//# sourceMappingURL=otlp-browser-http-export-delegate.d.ts.map

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOtlpSendBeaconExportDelegate = exports.createOtlpFetchExportDelegate = void 0;
const retrying_transport_1 = require("./retrying-transport");
const otlp_network_export_delegate_1 = require("./otlp-network-export-delegate");
const fetch_transport_1 = require("./transport/fetch-transport");
function createOtlpFetchExportDelegate(options, serializer) {
return (0, otlp_network_export_delegate_1.createOtlpNetworkExportDelegate)(options, serializer, (0, retrying_transport_1.createRetryingTransport)({
transport: (0, fetch_transport_1.createFetchTransport)(options),
}));
}
exports.createOtlpFetchExportDelegate = createOtlpFetchExportDelegate;
/**
* @deprecated Use {@link createOtlpFetchExportDelegate} instead. Modern browsers use `fetch` with `keepAlive: true` when `sendBeacon` is used. Use a `fetch` polyfill that mimics this behavior to keep using `sendBeacon`.
*/
function createOtlpSendBeaconExportDelegate(options, serializer) {
return createOtlpFetchExportDelegate(options, serializer);
}
exports.createOtlpSendBeaconExportDelegate = createOtlpSendBeaconExportDelegate;
//# sourceMappingURL=otlp-browser-http-export-delegate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"otlp-browser-http-export-delegate.js","sourceRoot":"","sources":["../../src/otlp-browser-http-export-delegate.ts"],"names":[],"mappings":";;;AAOA,6DAA+D;AAC/D,iFAAiF;AACjF,iEAAmE;AAEnE,SAAgB,6BAA6B,CAC3C,OAA8B,EAC9B,UAA2C;IAE3C,OAAO,IAAA,8DAA+B,EACpC,OAAO,EACP,UAAU,EACV,IAAA,4CAAuB,EAAC;QACtB,SAAS,EAAE,IAAA,sCAAoB,EAAC,OAAO,CAAC;KACzC,CAAC,CACH,CAAC;AACJ,CAAC;AAXD,sEAWC;AAED;;GAEG;AACH,SAAgB,kCAAkC,CAChD,OAA8B,EAC9B,UAA2C;IAE3C,OAAO,6BAA6B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC5D,CAAC;AALD,gFAKC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { OtlpHttpConfiguration } from './configuration/otlp-http-configuration';\nimport type { ISerializer } from '@opentelemetry/otlp-transformer';\nimport type { IOtlpExportDelegate } from './otlp-export-delegate';\nimport { createRetryingTransport } from './retrying-transport';\nimport { createOtlpNetworkExportDelegate } from './otlp-network-export-delegate';\nimport { createFetchTransport } from './transport/fetch-transport';\n\nexport function createOtlpFetchExportDelegate<Internal, Response>(\n options: OtlpHttpConfiguration,\n serializer: ISerializer<Internal, Response>\n): IOtlpExportDelegate<Internal> {\n return createOtlpNetworkExportDelegate(\n options,\n serializer,\n createRetryingTransport({\n transport: createFetchTransport(options),\n })\n );\n}\n\n/**\n * @deprecated Use {@link createOtlpFetchExportDelegate} instead. Modern browsers use `fetch` with `keepAlive: true` when `sendBeacon` is used. Use a `fetch` polyfill that mimics this behavior to keep using `sendBeacon`.\n */\nexport function createOtlpSendBeaconExportDelegate<Internal, Response>(\n options: OtlpHttpConfiguration,\n serializer: ISerializer<Internal, Response>\n): IOtlpExportDelegate<Internal> {\n return createOtlpFetchExportDelegate(options, serializer);\n}\n"]}

View File

@@ -0,0 +1,24 @@
import type { ExportResult } from '@opentelemetry/core';
import type { IExporterTransport } from './exporter-transport';
import type { IExportPromiseHandler } from './bounded-queue-export-promise-handler';
import type { ISerializer } from '@opentelemetry/otlp-transformer';
/**
* Internally shared export logic for OTLP.
*/
export interface IOtlpExportDelegate<Internal> {
export(internalRepresentation: Internal, resultCallback: (result: ExportResult) => void): void;
forceFlush(): Promise<void>;
shutdown(): Promise<void>;
}
/**
* Creates a generic delegate for OTLP exports which only contains parts of the OTLP export that are shared across all
* signals.
*/
export declare function createOtlpExportDelegate<Internal, Response>(components: {
transport: IExporterTransport;
serializer: ISerializer<Internal, Response>;
promiseHandler: IExportPromiseHandler;
}, settings: {
timeout: number;
}): IOtlpExportDelegate<Internal>;
//# sourceMappingURL=otlp-export-delegate.d.ts.map

View File

@@ -0,0 +1,105 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOtlpExportDelegate = void 0;
const core_1 = require("@opentelemetry/core");
const types_1 = require("./types");
const logging_response_handler_1 = require("./logging-response-handler");
const api_1 = require("@opentelemetry/api");
class OTLPExportDelegate {
_diagLogger;
_transport;
_serializer;
_responseHandler;
_promiseQueue;
_timeout;
constructor(transport, serializer, responseHandler, promiseQueue, timeout) {
this._transport = transport;
this._serializer = serializer;
this._responseHandler = responseHandler;
this._promiseQueue = promiseQueue;
this._timeout = timeout;
this._diagLogger = api_1.diag.createComponentLogger({
namespace: 'OTLPExportDelegate',
});
}
export(internalRepresentation, resultCallback) {
this._diagLogger.debug('items to be sent', internalRepresentation);
// don't do any work if too many exports are in progress.
if (this._promiseQueue.hasReachedLimit()) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error('Concurrent export limit reached'),
});
return;
}
const serializedRequest = this._serializer.serializeRequest(internalRepresentation);
if (serializedRequest == null) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new Error('Nothing to send'),
});
return;
}
this._promiseQueue.pushPromise(this._transport.send(serializedRequest, this._timeout).then(response => {
if (response.status === 'success') {
if (response.data != null) {
try {
this._responseHandler.handleResponse(this._serializer.deserializeResponse(response.data));
}
catch (e) {
this._diagLogger.warn('Export succeeded but could not deserialize response - is the response specification compliant?', e, response.data);
}
}
// No matter the response, we can consider the export still successful.
resultCallback({
code: core_1.ExportResultCode.SUCCESS,
});
return;
}
else if (response.status === 'failure' && response.error) {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: response.error,
});
return;
}
else if (response.status === 'retryable') {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: response.error ??
new types_1.OTLPExporterError('Export failed with retryable status'),
});
}
else {
resultCallback({
code: core_1.ExportResultCode.FAILED,
error: new types_1.OTLPExporterError('Export failed with unknown error'),
});
}
}, reason => resultCallback({
code: core_1.ExportResultCode.FAILED,
error: reason,
})));
}
forceFlush() {
return this._promiseQueue.awaitAll();
}
async shutdown() {
this._diagLogger.debug('shutdown started');
await this.forceFlush();
this._transport.shutdown();
}
}
/**
* Creates a generic delegate for OTLP exports which only contains parts of the OTLP export that are shared across all
* signals.
*/
function createOtlpExportDelegate(components, settings) {
return new OTLPExportDelegate(components.transport, components.serializer, (0, logging_response_handler_1.createLoggingPartialSuccessResponseHandler)(), components.promiseHandler, settings.timeout);
}
exports.createOtlpExportDelegate = createOtlpExportDelegate;
//# sourceMappingURL=otlp-export-delegate.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
import type { IOtlpExportDelegate } from './otlp-export-delegate';
import type { ISerializer } from '@opentelemetry/otlp-transformer';
import type { OtlpNodeHttpConfiguration } from './configuration/otlp-node-http-configuration';
export declare function createOtlpHttpExportDelegate<Internal, Response>(options: OtlpNodeHttpConfiguration, serializer: ISerializer<Internal, Response>): IOtlpExportDelegate<Internal>;
//# sourceMappingURL=otlp-http-export-delegate.d.ts.map

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOtlpHttpExportDelegate = void 0;
const otlp_export_delegate_1 = require("./otlp-export-delegate");
const http_exporter_transport_1 = require("./transport/http-exporter-transport");
const bounded_queue_export_promise_handler_1 = require("./bounded-queue-export-promise-handler");
const retrying_transport_1 = require("./retrying-transport");
function createOtlpHttpExportDelegate(options, serializer) {
return (0, otlp_export_delegate_1.createOtlpExportDelegate)({
transport: (0, retrying_transport_1.createRetryingTransport)({
transport: (0, http_exporter_transport_1.createHttpExporterTransport)(options),
}),
serializer: serializer,
promiseHandler: (0, bounded_queue_export_promise_handler_1.createBoundedQueueExportPromiseHandler)(options),
}, { timeout: options.timeoutMillis });
}
exports.createOtlpHttpExportDelegate = createOtlpHttpExportDelegate;
//# sourceMappingURL=otlp-http-export-delegate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"otlp-http-export-delegate.js","sourceRoot":"","sources":["../../src/otlp-http-export-delegate.ts"],"names":[],"mappings":";;;AAKA,iEAAkE;AAElE,iFAAkF;AAClF,iGAAgG;AAChG,6DAA+D;AAG/D,SAAgB,4BAA4B,CAC1C,OAAkC,EAClC,UAA2C;IAE3C,OAAO,IAAA,+CAAwB,EAC7B;QACE,SAAS,EAAE,IAAA,4CAAuB,EAAC;YACjC,SAAS,EAAE,IAAA,qDAA2B,EAAC,OAAO,CAAC;SAChD,CAAC;QACF,UAAU,EAAE,UAAU;QACtB,cAAc,EAAE,IAAA,6EAAsC,EAAC,OAAO,CAAC;KAChE,EACD,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,CACnC,CAAC;AACJ,CAAC;AAdD,oEAcC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { IOtlpExportDelegate } from './otlp-export-delegate';\nimport { createOtlpExportDelegate } from './otlp-export-delegate';\nimport type { ISerializer } from '@opentelemetry/otlp-transformer';\nimport { createHttpExporterTransport } from './transport/http-exporter-transport';\nimport { createBoundedQueueExportPromiseHandler } from './bounded-queue-export-promise-handler';\nimport { createRetryingTransport } from './retrying-transport';\nimport type { OtlpNodeHttpConfiguration } from './configuration/otlp-node-http-configuration';\n\nexport function createOtlpHttpExportDelegate<Internal, Response>(\n options: OtlpNodeHttpConfiguration,\n serializer: ISerializer<Internal, Response>\n): IOtlpExportDelegate<Internal> {\n return createOtlpExportDelegate(\n {\n transport: createRetryingTransport({\n transport: createHttpExporterTransport(options),\n }),\n serializer: serializer,\n promiseHandler: createBoundedQueueExportPromiseHandler(options),\n },\n { timeout: options.timeoutMillis }\n );\n}\n"]}

View File

@@ -0,0 +1,6 @@
import type { OtlpSharedConfiguration } from './configuration/shared-configuration';
import type { ISerializer } from '@opentelemetry/otlp-transformer';
import type { IExporterTransport } from './exporter-transport';
import type { IOtlpExportDelegate } from './otlp-export-delegate';
export declare function createOtlpNetworkExportDelegate<Internal, Response>(options: OtlpSharedConfiguration, serializer: ISerializer<Internal, Response>, transport: IExporterTransport): IOtlpExportDelegate<Internal>;
//# sourceMappingURL=otlp-network-export-delegate.d.ts.map

View File

@@ -0,0 +1,18 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOtlpNetworkExportDelegate = void 0;
const bounded_queue_export_promise_handler_1 = require("./bounded-queue-export-promise-handler");
const otlp_export_delegate_1 = require("./otlp-export-delegate");
function createOtlpNetworkExportDelegate(options, serializer, transport) {
return (0, otlp_export_delegate_1.createOtlpExportDelegate)({
transport: transport,
serializer,
promiseHandler: (0, bounded_queue_export_promise_handler_1.createBoundedQueueExportPromiseHandler)(options),
}, { timeout: options.timeoutMillis });
}
exports.createOtlpNetworkExportDelegate = createOtlpNetworkExportDelegate;
//# sourceMappingURL=otlp-network-export-delegate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"otlp-network-export-delegate.js","sourceRoot":"","sources":["../../src/otlp-network-export-delegate.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,iGAAgG;AAKhG,iEAAkE;AAElE,SAAgB,+BAA+B,CAC7C,OAAgC,EAChC,UAA2C,EAC3C,SAA6B;IAE7B,OAAO,IAAA,+CAAwB,EAC7B;QACE,SAAS,EAAE,SAAS;QACpB,UAAU;QACV,cAAc,EAAE,IAAA,6EAAsC,EAAC,OAAO,CAAC;KAChE,EACD,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,CACnC,CAAC;AACJ,CAAC;AAbD,0EAaC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createBoundedQueueExportPromiseHandler } from './bounded-queue-export-promise-handler';\nimport type { OtlpSharedConfiguration } from './configuration/shared-configuration';\nimport type { ISerializer } from '@opentelemetry/otlp-transformer';\nimport type { IExporterTransport } from './exporter-transport';\nimport type { IOtlpExportDelegate } from './otlp-export-delegate';\nimport { createOtlpExportDelegate } from './otlp-export-delegate';\n\nexport function createOtlpNetworkExportDelegate<Internal, Response>(\n options: OtlpSharedConfiguration,\n serializer: ISerializer<Internal, Response>,\n transport: IExporterTransport\n): IOtlpExportDelegate<Internal> {\n return createOtlpExportDelegate(\n {\n transport: transport,\n serializer,\n promiseHandler: createBoundedQueueExportPromiseHandler(options),\n },\n { timeout: options.timeoutMillis }\n );\n}\n"]}

View File

@@ -0,0 +1,12 @@
/**
* Generic export response handler. Can be implemented to handle export responses like partial success.
*/
export interface IOtlpResponseHandler<Response> {
/**
* Handles an OTLP export response.
* Implementations MUST NOT throw.
* @param response
*/
handleResponse(response: Response): void;
}
//# sourceMappingURL=response-handler.d.ts.map

View File

@@ -0,0 +1,7 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=response-handler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"response-handler.js","sourceRoot":"","sources":["../../src/response-handler.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Generic export response handler. Can be implemented to handle export responses like partial success.\n */\nexport interface IOtlpResponseHandler<Response> {\n /**\n * Handles an OTLP export response.\n * Implementations MUST NOT throw.\n * @param response\n */\n handleResponse(response: Response): void;\n}\n"]}

View File

@@ -0,0 +1,8 @@
import type { IExporterTransport } from './exporter-transport';
/**
* Creates an Exporter Transport that retries on 'retryable' response.
*/
export declare function createRetryingTransport(options: {
transport: IExporterTransport;
}): IExporterTransport;
//# sourceMappingURL=retrying-transport.d.ts.map

View File

@@ -0,0 +1,74 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRetryingTransport = void 0;
const api_1 = require("@opentelemetry/api");
const MAX_ATTEMPTS = 5;
const INITIAL_BACKOFF = 1000;
const MAX_BACKOFF = 5000;
const BACKOFF_MULTIPLIER = 1.5;
const JITTER = 0.2;
/**
* Get a pseudo-random jitter that falls in the range of [-JITTER, +JITTER]
*/
function getJitter() {
return Math.random() * (2 * JITTER) - JITTER;
}
class RetryingTransport {
_transport;
constructor(transport) {
this._transport = transport;
}
retry(data, timeoutMillis, inMillis) {
return new Promise((resolve, reject) => {
setTimeout(() => {
this._transport.send(data, timeoutMillis).then(resolve, reject);
}, inMillis);
});
}
async send(data, timeoutMillis) {
let attempts = MAX_ATTEMPTS;
let nextBackoff = INITIAL_BACKOFF;
const deadline = Date.now() + timeoutMillis;
let result = await this._transport.send(data, timeoutMillis);
while (result.status === 'retryable' && attempts > 0) {
attempts--;
// use maximum of computed backoff and 0 to avoid negative timeouts
const backoff = Math.max(Math.min(nextBackoff * (1 + getJitter()), MAX_BACKOFF), 0);
nextBackoff = nextBackoff * BACKOFF_MULTIPLIER;
const retryInMillis = result.retryInMillis ?? backoff;
// return when expected retry time is after the export deadline.
const remainingTimeoutMillis = deadline - Date.now();
if (retryInMillis > remainingTimeoutMillis) {
api_1.diag.info(`Export retry time ${Math.round(retryInMillis)}ms exceeds remaining timeout ${Math.round(remainingTimeoutMillis)}ms, not retrying further.`);
return result;
}
api_1.diag.verbose(`Scheduling export retry in ${Math.round(retryInMillis)}ms`);
result = await this.retry(data, remainingTimeoutMillis, retryInMillis);
}
if (result.status === 'success') {
api_1.diag.verbose(`Export succeeded after ${MAX_ATTEMPTS - attempts} retry attempts.`);
}
else if (result.status === 'retryable') {
api_1.diag.info(`Export failed after maximum retry attempts (${MAX_ATTEMPTS}).`);
}
else {
api_1.diag.info(`Export failed with non-retryable error: ${result.error}`);
}
return result;
}
shutdown() {
return this._transport.shutdown();
}
}
/**
* Creates an Exporter Transport that retries on 'retryable' response.
*/
function createRetryingTransport(options) {
return new RetryingTransport(options.transport);
}
exports.createRetryingTransport = createRetryingTransport;
//# sourceMappingURL=retrying-transport.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import type { IExporterTransport } from '../exporter-transport';
import type { HeadersFactory } from '../configuration/otlp-http-configuration';
export interface FetchTransportParameters {
url: string;
headers: HeadersFactory;
}
/**
* Creates an exporter transport that uses `fetch` to send the data
* @param parameters applied to each request made by transport
*/
export declare function createFetchTransport(parameters: FetchTransportParameters): IExporterTransport;
//# sourceMappingURL=fetch-transport.d.ts.map

View File

@@ -0,0 +1,137 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFetchTransport = void 0;
const api_1 = require("@opentelemetry/api");
const is_export_retryable_1 = require("../is-export-retryable");
/**
* Maximum total body size for concurrent keepalive requests.
* Browsers enforce a 64KiB cumulative limit across all pending keepalive requests.
* We use 60KB to leave headroom for headers.
* @see https://github.com/whatwg/fetch/issues/679
* @see https://blog.huli.tw/2025/01/06/en/navigator-sendbeacon-64kib-and-source-code/
*/
const MAX_KEEPALIVE_BODY_SIZE = 60 * 1024;
/**
* Maximum concurrent keepalive requests.
* Chrome enforces 9 concurrent keepalive fetch requests per renderer process.
* @see https://github.com/whatwg/fetch/issues/679
* Quote: "If the renderer process is processing more than 9 requests with keepalive set, we reject a new request"
*/
const MAX_KEEPALIVE_REQUESTS = 9;
/**
* Track cumulative pending body size across all in-flight keepalive requests.
* This is necessary because the 64KiB limit is cumulative, not per-request.
*/
let pendingBodySize = 0;
/**
* Track number of pending keepalive requests.
*/
let pendingKeepaliveCount = 0;
class FetchTransport {
_parameters;
constructor(parameters) {
this._parameters = parameters;
}
async send(data, timeoutMillis) {
const abortController = new AbortController();
const timeout = setTimeout(() => abortController.abort(), timeoutMillis);
// Fetch API may be wrapped by an instrumentation like `@opentelemetry/instrumentation-fetch`.
// In that case the instrumentation would create a new Span for this request
// because the context manager cannot keep the context after `await` calls.
// This creates an indirect endless loop Export -> Span -> Export
// By using the `__original` function the instrumentation can't intercept the call
// and no Span will be created breaking the vicious cycle
let fetchApi = globalThis.fetch;
// @ts-expect-error -- fetch could be wrapped
if (typeof fetchApi.__original === 'function') {
// @ts-expect-error -- fetch could be wrapped
fetchApi = fetchApi.__original;
}
const requestSize = data.byteLength;
// Determine if we can use keepalive based on cumulative browser limits.
// We must check BEFORE adding to pending totals to avoid exceeding limits.
const wouldExceedSize = pendingBodySize + requestSize > MAX_KEEPALIVE_BODY_SIZE;
const wouldExceedCount = pendingKeepaliveCount >= MAX_KEEPALIVE_REQUESTS;
const useKeepalive = !wouldExceedSize && !wouldExceedCount;
if (useKeepalive) {
pendingBodySize += requestSize;
pendingKeepaliveCount++;
}
else {
const reason = wouldExceedSize ? 'size limit' : 'count limit';
api_1.diag.debug(`keepalive disabled: ${(requestSize / 1024).toFixed(1)}KB payload, ${pendingKeepaliveCount} pending (${reason})`);
}
try {
const url = new URL(this._parameters.url);
const response = await fetchApi(url.href, {
method: 'POST',
headers: await this._parameters.headers(),
body: data,
signal: abortController.signal,
keepalive: useKeepalive,
mode: globalThis.location
? globalThis.location.origin === url.origin
? 'same-origin'
: 'cors'
: 'no-cors',
});
if (response.status >= 200 && response.status <= 299) {
api_1.diag.debug(`export response success (status: ${response.status})`);
return { status: 'success' };
}
else if ((0, is_export_retryable_1.isExportHTTPErrorRetryable)(response.status)) {
api_1.diag.warn(`export response retryable (status: ${response.status})`);
const retryAfter = response.headers.get('Retry-After');
const retryInMillis = (0, is_export_retryable_1.parseRetryAfterToMills)(retryAfter);
return { status: 'retryable', retryInMillis };
}
api_1.diag.error(`export response failure (status: ${response.status})`);
return {
status: 'failure',
error: new Error(`Fetch request failed with non-retryable status ${response.status}`),
};
}
catch (error) {
if (isFetchNetworkErrorRetryable(error)) {
api_1.diag.warn(`export request retryable (network error: ${error})`);
return {
status: 'retryable',
error: new Error('Fetch request encountered a network error', {
cause: error,
}),
};
}
api_1.diag.error(`export request failure (error: ${error})`);
return {
status: 'failure',
error: new Error('Fetch request errored', { cause: error }),
};
}
finally {
clearTimeout(timeout);
if (useKeepalive) {
pendingBodySize -= requestSize;
pendingKeepaliveCount--;
}
}
}
shutdown() {
// Intentionally left empty, nothing to do.
}
}
/**
* Creates an exporter transport that uses `fetch` to send the data
* @param parameters applied to each request made by transport
*/
function createFetchTransport(parameters) {
return new FetchTransport(parameters);
}
exports.createFetchTransport = createFetchTransport;
function isFetchNetworkErrorRetryable(error) {
return error instanceof TypeError && !error.cause;
}
//# sourceMappingURL=fetch-transport.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
import type { IExporterTransport } from '../exporter-transport';
import type { NodeHttpRequestParameters } from './node-http-transport-types';
export declare function createHttpExporterTransport(parameters: NodeHttpRequestParameters): IExporterTransport;
//# sourceMappingURL=http-exporter-transport.d.ts.map

View File

@@ -0,0 +1,45 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createHttpExporterTransport = void 0;
const http_transport_utils_1 = require("./http-transport-utils");
class HttpExporterTransport {
_utils = null;
_parameters;
constructor(parameters) {
this._parameters = parameters;
}
async send(data, timeoutMillis) {
const { agent, request } = await this._loadUtils();
const headers = await this._parameters.headers();
return (0, http_transport_utils_1.sendWithHttp)(request, this._parameters.url, headers, this._parameters.compression, this._parameters.userAgent, agent, data, timeoutMillis);
}
shutdown() {
// intentionally left empty, nothing to do.
}
async _loadUtils() {
let utils = this._utils;
if (utils === null) {
const protocol = new URL(this._parameters.url).protocol;
const [agent, request] = await Promise.all([
this._parameters.agentFactory(protocol),
requestFunctionFactory(protocol),
]);
utils = this._utils = { agent, request };
}
return utils;
}
}
async function requestFunctionFactory(protocol) {
const module = protocol === 'http:' ? import('http') : import('https');
const { request } = await module;
return request;
}
function createHttpExporterTransport(parameters) {
return new HttpExporterTransport(parameters);
}
exports.createHttpExporterTransport = createHttpExporterTransport;
//# sourceMappingURL=http-exporter-transport.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"http-exporter-transport.js","sourceRoot":"","sources":["../../../src/transport/http-exporter-transport.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAQH,iEAAsD;AAQtD,MAAM,qBAAqB;IACjB,MAAM,GAAiB,IAAI,CAAC;IAC5B,WAAW,CAA4B;IAE/C,YAAY,UAAqC;QAC/C,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAgB,EAAE,aAAqB;QAChD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjD,OAAO,IAAA,mCAAY,EACjB,OAAO,EACP,IAAI,CAAC,WAAW,CAAC,GAAG,EACpB,OAAO,EACP,IAAI,CAAC,WAAW,CAAC,WAAW,EAC5B,IAAI,CAAC,WAAW,CAAC,SAAS,EAC1B,KAAK,EACL,IAAI,EACJ,aAAa,CACd,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,2CAA2C;IAC7C,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAExB,IAAI,KAAK,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;YACxD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACzC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC;gBACvC,sBAAsB,CAAC,QAAQ,CAAC;aACjC,CAAC,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;SAC1C;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED,KAAK,UAAU,sBAAsB,CACnC,QAAgB;IAEhB,MAAM,MAAM,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,2BAA2B,CACzC,UAAqC;IAErC,OAAO,IAAI,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC;AAJD,kEAIC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// NOTE: do not change these type imports to actual imports. Doing so WILL break `@opentelemetry/instrumentation-http`,\n// as they'd be imported before the http/https modules can be wrapped.\nimport type * as https from 'https';\nimport type * as http from 'http';\nimport type { ExportResponse } from '../export-response';\nimport type { IExporterTransport } from '../exporter-transport';\nimport { sendWithHttp } from './http-transport-utils';\nimport type { NodeHttpRequestParameters } from './node-http-transport-types';\n\ninterface Utils {\n agent: http.Agent | https.Agent;\n request: typeof http.request | typeof https.request;\n}\n\nclass HttpExporterTransport implements IExporterTransport {\n private _utils: Utils | null = null;\n private _parameters: NodeHttpRequestParameters;\n\n constructor(parameters: NodeHttpRequestParameters) {\n this._parameters = parameters;\n }\n\n async send(data: Uint8Array, timeoutMillis: number): Promise<ExportResponse> {\n const { agent, request } = await this._loadUtils();\n const headers = await this._parameters.headers();\n\n return sendWithHttp(\n request,\n this._parameters.url,\n headers,\n this._parameters.compression,\n this._parameters.userAgent,\n agent,\n data,\n timeoutMillis\n );\n }\n\n shutdown() {\n // intentionally left empty, nothing to do.\n }\n\n private async _loadUtils(): Promise<Utils> {\n let utils = this._utils;\n\n if (utils === null) {\n const protocol = new URL(this._parameters.url).protocol;\n const [agent, request] = await Promise.all([\n this._parameters.agentFactory(protocol),\n requestFunctionFactory(protocol),\n ]);\n utils = this._utils = { agent, request };\n }\n\n return utils;\n }\n}\n\nasync function requestFunctionFactory(\n protocol: string\n): Promise<typeof http.request | typeof https.request> {\n const module = protocol === 'http:' ? import('http') : import('https');\n const { request } = await module;\n return request;\n}\n\nexport function createHttpExporterTransport(\n parameters: NodeHttpRequestParameters\n): IExporterTransport {\n return new HttpExporterTransport(parameters);\n}\n"]}

View File

@@ -0,0 +1,8 @@
import type { HeadersFactory } from '../configuration/otlp-http-configuration';
export interface HttpRequestParameters {
url: string;
headers: HeadersFactory;
compression: 'gzip' | 'none';
userAgent?: string;
}
//# sourceMappingURL=http-transport-types.d.ts.map

View File

@@ -0,0 +1,7 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=http-transport-types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"http-transport-types.js","sourceRoot":"","sources":["../../../src/transport/http-transport-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HeadersFactory } from '../configuration/otlp-http-configuration';\n\nexport interface HttpRequestParameters {\n url: string;\n headers: HeadersFactory;\n compression: 'gzip' | 'none';\n userAgent?: string;\n}\n"]}

View File

@@ -0,0 +1,19 @@
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'http';
import type * as https from 'https';
import type { ExportResponse } from '../export-response';
/**
* Sends data using http
* @param request
* @param url
* @param headers
* @param compression
* @param userAgent
* @param agent
* @param data
* @param timeoutMillis
*/
export declare function sendWithHttp(request: typeof https.request | typeof http.request, url: string, headers: Record<string, string>, compression: 'gzip' | 'none', userAgent: string | undefined, agent: http.Agent | https.Agent, data: Uint8Array, timeoutMillis: number): Promise<ExportResponse>;
export declare function compressAndSend(req: http.ClientRequest, compression: 'gzip' | 'none', data: Uint8Array, onError: (error: Error) => void): void;
//# sourceMappingURL=http-transport-utils.d.ts.map

View File

@@ -0,0 +1,153 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.compressAndSend = exports.sendWithHttp = void 0;
const zlib = require("zlib");
const stream_1 = require("stream");
const is_export_retryable_1 = require("../is-export-retryable");
const types_1 = require("../types");
const version_1 = require("../version");
const DEFAULT_USER_AGENT = `OTel-OTLP-Exporter-JavaScript/${version_1.VERSION}`;
/**
* Sends data using http
* @param request
* @param url
* @param headers
* @param compression
* @param userAgent
* @param agent
* @param data
* @param timeoutMillis
*/
function sendWithHttp(request, url, headers, compression, userAgent, agent, data, timeoutMillis) {
return new Promise(resolve => {
const parsedUrl = new URL(url);
if (userAgent) {
headers['User-Agent'] = `${userAgent} ${DEFAULT_USER_AGENT}`;
}
else {
headers['User-Agent'] = DEFAULT_USER_AGENT;
}
const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port,
path: parsedUrl.pathname,
method: 'POST',
headers,
agent,
};
const req = request(options, (res) => {
const responseData = [];
res.on('data', chunk => responseData.push(chunk));
res.on('end', () => {
if (res.statusCode && res.statusCode <= 299) {
resolve({
status: 'success',
data: Buffer.concat(responseData),
});
}
else if (res.statusCode &&
(0, is_export_retryable_1.isExportHTTPErrorRetryable)(res.statusCode)) {
resolve({
status: 'retryable',
retryInMillis: (0, is_export_retryable_1.parseRetryAfterToMills)(res.headers['retry-after']),
});
}
else {
const error = new types_1.OTLPExporterError(res.statusMessage, res.statusCode, Buffer.concat(responseData).toString());
resolve({
status: 'failure',
error,
});
}
});
res.on('error', (error) => {
// Note: 'end' may still be emitted after 'error' on the same response object, since we're resolving a promise,
// the first call to resolve() will determine the final state.
if (res.statusCode && res.statusCode <= 299) {
// If the response is successful but an error occurs while reading the response,
// we consider it a success since the data has been sent successfully.
resolve({
status: 'success',
});
}
else if (res.statusCode &&
(0, is_export_retryable_1.isExportHTTPErrorRetryable)(res.statusCode)) {
resolve({
status: 'retryable',
error: error,
retryInMillis: (0, is_export_retryable_1.parseRetryAfterToMills)(res.headers['retry-after']),
});
}
else {
resolve({
status: 'failure',
error,
});
}
});
});
req.setTimeout(timeoutMillis, () => {
req.destroy();
resolve({
status: 'retryable',
error: new Error('Request timed out'),
});
});
req.on('error', (error) => {
if (isHttpTransportNetworkErrorRetryable(error)) {
resolve({
status: 'retryable',
error,
});
}
else {
resolve({
status: 'failure',
error,
});
}
});
compressAndSend(req, compression, data, (error) => {
resolve({
status: 'failure',
error,
});
});
});
}
exports.sendWithHttp = sendWithHttp;
function compressAndSend(req, compression, data, onError) {
let dataStream = readableFromUint8Array(data);
if (compression === 'gzip') {
req.setHeader('Content-Encoding', 'gzip');
dataStream = dataStream
.on('error', onError)
.pipe(zlib.createGzip())
.on('error', onError);
}
dataStream.pipe(req).on('error', onError);
}
exports.compressAndSend = compressAndSend;
function readableFromUint8Array(buff) {
const readable = new stream_1.Readable();
readable.push(buff);
readable.push(null);
return readable;
}
function isHttpTransportNetworkErrorRetryable(error) {
const RETRYABLE_NETWORK_ERROR_CODES = new Set([
'ECONNRESET',
'ECONNREFUSED',
'EPIPE',
'ETIMEDOUT',
'EAI_AGAIN',
'ENOTFOUND',
'ENETUNREACH',
'EHOSTUNREACH',
]);
if ('code' in error && typeof error.code === 'string') {
return RETRYABLE_NETWORK_ERROR_CODES.has(error.code);
}
return false;
}
//# sourceMappingURL=http-transport-utils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import type { HttpAgentFactory } from '../configuration/otlp-node-http-configuration';
import type { HttpRequestParameters } from './http-transport-types';
export interface NodeHttpRequestParameters extends HttpRequestParameters {
agentFactory: HttpAgentFactory;
}
//# sourceMappingURL=node-http-transport-types.d.ts.map

View File

@@ -0,0 +1,7 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=node-http-transport-types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"node-http-transport-types.js","sourceRoot":"","sources":["../../../src/transport/node-http-transport-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HttpAgentFactory } from '../configuration/otlp-node-http-configuration';\nimport type { HttpRequestParameters } from './http-transport-types';\n\nexport interface NodeHttpRequestParameters extends HttpRequestParameters {\n agentFactory: HttpAgentFactory;\n}\n"]}

View File

@@ -0,0 +1,23 @@
/**
* Interface for handling error
*/
export declare class OTLPExporterError extends Error {
readonly code?: number;
readonly name: string;
readonly data?: string;
constructor(message?: string, code?: number, data?: string);
}
/**
* Interface for handling export service errors
*/
export interface ExportServiceError {
name: string;
code: number;
details: string;
metadata: {
[key: string]: unknown;
};
message: string;
stack: string;
}
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1,22 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.OTLPExporterError = void 0;
/**
* Interface for handling error
*/
class OTLPExporterError extends Error {
code;
name = 'OTLPExporterError';
data;
constructor(message, code, data) {
super(message);
this.data = data;
this.code = code;
}
}
exports.OTLPExporterError = OTLPExporterError;
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,MAAa,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAU;IACL,IAAI,GAAW,mBAAmB,CAAC;IAC5C,IAAI,CAAU;IAEvB,YAAY,OAAgB,EAAE,IAAa,EAAE,IAAa;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAVD,8CAUC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Interface for handling error\n */\nexport class OTLPExporterError extends Error {\n readonly code?: number;\n override readonly name: string = 'OTLPExporterError';\n readonly data?: string;\n\n constructor(message?: string, code?: number, data?: string) {\n super(message);\n this.data = data;\n this.code = code;\n }\n}\n\n/**\n * Interface for handling export service errors\n */\nexport interface ExportServiceError {\n name: string;\n code: number;\n details: string;\n metadata: { [key: string]: unknown };\n message: string;\n stack: string;\n}\n"]}

View File

@@ -0,0 +1,6 @@
/**
* Parses headers from config leaving only those that have defined values
* @param partialHeaders
*/
export declare function validateAndNormalizeHeaders(partialHeaders: Record<string, string> | undefined): Record<string, string>;
//# sourceMappingURL=util.d.ts.map

View File

@@ -0,0 +1,26 @@
"use strict";
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateAndNormalizeHeaders = void 0;
const api_1 = require("@opentelemetry/api");
/**
* Parses headers from config leaving only those that have defined values
* @param partialHeaders
*/
function validateAndNormalizeHeaders(partialHeaders) {
const headers = {};
Object.entries(partialHeaders ?? {}).forEach(([key, value]) => {
if (typeof value !== 'undefined') {
headers[key] = String(value);
}
else {
api_1.diag.warn(`Header "${key}" has invalid value (${value}) and will be ignored`);
}
});
return headers;
}
exports.validateAndNormalizeHeaders = validateAndNormalizeHeaders;
//# sourceMappingURL=util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,4CAA0C;AAE1C;;;GAGG;AACH,SAAgB,2BAA2B,CACzC,cAAkD;IAElD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5D,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE;YAChC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;SAC9B;aAAM;YACL,UAAI,CAAC,IAAI,CACP,WAAW,GAAG,wBAAwB,KAAK,uBAAuB,CACnE,CAAC;SACH;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAdD,kEAcC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { diag } from '@opentelemetry/api';\n\n/**\n * Parses headers from config leaving only those that have defined values\n * @param partialHeaders\n */\nexport function validateAndNormalizeHeaders(\n partialHeaders: Record<string, string> | undefined\n): Record<string, string> {\n const headers: Record<string, string> = {};\n Object.entries(partialHeaders ?? {}).forEach(([key, value]) => {\n if (typeof value !== 'undefined') {\n headers[key] = String(value);\n } else {\n diag.warn(\n `Header \"${key}\" has invalid value (${value}) and will be ignored`\n );\n }\n });\n return headers;\n}\n"]}

View File

@@ -0,0 +1,2 @@
export declare const VERSION = "0.214.0";
//# sourceMappingURL=version.d.ts.map

Some files were not shown because too many files have changed in this diff Show More