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,24 @@
import type { TracerProvider, Tracer as ApiTracer } from '@opentelemetry/api';
import type { TracerConfig } from './types';
export declare enum ForceFlushState {
'resolved' = 0,
'timeout' = 1,
'error' = 2,
'unresolved' = 3
}
/**
* This class represents a basic tracer provider which platform libraries can extend
*/
export declare class BasicTracerProvider implements TracerProvider {
private readonly _config;
private readonly _tracers;
private readonly _resource;
private readonly _activeSpanProcessor;
constructor(config?: TracerConfig);
getTracer(name: string, version?: string, options?: {
schemaUrl?: string;
}): ApiTracer;
forceFlush(): Promise<void>;
shutdown(): Promise<void>;
}
//# sourceMappingURL=BasicTracerProvider.d.ts.map

View File

@@ -0,0 +1,89 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { merge } from '@opentelemetry/core';
import { defaultResource } from '@opentelemetry/resources';
import { Tracer } from './Tracer';
import { loadDefaultConfig } from './config';
import { MultiSpanProcessor } from './MultiSpanProcessor';
import { reconfigureLimits } from './utility';
export var ForceFlushState;
(function (ForceFlushState) {
ForceFlushState[ForceFlushState["resolved"] = 0] = "resolved";
ForceFlushState[ForceFlushState["timeout"] = 1] = "timeout";
ForceFlushState[ForceFlushState["error"] = 2] = "error";
ForceFlushState[ForceFlushState["unresolved"] = 3] = "unresolved";
})(ForceFlushState || (ForceFlushState = {}));
/**
* This class represents a basic tracer provider which platform libraries can extend
*/
export class BasicTracerProvider {
_config;
_tracers = new Map();
_resource;
_activeSpanProcessor;
constructor(config = {}) {
const mergedConfig = merge({}, loadDefaultConfig(), reconfigureLimits(config));
this._resource = mergedConfig.resource ?? defaultResource();
this._config = Object.assign({}, mergedConfig, {
resource: this._resource,
});
const spanProcessors = [];
if (config.spanProcessors?.length) {
spanProcessors.push(...config.spanProcessors);
}
this._activeSpanProcessor = new MultiSpanProcessor(spanProcessors);
}
getTracer(name, version, options) {
const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;
if (!this._tracers.has(key)) {
this._tracers.set(key, new Tracer({ name, version, schemaUrl: options?.schemaUrl }, this._config, this._resource, this._activeSpanProcessor));
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this._tracers.get(key);
}
forceFlush() {
const timeout = this._config.forceFlushTimeoutMillis;
const promises = this._activeSpanProcessor['_spanProcessors'].map((spanProcessor) => {
return new Promise(resolve => {
let state;
const timeoutInterval = setTimeout(() => {
resolve(new Error(`Span processor did not completed within timeout period of ${timeout} ms`));
state = ForceFlushState.timeout;
}, timeout);
spanProcessor
.forceFlush()
.then(() => {
clearTimeout(timeoutInterval);
if (state !== ForceFlushState.timeout) {
state = ForceFlushState.resolved;
resolve(state);
}
})
.catch(error => {
clearTimeout(timeoutInterval);
state = ForceFlushState.error;
resolve(error);
});
});
});
return new Promise((resolve, reject) => {
Promise.all(promises)
.then(results => {
const errors = results.filter(result => result !== ForceFlushState.resolved);
if (errors.length > 0) {
reject(errors);
}
else {
resolve();
}
})
.catch(error => reject([error]));
});
}
shutdown() {
return this._activeSpanProcessor.shutdown();
}
}
//# sourceMappingURL=BasicTracerProvider.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/** IdGenerator provides an interface for generating Trace Id and Span Id */
export interface IdGenerator {
/** Returns a trace ID composed of 32 lowercase hex characters. */
generateTraceId(): string;
/** Returns a span ID composed of 16 lowercase hex characters. */
generateSpanId(): string;
}
//# sourceMappingURL=IdGenerator.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=IdGenerator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IdGenerator.js","sourceRoot":"","sources":["../../src/IdGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/** IdGenerator provides an interface for generating Trace Id and Span Id */\nexport interface IdGenerator {\n /** Returns a trace ID composed of 32 lowercase hex characters. */\n generateTraceId(): string;\n /** Returns a span ID composed of 16 lowercase hex characters. */\n generateSpanId(): string;\n}\n"]}

View File

@@ -0,0 +1,18 @@
import type { Context } from '@opentelemetry/api';
import type { ReadableSpan } from './export/ReadableSpan';
import type { Span } from './Span';
import type { SpanProcessor } from './SpanProcessor';
/**
* Implementation of the {@link SpanProcessor} that simply forwards all
* received events to a list of {@link SpanProcessor}s.
*/
export declare class MultiSpanProcessor implements SpanProcessor {
private readonly _spanProcessors;
constructor(spanProcessors: SpanProcessor[]);
forceFlush(): Promise<void>;
onStart(span: Span, context: Context): void;
onEnding(span: Span): void;
onEnd(span: ReadableSpan): void;
shutdown(): Promise<void>;
}
//# sourceMappingURL=MultiSpanProcessor.d.ts.map

View File

@@ -0,0 +1,60 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { globalErrorHandler } from '@opentelemetry/core';
/**
* Implementation of the {@link SpanProcessor} that simply forwards all
* received events to a list of {@link SpanProcessor}s.
*/
export class MultiSpanProcessor {
_spanProcessors;
constructor(spanProcessors) {
this._spanProcessors = spanProcessors;
}
forceFlush() {
const promises = [];
for (const spanProcessor of this._spanProcessors) {
promises.push(spanProcessor.forceFlush());
}
return new Promise(resolve => {
Promise.all(promises)
.then(() => {
resolve();
})
.catch(error => {
globalErrorHandler(error || new Error('MultiSpanProcessor: forceFlush failed'));
resolve();
});
});
}
onStart(span, context) {
for (const spanProcessor of this._spanProcessors) {
spanProcessor.onStart(span, context);
}
}
onEnding(span) {
for (const spanProcessor of this._spanProcessors) {
if (spanProcessor.onEnding) {
spanProcessor.onEnding(span);
}
}
}
onEnd(span) {
for (const spanProcessor of this._spanProcessors) {
spanProcessor.onEnd(span);
}
}
shutdown() {
const promises = [];
for (const spanProcessor of this._spanProcessors) {
promises.push(spanProcessor.shutdown());
}
return new Promise((resolve, reject) => {
Promise.all(promises).then(() => {
resolve();
}, reject);
});
}
}
//# sourceMappingURL=MultiSpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MultiSpanProcessor.js","sourceRoot":"","sources":["../../src/MultiSpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAKzD;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACZ,eAAe,CAAkB;IAClD,YAAY,cAA+B;QACzC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;IACxC,CAAC;IAED,UAAU;QACR,MAAM,QAAQ,GAAoB,EAAE,CAAC;QAErC,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE;YAChD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;SAC3C;QACD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;iBAClB,IAAI,CAAC,GAAG,EAAE;gBACT,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;iBACD,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,kBAAkB,CAChB,KAAK,IAAI,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAC5D,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,IAAU,EAAE,OAAgB;QAClC,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE;YAChD,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SACtC;IACH,CAAC;IAED,QAAQ,CAAC,IAAU;QACjB,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE;YAChD,IAAI,aAAa,CAAC,QAAQ,EAAE;gBAC1B,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC9B;SACF;IACH,CAAC;IAED,KAAK,CAAC,IAAkB;QACtB,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE;YAChD,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAC3B;IACH,CAAC;IAED,QAAQ;QACN,MAAM,QAAQ,GAAoB,EAAE,CAAC;QAErC,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE;YAChD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,MAAM,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Context } from '@opentelemetry/api';\nimport { globalErrorHandler } from '@opentelemetry/core';\nimport type { ReadableSpan } from './export/ReadableSpan';\nimport type { Span } from './Span';\nimport type { SpanProcessor } from './SpanProcessor';\n\n/**\n * Implementation of the {@link SpanProcessor} that simply forwards all\n * received events to a list of {@link SpanProcessor}s.\n */\nexport class MultiSpanProcessor implements SpanProcessor {\n private readonly _spanProcessors: SpanProcessor[];\n constructor(spanProcessors: SpanProcessor[]) {\n this._spanProcessors = spanProcessors;\n }\n\n forceFlush(): Promise<void> {\n const promises: Promise<void>[] = [];\n\n for (const spanProcessor of this._spanProcessors) {\n promises.push(spanProcessor.forceFlush());\n }\n return new Promise(resolve => {\n Promise.all(promises)\n .then(() => {\n resolve();\n })\n .catch(error => {\n globalErrorHandler(\n error || new Error('MultiSpanProcessor: forceFlush failed')\n );\n resolve();\n });\n });\n }\n\n onStart(span: Span, context: Context): void {\n for (const spanProcessor of this._spanProcessors) {\n spanProcessor.onStart(span, context);\n }\n }\n\n onEnding(span: Span): void {\n for (const spanProcessor of this._spanProcessors) {\n if (spanProcessor.onEnding) {\n spanProcessor.onEnding(span);\n }\n }\n }\n\n onEnd(span: ReadableSpan): void {\n for (const spanProcessor of this._spanProcessors) {\n spanProcessor.onEnd(span);\n }\n }\n\n shutdown(): Promise<void> {\n const promises: Promise<void>[] = [];\n\n for (const spanProcessor of this._spanProcessors) {\n promises.push(spanProcessor.shutdown());\n }\n return new Promise((resolve, reject) => {\n Promise.all(promises).then(() => {\n resolve();\n }, reject);\n });\n }\n}\n"]}

View File

@@ -0,0 +1,70 @@
import type { Context, Link, Attributes, SpanKind, TraceState } from '@opentelemetry/api';
/**
* A sampling decision that determines how a {@link Span} will be recorded
* and collected.
*/
export declare enum SamplingDecision {
/**
* `Span.isRecording() === false`, span will not be recorded and all events
* and attributes will be dropped.
*/
NOT_RECORD = 0,
/**
* `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags}
* MUST NOT be set.
*/
RECORD = 1,
/**
* `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags}
* MUST be set.
*/
RECORD_AND_SAMPLED = 2
}
/**
* A sampling result contains a decision for a {@link Span} and additional
* attributes the sampler would like to added to the Span.
*/
export interface SamplingResult {
/**
* A sampling decision, refer to {@link SamplingDecision} for details.
*/
decision: SamplingDecision;
/**
* The list of attributes returned by SamplingResult MUST be immutable.
* Caller may call {@link Sampler}.shouldSample any number of times and
* can safely cache the returned value.
*/
attributes?: Readonly<Attributes>;
/**
* A {@link TraceState} that will be associated with the {@link Span} through
* the new {@link SpanContext}. Samplers SHOULD return the TraceState from
* the passed-in {@link Context} if they do not intend to change it. Leaving
* the value undefined will also leave the TraceState unchanged.
*/
traceState?: TraceState;
}
/**
* This interface represent a sampler. Sampling is a mechanism to control the
* noise and overhead introduced by OpenTelemetry by reducing the number of
* samples of traces collected and sent to the backend.
*/
export interface Sampler {
/**
* Checks whether span needs to be created and tracked.
*
* @param context Parent Context which may contain a span.
* @param traceId of the span to be created. It can be different from the
* traceId in the {@link SpanContext}. Typically in situations when the
* span to be created starts a new trace.
* @param spanName of the span to be created.
* @param spanKind of the span to be created.
* @param attributes Initial set of Attributes for the Span being constructed.
* @param links Collection of links that will be associated with the Span to
* be created. Typically useful for batch operations.
* @returns a {@link SamplingResult}.
*/
shouldSample(context: Context, traceId: string, spanName: string, spanKind: SpanKind, attributes: Attributes, links: Link[]): SamplingResult;
/** Returns the sampler name or short description with the configuration. */
toString(): string;
}
//# sourceMappingURL=Sampler.d.ts.map

View File

@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/**
* A sampling decision that determines how a {@link Span} will be recorded
* and collected.
*/
export var SamplingDecision;
(function (SamplingDecision) {
/**
* `Span.isRecording() === false`, span will not be recorded and all events
* and attributes will be dropped.
*/
SamplingDecision[SamplingDecision["NOT_RECORD"] = 0] = "NOT_RECORD";
/**
* `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags}
* MUST NOT be set.
*/
SamplingDecision[SamplingDecision["RECORD"] = 1] = "RECORD";
/**
* `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags}
* MUST be set.
*/
SamplingDecision[SamplingDecision["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED";
})(SamplingDecision || (SamplingDecision = {}));
//# sourceMappingURL=Sampler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Sampler.js","sourceRoot":"","sources":["../../src/Sampler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;GAGG;AACH,MAAM,CAAN,IAAY,gBAgBX;AAhBD,WAAY,gBAAgB;IAC1B;;;OAGG;IACH,mEAAU,CAAA;IACV;;;OAGG;IACH,2DAAM,CAAA;IACN;;;OAGG;IACH,mFAAkB,CAAA;AACpB,CAAC,EAhBW,gBAAgB,KAAhB,gBAAgB,QAgB3B","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n Context,\n Link,\n Attributes,\n SpanKind,\n TraceState,\n} from '@opentelemetry/api';\n\n/**\n * A sampling decision that determines how a {@link Span} will be recorded\n * and collected.\n */\nexport enum SamplingDecision {\n /**\n * `Span.isRecording() === false`, span will not be recorded and all events\n * and attributes will be dropped.\n */\n NOT_RECORD,\n /**\n * `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags}\n * MUST NOT be set.\n */\n RECORD,\n /**\n * `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags}\n * MUST be set.\n */\n RECORD_AND_SAMPLED,\n}\n\n/**\n * A sampling result contains a decision for a {@link Span} and additional\n * attributes the sampler would like to added to the Span.\n */\nexport interface SamplingResult {\n /**\n * A sampling decision, refer to {@link SamplingDecision} for details.\n */\n decision: SamplingDecision;\n /**\n * The list of attributes returned by SamplingResult MUST be immutable.\n * Caller may call {@link Sampler}.shouldSample any number of times and\n * can safely cache the returned value.\n */\n attributes?: Readonly<Attributes>;\n /**\n * A {@link TraceState} that will be associated with the {@link Span} through\n * the new {@link SpanContext}. Samplers SHOULD return the TraceState from\n * the passed-in {@link Context} if they do not intend to change it. Leaving\n * the value undefined will also leave the TraceState unchanged.\n */\n traceState?: TraceState;\n}\n\n/**\n * This interface represent a sampler. Sampling is a mechanism to control the\n * noise and overhead introduced by OpenTelemetry by reducing the number of\n * samples of traces collected and sent to the backend.\n */\nexport interface Sampler {\n /**\n * Checks whether span needs to be created and tracked.\n *\n * @param context Parent Context which may contain a span.\n * @param traceId of the span to be created. It can be different from the\n * traceId in the {@link SpanContext}. Typically in situations when the\n * span to be created starts a new trace.\n * @param spanName of the span to be created.\n * @param spanKind of the span to be created.\n * @param attributes Initial set of Attributes for the Span being constructed.\n * @param links Collection of links that will be associated with the Span to\n * be created. Typically useful for batch operations.\n * @returns a {@link SamplingResult}.\n */\n shouldSample(\n context: Context,\n traceId: string,\n spanName: string,\n spanKind: SpanKind,\n attributes: Attributes,\n links: Link[]\n ): SamplingResult;\n\n /** Returns the sampler name or short description with the configuration. */\n toString(): string;\n}\n"]}

View File

@@ -0,0 +1,99 @@
import type { Context, Exception, HrTime, Link, Span as APISpan, SpanOptions as APISpanOptions, Attributes, AttributeValue, SpanContext, SpanKind, SpanStatus, TimeInput } from '@opentelemetry/api';
import type { InstrumentationScope } from '@opentelemetry/core';
import type { Resource } from '@opentelemetry/resources';
import type { ReadableSpan } from './export/ReadableSpan';
import type { SpanProcessor } from './SpanProcessor';
import type { TimedEvent } from './TimedEvent';
import type { SpanLimits } from './types';
/**
* This type provides the properties of @link{ReadableSpan} at the same time
* of the Span API
*/
export type Span = APISpan & ReadableSpan;
type SpanOptions = Omit<APISpanOptions, 'root'> & {
resource: Resource;
scope: InstrumentationScope;
context: Context;
spanContext: SpanContext;
name: string;
kind: SpanKind;
parentSpanContext?: SpanContext;
spanLimits: SpanLimits;
spanProcessor: SpanProcessor;
recordEndMetrics?: () => void;
};
/**
* This class represents a span.
*/
export declare class SpanImpl implements Span {
private readonly _spanContext;
readonly kind: SpanKind;
readonly parentSpanContext?: SpanContext;
readonly attributes: Attributes;
readonly links: Link[];
readonly events: TimedEvent[];
readonly startTime: HrTime;
readonly resource: Resource;
readonly instrumentationScope: InstrumentationScope;
private _droppedAttributesCount;
private _droppedEventsCount;
private _droppedLinksCount;
private _attributesCount;
name: string;
status: SpanStatus;
endTime: HrTime;
private _ended;
private _duration;
private readonly _spanProcessor;
private readonly _spanLimits;
private readonly _attributeValueLengthLimit;
private readonly _recordEndMetrics?;
private readonly _performanceStartTime;
private readonly _performanceOffset;
private readonly _startTimeProvided;
/**
* Constructs a new SpanImpl instance.
*/
constructor(opts: SpanOptions);
spanContext(): SpanContext;
setAttribute(key: string, value?: AttributeValue): this;
setAttributes(attributes: Attributes): this;
/**
*
* @param name Span Name
* @param [attributesOrStartTime] Span attributes or start time
* if type is {@type TimeInput} and 3rd param is undefined
* @param [timeStamp] Specified time stamp for the event
*/
addEvent(name: string, attributesOrStartTime?: Attributes | TimeInput, timeStamp?: TimeInput): this;
addLink(link: Link): this;
addLinks(links: Link[]): this;
setStatus(status: SpanStatus): this;
updateName(name: string): this;
end(endTime?: TimeInput): void;
private _getTime;
isRecording(): boolean;
recordException(exception: Exception, time?: TimeInput): void;
get duration(): HrTime;
get ended(): boolean;
get droppedAttributesCount(): number;
get droppedEventsCount(): number;
get droppedLinksCount(): number;
private _isSpanEnded;
private _truncateToLimitUtil;
/**
* If the given attribute value is of type string and has more characters than given {@code attributeValueLengthLimit} then
* return string with truncated to {@code attributeValueLengthLimit} characters
*
* If the given attribute value is array of strings then
* return new array of strings with each element truncated to {@code attributeValueLengthLimit} characters
*
* Otherwise return same Attribute {@code value}
*
* @param value Attribute value
* @returns truncated attribute value if required, otherwise same value
*/
private _truncateToSize;
}
export {};
//# sourceMappingURL=Span.d.ts.map

View File

@@ -0,0 +1,384 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { diag, SpanStatusCode } from '@opentelemetry/api';
import { addHrTimes, millisToHrTime, hrTime, hrTimeDuration, isAttributeValue, isTimeInput, isTimeInputHrTime, otperformance, sanitizeAttributes, } from '@opentelemetry/core';
import { ATTR_EXCEPTION_MESSAGE, ATTR_EXCEPTION_STACKTRACE, ATTR_EXCEPTION_TYPE, } from '@opentelemetry/semantic-conventions';
import { ExceptionEventName } from './enums';
/**
* This class represents a span.
*/
export class SpanImpl {
// Below properties are included to implement ReadableSpan for export
// purposes but are not intended to be written-to directly.
_spanContext;
kind;
parentSpanContext;
attributes = {};
links = [];
events = [];
startTime;
resource;
instrumentationScope;
_droppedAttributesCount = 0;
_droppedEventsCount = 0;
_droppedLinksCount = 0;
_attributesCount = 0;
name;
status = {
code: SpanStatusCode.UNSET,
};
endTime = [0, 0];
_ended = false;
_duration = [-1, -1];
_spanProcessor;
_spanLimits;
_attributeValueLengthLimit;
_recordEndMetrics;
_performanceStartTime;
_performanceOffset;
_startTimeProvided;
/**
* Constructs a new SpanImpl instance.
*/
constructor(opts) {
const now = Date.now();
this._spanContext = opts.spanContext;
this._performanceStartTime = otperformance.now();
this._performanceOffset =
now - (this._performanceStartTime + otperformance.timeOrigin);
this._startTimeProvided = opts.startTime != null;
this._spanLimits = opts.spanLimits;
this._attributeValueLengthLimit =
this._spanLimits.attributeValueLengthLimit ?? 0;
this._spanProcessor = opts.spanProcessor;
this.name = opts.name;
this.parentSpanContext = opts.parentSpanContext;
this.kind = opts.kind;
if (opts.links) {
for (const link of opts.links) {
this.addLink(link);
}
}
this.startTime = this._getTime(opts.startTime ?? now);
this.resource = opts.resource;
this.instrumentationScope = opts.scope;
this._recordEndMetrics = opts.recordEndMetrics;
if (opts.attributes != null) {
this.setAttributes(opts.attributes);
}
this._spanProcessor.onStart(this, opts.context);
}
spanContext() {
return this._spanContext;
}
setAttribute(key, value) {
if (value == null || this._isSpanEnded())
return this;
if (key.length === 0) {
diag.warn(`Invalid attribute key: ${key}`);
return this;
}
if (!isAttributeValue(value)) {
diag.warn(`Invalid attribute value set for key: ${key}`);
return this;
}
const { attributeCountLimit } = this._spanLimits;
const isNewKey = !Object.prototype.hasOwnProperty.call(this.attributes, key);
if (attributeCountLimit !== undefined &&
this._attributesCount >= attributeCountLimit &&
isNewKey) {
this._droppedAttributesCount++;
return this;
}
this.attributes[key] = this._truncateToSize(value);
if (isNewKey) {
this._attributesCount++;
}
return this;
}
setAttributes(attributes) {
for (const key in attributes) {
if (Object.prototype.hasOwnProperty.call(attributes, key)) {
this.setAttribute(key, attributes[key]);
}
}
return this;
}
/**
*
* @param name Span Name
* @param [attributesOrStartTime] Span attributes or start time
* if type is {@type TimeInput} and 3rd param is undefined
* @param [timeStamp] Specified time stamp for the event
*/
addEvent(name, attributesOrStartTime, timeStamp) {
if (this._isSpanEnded())
return this;
const { eventCountLimit } = this._spanLimits;
if (eventCountLimit === 0) {
diag.warn('No events allowed.');
this._droppedEventsCount++;
return this;
}
if (eventCountLimit !== undefined &&
this.events.length >= eventCountLimit) {
if (this._droppedEventsCount === 0) {
diag.debug('Dropping extra events.');
}
this.events.shift();
this._droppedEventsCount++;
}
if (isTimeInput(attributesOrStartTime)) {
if (!isTimeInput(timeStamp)) {
timeStamp = attributesOrStartTime;
}
attributesOrStartTime = undefined;
}
const sanitized = sanitizeAttributes(attributesOrStartTime);
const { attributePerEventCountLimit } = this._spanLimits;
const attributes = {};
let droppedAttributesCount = 0;
let eventAttributesCount = 0;
for (const attr in sanitized) {
if (!Object.prototype.hasOwnProperty.call(sanitized, attr)) {
continue;
}
const attrVal = sanitized[attr];
if (attributePerEventCountLimit !== undefined &&
eventAttributesCount >= attributePerEventCountLimit) {
droppedAttributesCount++;
continue;
}
attributes[attr] = this._truncateToSize(attrVal);
eventAttributesCount++;
}
this.events.push({
name,
attributes,
time: this._getTime(timeStamp),
droppedAttributesCount,
});
return this;
}
addLink(link) {
if (this._isSpanEnded())
return this;
const { linkCountLimit } = this._spanLimits;
if (linkCountLimit === 0) {
this._droppedLinksCount++;
return this;
}
if (linkCountLimit !== undefined && this.links.length >= linkCountLimit) {
if (this._droppedLinksCount === 0) {
diag.debug('Dropping extra links.');
}
this.links.shift();
this._droppedLinksCount++;
}
const { attributePerLinkCountLimit } = this._spanLimits;
const sanitized = sanitizeAttributes(link.attributes);
const attributes = {};
let droppedAttributesCount = 0;
let linkAttributesCount = 0;
for (const attr in sanitized) {
if (!Object.prototype.hasOwnProperty.call(sanitized, attr)) {
continue;
}
const attrVal = sanitized[attr];
if (attributePerLinkCountLimit !== undefined &&
linkAttributesCount >= attributePerLinkCountLimit) {
droppedAttributesCount++;
continue;
}
attributes[attr] = this._truncateToSize(attrVal);
linkAttributesCount++;
}
const processedLink = { context: link.context };
if (linkAttributesCount > 0) {
processedLink.attributes = attributes;
}
if (droppedAttributesCount > 0) {
processedLink.droppedAttributesCount = droppedAttributesCount;
}
this.links.push(processedLink);
return this;
}
addLinks(links) {
for (const link of links) {
this.addLink(link);
}
return this;
}
setStatus(status) {
if (this._isSpanEnded())
return this;
if (status.code === SpanStatusCode.UNSET)
return this;
if (this.status.code === SpanStatusCode.OK)
return this;
const newStatus = { code: status.code };
// When using try-catch, the caught "error" is of type `any`. When then assigning `any` to `status.message`,
// TypeScript will not error. While this can happen during use of any API, it is more common on Span#setStatus()
// as it's likely used in a catch-block. Therefore, we validate if `status.message` is actually a string, null, or
// undefined to avoid an incorrect type causing issues downstream.
if (status.code === SpanStatusCode.ERROR) {
if (typeof status.message === 'string') {
newStatus.message = status.message;
}
else if (status.message != null) {
diag.warn(`Dropping invalid status.message of type '${typeof status.message}', expected 'string'`);
}
}
this.status = newStatus;
return this;
}
updateName(name) {
if (this._isSpanEnded())
return this;
this.name = name;
return this;
}
end(endTime) {
if (this._isSpanEnded()) {
diag.error(`${this.name} ${this._spanContext.traceId}-${this._spanContext.spanId} - You can only call end() on a span once.`);
return;
}
this.endTime = this._getTime(endTime);
this._duration = hrTimeDuration(this.startTime, this.endTime);
if (this._duration[0] < 0) {
diag.warn('Inconsistent start and end time, startTime > endTime. Setting span duration to 0ms.', this.startTime, this.endTime);
this.endTime = this.startTime.slice();
this._duration = [0, 0];
}
if (this._droppedEventsCount > 0) {
diag.warn(`Dropped ${this._droppedEventsCount} events because eventCountLimit reached`);
}
if (this._droppedLinksCount > 0) {
diag.warn(`Dropped ${this._droppedLinksCount} links because linkCountLimit reached`);
}
if (this._spanProcessor.onEnding) {
this._spanProcessor.onEnding(this);
}
this._recordEndMetrics?.();
this._ended = true;
this._spanProcessor.onEnd(this);
}
_getTime(inp) {
if (typeof inp === 'number' && inp <= otperformance.now()) {
// must be a performance timestamp
// apply correction and convert to hrtime
return hrTime(inp + this._performanceOffset);
}
if (typeof inp === 'number') {
return millisToHrTime(inp);
}
if (inp instanceof Date) {
return millisToHrTime(inp.getTime());
}
if (isTimeInputHrTime(inp)) {
return inp;
}
if (this._startTimeProvided) {
// if user provided a time for the start manually
// we can't use duration to calculate event/end times
return millisToHrTime(Date.now());
}
const msDuration = otperformance.now() - this._performanceStartTime;
return addHrTimes(this.startTime, millisToHrTime(msDuration));
}
isRecording() {
return this._ended === false;
}
recordException(exception, time) {
const attributes = {};
if (typeof exception === 'string') {
attributes[ATTR_EXCEPTION_MESSAGE] = exception;
}
else if (exception) {
if (exception.code) {
attributes[ATTR_EXCEPTION_TYPE] = exception.code.toString();
}
else if (exception.name) {
attributes[ATTR_EXCEPTION_TYPE] = exception.name;
}
if (exception.message) {
attributes[ATTR_EXCEPTION_MESSAGE] = exception.message;
}
if (exception.stack) {
attributes[ATTR_EXCEPTION_STACKTRACE] = exception.stack;
}
}
// these are minimum requirements from spec
if (attributes[ATTR_EXCEPTION_TYPE] || attributes[ATTR_EXCEPTION_MESSAGE]) {
this.addEvent(ExceptionEventName, attributes, time);
}
else {
diag.warn(`Failed to record an exception ${exception}`);
}
}
get duration() {
return this._duration;
}
get ended() {
return this._ended;
}
get droppedAttributesCount() {
return this._droppedAttributesCount;
}
get droppedEventsCount() {
return this._droppedEventsCount;
}
get droppedLinksCount() {
return this._droppedLinksCount;
}
_isSpanEnded() {
if (this._ended) {
const error = new Error(`Operation attempted on ended Span {traceId: ${this._spanContext.traceId}, spanId: ${this._spanContext.spanId}}`);
diag.warn(`Cannot execute the operation on ended Span {traceId: ${this._spanContext.traceId}, spanId: ${this._spanContext.spanId}}`, error);
}
return this._ended;
}
// Utility function to truncate given value within size
// for value type of string, will truncate to given limit
// for type of non-string, will return same value
_truncateToLimitUtil(value, limit) {
if (value.length <= limit) {
return value;
}
return value.substring(0, limit);
}
/**
* If the given attribute value is of type string and has more characters than given {@code attributeValueLengthLimit} then
* return string with truncated to {@code attributeValueLengthLimit} characters
*
* If the given attribute value is array of strings then
* return new array of strings with each element truncated to {@code attributeValueLengthLimit} characters
*
* Otherwise return same Attribute {@code value}
*
* @param value Attribute value
* @returns truncated attribute value if required, otherwise same value
*/
_truncateToSize(value) {
const limit = this._attributeValueLengthLimit;
// Check limit
if (limit <= 0) {
// Negative values are invalid, so do not truncate
diag.warn(`Attribute value limit must be positive, got ${limit}`);
return value;
}
// String
if (typeof value === 'string') {
return this._truncateToLimitUtil(value, limit);
}
// Array of strings
if (Array.isArray(value)) {
return value.map(val => typeof val === 'string' ? this._truncateToLimitUtil(val, limit) : val);
}
// Other types, no need to apply value length limit
return value;
}
}
//# sourceMappingURL=Span.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
import type { Context } from '@opentelemetry/api';
import type { ReadableSpan } from './export/ReadableSpan';
import type { Span } from './Span';
/**
* SpanProcessor is the interface Tracer SDK uses to allow synchronous hooks
* for when a {@link Span} is started or when a {@link Span} is ended.
*/
export interface SpanProcessor {
/**
* Forces to export all finished spans
*/
forceFlush(): Promise<void>;
/**
* Called when a {@link Span} is started, if the `span.isRecording()`
* returns true.
* @param span the Span that just started.
*/
onStart(span: Span, parentContext: Context): void;
/**
* Called when a {@link Span} is ending, if the `span.isRecording()`
* returns true.
* @param span the Span that is ending.
*
* @experimental This method is experimental and may break in minor versions of this package
*/
onEnding?(span: Span): void;
/**
* Called when a {@link ReadableSpan} is ended, if the `span.isRecording()`
* returns true.
* @param span the Span that just ended.
*/
onEnd(span: ReadableSpan): void;
/**
* Shuts down the processor. Called when SDK is shut down. This is an
* opportunity for processor to do any cleanup required.
*/
shutdown(): Promise<void>;
}
//# sourceMappingURL=SpanProcessor.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=SpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SpanProcessor.js","sourceRoot":"","sources":["../../src/SpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Context } from '@opentelemetry/api';\nimport type { ReadableSpan } from './export/ReadableSpan';\nimport type { Span } from './Span';\n\n/**\n * SpanProcessor is the interface Tracer SDK uses to allow synchronous hooks\n * for when a {@link Span} is started or when a {@link Span} is ended.\n */\nexport interface SpanProcessor {\n /**\n * Forces to export all finished spans\n */\n forceFlush(): Promise<void>;\n\n /**\n * Called when a {@link Span} is started, if the `span.isRecording()`\n * returns true.\n * @param span the Span that just started.\n */\n onStart(span: Span, parentContext: Context): void;\n\n /**\n * Called when a {@link Span} is ending, if the `span.isRecording()`\n * returns true.\n * @param span the Span that is ending.\n *\n * @experimental This method is experimental and may break in minor versions of this package\n */\n onEnding?(span: Span): void;\n\n /**\n * Called when a {@link ReadableSpan} is ended, if the `span.isRecording()`\n * returns true.\n * @param span the Span that just ended.\n */\n onEnd(span: ReadableSpan): void;\n\n /**\n * Shuts down the processor. Called when SDK is shut down. This is an\n * opportunity for processor to do any cleanup required.\n */\n shutdown(): Promise<void>;\n}\n"]}

View File

@@ -0,0 +1,15 @@
import type { HrTime, Attributes } from '@opentelemetry/api';
/**
* Represents a timed event.
* A timed event is an event with a timestamp.
*/
export interface TimedEvent {
time: HrTime;
/** The name of the event. */
name: string;
/** The attributes of the event. */
attributes?: Attributes;
/** Count of attributes of the event that were dropped due to collection limits */
droppedAttributesCount?: number;
}
//# sourceMappingURL=TimedEvent.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=TimedEvent.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TimedEvent.js","sourceRoot":"","sources":["../../src/TimedEvent.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HrTime, Attributes } from '@opentelemetry/api';\n\n/**\n * Represents a timed event.\n * A timed event is an event with a timestamp.\n */\nexport interface TimedEvent {\n time: HrTime;\n /** The name of the event. */\n name: string;\n /** The attributes of the event. */\n attributes?: Attributes;\n /** Count of attributes of the event that were dropped due to collection limits */\n droppedAttributesCount?: number;\n}\n"]}

View File

@@ -0,0 +1,78 @@
import * as api from '@opentelemetry/api';
import type { InstrumentationScope } from '@opentelemetry/core';
import type { GeneralLimits, SpanLimits, TracerConfig } from './types';
import type { SpanProcessor } from './SpanProcessor';
import type { Resource } from '@opentelemetry/resources';
/**
* This class represents a basic tracer.
*/
export declare class Tracer implements api.Tracer {
private readonly _sampler;
private readonly _generalLimits;
private readonly _spanLimits;
private readonly _idGenerator;
readonly instrumentationScope: InstrumentationScope;
private readonly _resource;
private readonly _spanProcessor;
private readonly _tracerMetrics;
/**
* Constructs a new Tracer instance.
*/
constructor(instrumentationScope: InstrumentationScope, config: TracerConfig, resource: Resource, spanProcessor: SpanProcessor);
/**
* Starts a new Span or returns the default NoopSpan based on the sampling
* decision.
*/
startSpan(name: string, options?: api.SpanOptions, context?: api.Context): api.Span;
/**
* Starts a new {@link Span} and calls the given function passing it the
* created span as first argument.
* Additionally the new span gets set in context and this context is activated
* for the duration of the function call.
*
* @param name The name of the span
* @param [options] SpanOptions used for span creation
* @param [context] Context to use to extract parent
* @param fn function called in the context of the span and receives the newly created span as an argument
* @returns return value of fn
* @example
* const something = tracer.startActiveSpan('op', span => {
* try {
* do some work
* span.setStatus({code: SpanStatusCode.OK});
* return something;
* } catch (err) {
* span.setStatus({
* code: SpanStatusCode.ERROR,
* message: err.message,
* });
* throw err;
* } finally {
* span.end();
* }
* });
* @example
* const span = tracer.startActiveSpan('op', span => {
* try {
* do some work
* return span;
* } catch (err) {
* span.setStatus({
* code: SpanStatusCode.ERROR,
* message: err.message,
* });
* throw err;
* }
* });
* do some more work
* span.end();
*/
startActiveSpan<F extends (span: api.Span) => ReturnType<F>>(name: string, fn: F): ReturnType<F>;
startActiveSpan<F extends (span: api.Span) => ReturnType<F>>(name: string, opts: api.SpanOptions, fn: F): ReturnType<F>;
startActiveSpan<F extends (span: api.Span) => ReturnType<F>>(name: string, opts: api.SpanOptions, ctx: api.Context, fn: F): ReturnType<F>;
/** Returns the active {@link GeneralLimits}. */
getGeneralLimits(): GeneralLimits;
/** Returns the active {@link SpanLimits}. */
getSpanLimits(): SpanLimits;
}
//# sourceMappingURL=Tracer.d.ts.map

View File

@@ -0,0 +1,146 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import * as api from '@opentelemetry/api';
import { sanitizeAttributes, isTracingSuppressed } from '@opentelemetry/core';
import { SpanImpl } from './Span';
import { mergeConfig } from './utility';
import { RandomIdGenerator } from './platform';
import { TracerMetrics } from './TracerMetrics';
import { VERSION } from './version';
/**
* This class represents a basic tracer.
*/
export class Tracer {
_sampler;
_generalLimits;
_spanLimits;
_idGenerator;
instrumentationScope;
_resource;
_spanProcessor;
_tracerMetrics;
/**
* Constructs a new Tracer instance.
*/
constructor(instrumentationScope, config, resource, spanProcessor) {
const localConfig = mergeConfig(config);
this._sampler = localConfig.sampler;
this._generalLimits = localConfig.generalLimits;
this._spanLimits = localConfig.spanLimits;
this._idGenerator = config.idGenerator || new RandomIdGenerator();
this._resource = resource;
this._spanProcessor = spanProcessor;
this.instrumentationScope = instrumentationScope;
const meter = localConfig.meterProvider
? localConfig.meterProvider.getMeter('@opentelemetry/sdk-trace', VERSION)
: api.createNoopMeter();
this._tracerMetrics = new TracerMetrics(meter);
}
/**
* Starts a new Span or returns the default NoopSpan based on the sampling
* decision.
*/
startSpan(name, options = {}, context = api.context.active()) {
// remove span from context in case a root span is requested via options
if (options.root) {
context = api.trace.deleteSpan(context);
}
const parentSpan = api.trace.getSpan(context);
if (isTracingSuppressed(context)) {
api.diag.debug('Instrumentation suppressed, returning Noop Span');
const nonRecordingSpan = api.trace.wrapSpanContext(api.INVALID_SPAN_CONTEXT);
return nonRecordingSpan;
}
const parentSpanContext = parentSpan?.spanContext();
const spanId = this._idGenerator.generateSpanId();
let validParentSpanContext;
let traceId;
let traceState;
if (!parentSpanContext ||
!api.trace.isSpanContextValid(parentSpanContext)) {
// New root span.
traceId = this._idGenerator.generateTraceId();
}
else {
// New child span.
traceId = parentSpanContext.traceId;
traceState = parentSpanContext.traceState;
validParentSpanContext = parentSpanContext;
}
const spanKind = options.kind ?? api.SpanKind.INTERNAL;
const links = (options.links ?? []).map(link => {
return {
context: link.context,
attributes: sanitizeAttributes(link.attributes),
};
});
const attributes = sanitizeAttributes(options.attributes);
// make sampling decision
const samplingResult = this._sampler.shouldSample(context, traceId, name, spanKind, attributes, links);
const recordEndMetrics = this._tracerMetrics.startSpan(parentSpanContext, samplingResult.decision);
traceState = samplingResult.traceState ?? traceState;
const traceFlags = samplingResult.decision === api.SamplingDecision.RECORD_AND_SAMPLED
? api.TraceFlags.SAMPLED
: api.TraceFlags.NONE;
const spanContext = { traceId, spanId, traceFlags, traceState };
if (samplingResult.decision === api.SamplingDecision.NOT_RECORD) {
api.diag.debug('Recording is off, propagating context in a non-recording span');
const nonRecordingSpan = api.trace.wrapSpanContext(spanContext);
return nonRecordingSpan;
}
// Set initial span attributes. The attributes object may have been mutated
// by the sampler, so we sanitize the merged attributes before setting them.
const initAttributes = sanitizeAttributes(Object.assign(attributes, samplingResult.attributes));
const span = new SpanImpl({
resource: this._resource,
scope: this.instrumentationScope,
context,
spanContext,
name,
kind: spanKind,
links,
parentSpanContext: validParentSpanContext,
attributes: initAttributes,
startTime: options.startTime,
spanProcessor: this._spanProcessor,
spanLimits: this._spanLimits,
recordEndMetrics,
});
return span;
}
startActiveSpan(name, arg2, arg3, arg4) {
let opts;
let ctx;
let fn;
if (arguments.length < 2) {
return;
}
else if (arguments.length === 2) {
fn = arg2;
}
else if (arguments.length === 3) {
opts = arg2;
fn = arg3;
}
else {
opts = arg2;
ctx = arg3;
fn = arg4;
}
const parentContext = ctx ?? api.context.active();
const span = this.startSpan(name, opts, parentContext);
const contextWithSpanSet = api.trace.setSpan(parentContext, span);
return api.context.with(contextWithSpanSet, fn, undefined, span);
}
/** Returns the active {@link GeneralLimits}. */
getGeneralLimits() {
return this._generalLimits;
}
/** Returns the active {@link SpanLimits}. */
getSpanLimits() {
return this._spanLimits;
}
}
//# sourceMappingURL=Tracer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
import type { Meter, SpanContext } from '@opentelemetry/api';
import { SamplingDecision } from './Sampler';
/**
* Generates `otel.sdk.span.*` metrics.
* https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/#span-metrics
*/
export declare class TracerMetrics {
private readonly startedSpans;
private readonly liveSpans;
constructor(meter: Meter);
startSpan(parentSpanCtx: SpanContext | undefined, samplingDecision: SamplingDecision): () => void;
}
//# sourceMappingURL=TracerMetrics.d.ts.map

View File

@@ -0,0 +1,57 @@
import { SamplingDecision } from './Sampler';
import { ATTR_OTEL_SPAN_PARENT_ORIGIN, ATTR_OTEL_SPAN_SAMPLING_RESULT, METRIC_OTEL_SDK_SPAN_LIVE, METRIC_OTEL_SDK_SPAN_STARTED, } from './semconv';
/**
* Generates `otel.sdk.span.*` metrics.
* https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/#span-metrics
*/
export class TracerMetrics {
startedSpans;
liveSpans;
constructor(meter) {
this.startedSpans = meter.createCounter(METRIC_OTEL_SDK_SPAN_STARTED, {
unit: '{span}',
description: 'The number of created spans.',
});
this.liveSpans = meter.createUpDownCounter(METRIC_OTEL_SDK_SPAN_LIVE, {
unit: '{span}',
description: 'The number of currently live spans.',
});
}
startSpan(parentSpanCtx, samplingDecision) {
const samplingDecisionStr = samplingDecisionToString(samplingDecision);
this.startedSpans.add(1, {
[ATTR_OTEL_SPAN_PARENT_ORIGIN]: parentOrigin(parentSpanCtx),
[ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr,
});
if (samplingDecision === SamplingDecision.NOT_RECORD) {
return () => { };
}
const liveSpanAttributes = {
[ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr,
};
this.liveSpans.add(1, liveSpanAttributes);
return () => {
this.liveSpans.add(-1, liveSpanAttributes);
};
}
}
function parentOrigin(parentSpanContext) {
if (!parentSpanContext) {
return 'none';
}
if (parentSpanContext.isRemote) {
return 'remote';
}
return 'local';
}
function samplingDecisionToString(decision) {
switch (decision) {
case SamplingDecision.RECORD_AND_SAMPLED:
return 'RECORD_AND_SAMPLE';
case SamplingDecision.RECORD:
return 'RECORD_ONLY';
case SamplingDecision.NOT_RECORD:
return 'DROP';
}
}
//# sourceMappingURL=TracerMetrics.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TracerMetrics.js","sourceRoot":"","sources":["../../src/TracerMetrics.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,EAC9B,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,MAAM,OAAO,aAAa;IACP,YAAY,CAAU;IACtB,SAAS,CAAgB;IAE1C,YAAY,KAAY;QACtB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,4BAA4B,EAAE;YACpE,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,8BAA8B;SAC5C,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,mBAAmB,CAAC,yBAAyB,EAAE;YACpE,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,qCAAqC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CACP,aAAsC,EACtC,gBAAkC;QAElC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACvE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE;YACvB,CAAC,4BAA4B,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC;YAC3D,CAAC,8BAA8B,CAAC,EAAE,mBAAmB;SACtD,CAAC,CAAC;QAEH,IAAI,gBAAgB,KAAK,gBAAgB,CAAC,UAAU,EAAE;YACpD,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;SACjB;QAED,MAAM,kBAAkB,GAAG;YACzB,CAAC,8BAA8B,CAAC,EAAE,mBAAmB;SACtD,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7C,CAAC,CAAC;IACJ,CAAC;CACF;AAED,SAAS,YAAY,CAAC,iBAA0C;IAC9D,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO,MAAM,CAAC;KACf;IACD,IAAI,iBAAiB,CAAC,QAAQ,EAAE;QAC9B,OAAO,QAAQ,CAAC;KACjB;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,wBAAwB,CAAC,QAA0B;IAC1D,QAAQ,QAAQ,EAAE;QAChB,KAAK,gBAAgB,CAAC,kBAAkB;YACtC,OAAO,mBAAmB,CAAC;QAC7B,KAAK,gBAAgB,CAAC,MAAM;YAC1B,OAAO,aAAa,CAAC;QACvB,KAAK,gBAAgB,CAAC,UAAU;YAC9B,OAAO,MAAM,CAAC;KACjB;AACH,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type {\n Counter,\n Meter,\n SpanContext,\n UpDownCounter,\n} from '@opentelemetry/api';\nimport { SamplingDecision } from './Sampler';\nimport {\n ATTR_OTEL_SPAN_PARENT_ORIGIN,\n ATTR_OTEL_SPAN_SAMPLING_RESULT,\n METRIC_OTEL_SDK_SPAN_LIVE,\n METRIC_OTEL_SDK_SPAN_STARTED,\n} from './semconv';\n\n/**\n * Generates `otel.sdk.span.*` metrics.\n * https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/#span-metrics\n */\nexport class TracerMetrics {\n private readonly startedSpans: Counter;\n private readonly liveSpans: UpDownCounter;\n\n constructor(meter: Meter) {\n this.startedSpans = meter.createCounter(METRIC_OTEL_SDK_SPAN_STARTED, {\n unit: '{span}',\n description: 'The number of created spans.',\n });\n\n this.liveSpans = meter.createUpDownCounter(METRIC_OTEL_SDK_SPAN_LIVE, {\n unit: '{span}',\n description: 'The number of currently live spans.',\n });\n }\n\n startSpan(\n parentSpanCtx: SpanContext | undefined,\n samplingDecision: SamplingDecision\n ): () => void {\n const samplingDecisionStr = samplingDecisionToString(samplingDecision);\n this.startedSpans.add(1, {\n [ATTR_OTEL_SPAN_PARENT_ORIGIN]: parentOrigin(parentSpanCtx),\n [ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr,\n });\n\n if (samplingDecision === SamplingDecision.NOT_RECORD) {\n return () => {};\n }\n\n const liveSpanAttributes = {\n [ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr,\n };\n this.liveSpans.add(1, liveSpanAttributes);\n return () => {\n this.liveSpans.add(-1, liveSpanAttributes);\n };\n }\n}\n\nfunction parentOrigin(parentSpanContext: SpanContext | undefined): string {\n if (!parentSpanContext) {\n return 'none';\n }\n if (parentSpanContext.isRemote) {\n return 'remote';\n }\n return 'local';\n}\n\nfunction samplingDecisionToString(decision: SamplingDecision): string {\n switch (decision) {\n case SamplingDecision.RECORD_AND_SAMPLED:\n return 'RECORD_AND_SAMPLE';\n case SamplingDecision.RECORD:\n return 'RECORD_ONLY';\n case SamplingDecision.NOT_RECORD:\n return 'DROP';\n }\n}\n"]}

View File

@@ -0,0 +1,28 @@
import type { Sampler } from './Sampler';
/**
* Load default configuration. For fields with primitive values, any user-provided
* value will override the corresponding default value. For fields with
* non-primitive values (like `spanLimits`), the user-provided value will be
* used to extend the default value.
*/
export declare function loadDefaultConfig(): {
sampler: Sampler;
forceFlushTimeoutMillis: number;
generalLimits: {
attributeValueLengthLimit: number;
attributeCountLimit: number;
};
spanLimits: {
attributeValueLengthLimit: number;
attributeCountLimit: number;
linkCountLimit: number;
eventCountLimit: number;
attributePerEventCountLimit: number;
attributePerLinkCountLimit: number;
};
};
/**
* Based on environment, builds a sampler, complies with specification.
*/
export declare function buildSamplerFromEnv(): Sampler;
//# sourceMappingURL=config.d.ts.map

View File

@@ -0,0 +1,91 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { diag } from '@opentelemetry/api';
import { getNumberFromEnv, getStringFromEnv } from '@opentelemetry/core';
import { AlwaysOffSampler } from './sampler/AlwaysOffSampler';
import { AlwaysOnSampler } from './sampler/AlwaysOnSampler';
import { ParentBasedSampler } from './sampler/ParentBasedSampler';
import { TraceIdRatioBasedSampler } from './sampler/TraceIdRatioBasedSampler';
var TracesSamplerValues;
(function (TracesSamplerValues) {
TracesSamplerValues["AlwaysOff"] = "always_off";
TracesSamplerValues["AlwaysOn"] = "always_on";
TracesSamplerValues["ParentBasedAlwaysOff"] = "parentbased_always_off";
TracesSamplerValues["ParentBasedAlwaysOn"] = "parentbased_always_on";
TracesSamplerValues["ParentBasedTraceIdRatio"] = "parentbased_traceidratio";
TracesSamplerValues["TraceIdRatio"] = "traceidratio";
})(TracesSamplerValues || (TracesSamplerValues = {}));
const DEFAULT_RATIO = 1;
/**
* Load default configuration. For fields with primitive values, any user-provided
* value will override the corresponding default value. For fields with
* non-primitive values (like `spanLimits`), the user-provided value will be
* used to extend the default value.
*/
// object needs to be wrapped in this function and called when needed otherwise
// envs are parsed before tests are ran - causes tests using these envs to fail
export function loadDefaultConfig() {
return {
sampler: buildSamplerFromEnv(),
forceFlushTimeoutMillis: 30000,
generalLimits: {
attributeValueLengthLimit: getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ?? Infinity,
attributeCountLimit: getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT') ?? 128,
},
spanLimits: {
attributeValueLengthLimit: getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT') ?? Infinity,
attributeCountLimit: getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT') ?? 128,
linkCountLimit: getNumberFromEnv('OTEL_SPAN_LINK_COUNT_LIMIT') ?? 128,
eventCountLimit: getNumberFromEnv('OTEL_SPAN_EVENT_COUNT_LIMIT') ?? 128,
attributePerEventCountLimit: getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_PER_EVENT_COUNT_LIMIT') ?? 128,
attributePerLinkCountLimit: getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_PER_LINK_COUNT_LIMIT') ?? 128,
},
};
}
/**
* Based on environment, builds a sampler, complies with specification.
*/
export function buildSamplerFromEnv() {
const sampler = getStringFromEnv('OTEL_TRACES_SAMPLER') ??
TracesSamplerValues.ParentBasedAlwaysOn;
switch (sampler) {
case TracesSamplerValues.AlwaysOn:
return new AlwaysOnSampler();
case TracesSamplerValues.AlwaysOff:
return new AlwaysOffSampler();
case TracesSamplerValues.ParentBasedAlwaysOn:
return new ParentBasedSampler({
root: new AlwaysOnSampler(),
});
case TracesSamplerValues.ParentBasedAlwaysOff:
return new ParentBasedSampler({
root: new AlwaysOffSampler(),
});
case TracesSamplerValues.TraceIdRatio:
return new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv());
case TracesSamplerValues.ParentBasedTraceIdRatio:
return new ParentBasedSampler({
root: new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv()),
});
default:
diag.error(`OTEL_TRACES_SAMPLER value "${sampler}" invalid, defaulting to "${TracesSamplerValues.ParentBasedAlwaysOn}".`);
return new ParentBasedSampler({
root: new AlwaysOnSampler(),
});
}
}
function getSamplerProbabilityFromEnv() {
const probability = getNumberFromEnv('OTEL_TRACES_SAMPLER_ARG');
if (probability == null) {
diag.error(`OTEL_TRACES_SAMPLER_ARG is blank, defaulting to ${DEFAULT_RATIO}.`);
return DEFAULT_RATIO;
}
if (probability < 0 || probability > 1) {
diag.error(`OTEL_TRACES_SAMPLER_ARG=${probability} was given, but it is out of range ([0..1]), defaulting to ${DEFAULT_RATIO}.`);
return DEFAULT_RATIO;
}
return probability;
}
//# sourceMappingURL=config.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
export declare const ExceptionEventName = "exception";
//# sourceMappingURL=enums.d.ts.map

View File

@@ -0,0 +1,7 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
// Event name definitions
export const ExceptionEventName = 'exception';
//# sourceMappingURL=enums.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"enums.js","sourceRoot":"","sources":["../../src/enums.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yBAAyB;AACzB,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Event name definitions\nexport const ExceptionEventName = 'exception';\n"]}

View File

@@ -0,0 +1,41 @@
import type { Context } from '@opentelemetry/api';
import type { Span } from '../Span';
import type { SpanProcessor } from '../SpanProcessor';
import type { BufferConfig } from '../types';
import type { ReadableSpan } from './ReadableSpan';
import type { SpanExporter } from './SpanExporter';
/**
* Implementation of the {@link SpanProcessor} that batches spans exported by
* the SDK then pushes them to the exporter pipeline.
*/
export declare abstract class BatchSpanProcessorBase<T extends BufferConfig> implements SpanProcessor {
private readonly _maxExportBatchSize;
private readonly _maxQueueSize;
private readonly _scheduledDelayMillis;
private readonly _exportTimeoutMillis;
private readonly _exporter;
private _isExporting;
private _finishedSpans;
private _timer;
private _shutdownOnce;
private _droppedSpansCount;
constructor(exporter: SpanExporter, config?: T);
forceFlush(): Promise<void>;
onStart(_span: Span, _parentContext: Context): void;
onEnd(span: ReadableSpan): void;
shutdown(): Promise<void>;
private _shutdown;
/** Add a span in the buffer. */
private _addToBuffer;
/**
* Send all spans to the exporter respecting the batch size limit
* This function is used only on forceFlush or shutdown,
* for all other cases _flush should be used
* */
private _flushAll;
private _flushOneBatch;
private _maybeStartTimer;
private _clearTimer;
protected abstract onShutdown(): void;
}
//# sourceMappingURL=BatchSpanProcessorBase.d.ts.map

View File

@@ -0,0 +1,208 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { context, diag, TraceFlags } from '@opentelemetry/api';
import { BindOnceFuture, ExportResultCode, getNumberFromEnv, globalErrorHandler, suppressTracing, } from '@opentelemetry/core';
/**
* Implementation of the {@link SpanProcessor} that batches spans exported by
* the SDK then pushes them to the exporter pipeline.
*/
export class BatchSpanProcessorBase {
_maxExportBatchSize;
_maxQueueSize;
_scheduledDelayMillis;
_exportTimeoutMillis;
_exporter;
_isExporting = false;
_finishedSpans = [];
_timer;
_shutdownOnce;
_droppedSpansCount = 0;
constructor(exporter, config) {
this._exporter = exporter;
this._maxExportBatchSize =
typeof config?.maxExportBatchSize === 'number'
? config.maxExportBatchSize
: (getNumberFromEnv('OTEL_BSP_MAX_EXPORT_BATCH_SIZE') ?? 512);
this._maxQueueSize =
typeof config?.maxQueueSize === 'number'
? config.maxQueueSize
: (getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE') ?? 2048);
this._scheduledDelayMillis =
typeof config?.scheduledDelayMillis === 'number'
? config.scheduledDelayMillis
: (getNumberFromEnv('OTEL_BSP_SCHEDULE_DELAY') ?? 5000);
this._exportTimeoutMillis =
typeof config?.exportTimeoutMillis === 'number'
? config.exportTimeoutMillis
: (getNumberFromEnv('OTEL_BSP_EXPORT_TIMEOUT') ?? 30000);
this._shutdownOnce = new BindOnceFuture(this._shutdown, this);
if (this._maxExportBatchSize > this._maxQueueSize) {
diag.warn('BatchSpanProcessor: maxExportBatchSize must be smaller or equal to maxQueueSize, setting maxExportBatchSize to match maxQueueSize');
this._maxExportBatchSize = this._maxQueueSize;
}
}
forceFlush() {
if (this._shutdownOnce.isCalled) {
return this._shutdownOnce.promise;
}
return this._flushAll();
}
// does nothing.
onStart(_span, _parentContext) { }
onEnd(span) {
if (this._shutdownOnce.isCalled) {
return;
}
if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
return;
}
this._addToBuffer(span);
}
shutdown() {
return this._shutdownOnce.call();
}
_shutdown() {
return Promise.resolve()
.then(() => {
return this.onShutdown();
})
.then(() => {
return this._flushAll();
})
.then(() => {
return this._exporter.shutdown();
});
}
/** Add a span in the buffer. */
_addToBuffer(span) {
if (this._finishedSpans.length >= this._maxQueueSize) {
// limit reached, drop span
if (this._droppedSpansCount === 0) {
diag.debug('maxQueueSize reached, dropping spans');
}
this._droppedSpansCount++;
return;
}
if (this._droppedSpansCount > 0) {
// some spans were dropped, log once with count of spans dropped
diag.warn(`Dropped ${this._droppedSpansCount} spans because maxQueueSize reached`);
this._droppedSpansCount = 0;
}
this._finishedSpans.push(span);
this._maybeStartTimer();
}
/**
* Send all spans to the exporter respecting the batch size limit
* This function is used only on forceFlush or shutdown,
* for all other cases _flush should be used
* */
_flushAll() {
return new Promise((resolve, reject) => {
const promises = [];
// calculate number of batches
const count = Math.ceil(this._finishedSpans.length / this._maxExportBatchSize);
for (let i = 0, j = count; i < j; i++) {
promises.push(this._flushOneBatch());
}
Promise.all(promises)
.then(() => {
resolve();
})
.catch(reject);
});
}
_flushOneBatch() {
this._clearTimer();
if (this._finishedSpans.length === 0) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
// don't wait anymore for export, this way the next batch can start
reject(new Error('Timeout'));
}, this._exportTimeoutMillis);
// prevent downstream exporter calls from generating spans
context.with(suppressTracing(context.active()), () => {
// Reset the finished spans buffer here because the next invocations of the _flush method
// could pass the same finished spans to the exporter if the buffer is cleared
// outside the execution of this callback.
let spans;
if (this._finishedSpans.length <= this._maxExportBatchSize) {
spans = this._finishedSpans;
this._finishedSpans = [];
}
else {
spans = this._finishedSpans.splice(0, this._maxExportBatchSize);
}
const doExport = () => this._exporter.export(spans, result => {
clearTimeout(timer);
if (result.code === ExportResultCode.SUCCESS) {
resolve();
}
else {
reject(result.error ??
new Error('BatchSpanProcessor: span export failed'));
}
});
let pendingResources = null;
for (let i = 0, len = spans.length; i < len; i++) {
const span = spans[i];
if (span.resource.asyncAttributesPending &&
span.resource.waitForAsyncAttributes) {
pendingResources ??= [];
pendingResources.push(span.resource.waitForAsyncAttributes());
}
}
// Avoid scheduling a promise to make the behavior more predictable and easier to test
if (pendingResources === null) {
doExport();
}
else {
Promise.all(pendingResources).then(doExport, err => {
globalErrorHandler(err);
reject(err);
});
}
});
});
}
_maybeStartTimer() {
if (this._isExporting)
return;
const flush = () => {
this._isExporting = true;
this._flushOneBatch()
.finally(() => {
this._isExporting = false;
if (this._finishedSpans.length > 0) {
this._clearTimer();
this._maybeStartTimer();
}
})
.catch(e => {
this._isExporting = false;
globalErrorHandler(e);
});
};
// we only wait if the queue doesn't have enough elements yet
if (this._finishedSpans.length >= this._maxExportBatchSize) {
return flush();
}
if (this._timer !== undefined)
return;
this._timer = setTimeout(() => flush(), this._scheduledDelayMillis);
// depending on runtime, this may be a 'number' or NodeJS.Timeout
if (typeof this._timer !== 'number') {
this._timer.unref();
}
}
_clearTimer() {
if (this._timer !== undefined) {
clearTimeout(this._timer);
this._timer = undefined;
}
}
}
//# sourceMappingURL=BatchSpanProcessorBase.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
import type { SpanExporter } from './SpanExporter';
import type { ReadableSpan } from './ReadableSpan';
import type { ExportResult } from '@opentelemetry/core';
/**
* This is implementation of {@link SpanExporter} that prints spans to the
* console. This class can be used for diagnostic purposes.
*
* NOTE: This {@link SpanExporter} is intended for diagnostics use only, output rendered to the console may change at any time.
*/
export declare class ConsoleSpanExporter implements SpanExporter {
/**
* Export spans.
* @param spans
* @param resultCallback
*/
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
/**
* Shutdown the exporter.
*/
shutdown(): Promise<void>;
/**
* Exports any pending spans in exporter
*/
forceFlush(): Promise<void>;
/**
* converts span info into more readable format
* @param span
*/
private _exportInfo;
/**
* Showing spans in console
* @param spans
* @param done
*/
private _sendSpans;
}
//# sourceMappingURL=ConsoleSpanExporter.d.ts.map

View File

@@ -0,0 +1,73 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { ExportResultCode, hrTimeToMicroseconds } from '@opentelemetry/core';
/**
* This is implementation of {@link SpanExporter} that prints spans to the
* console. This class can be used for diagnostic purposes.
*
* NOTE: This {@link SpanExporter} is intended for diagnostics use only, output rendered to the console may change at any time.
*/
/* eslint-disable no-console */
export class ConsoleSpanExporter {
/**
* Export spans.
* @param spans
* @param resultCallback
*/
export(spans, resultCallback) {
return this._sendSpans(spans, resultCallback);
}
/**
* Shutdown the exporter.
*/
shutdown() {
this._sendSpans([]);
return this.forceFlush();
}
/**
* Exports any pending spans in exporter
*/
forceFlush() {
return Promise.resolve();
}
/**
* converts span info into more readable format
* @param span
*/
_exportInfo(span) {
return {
resource: {
attributes: span.resource.attributes,
},
instrumentationScope: span.instrumentationScope,
traceId: span.spanContext().traceId,
parentSpanContext: span.parentSpanContext,
traceState: span.spanContext().traceState?.serialize(),
name: span.name,
id: span.spanContext().spanId,
kind: span.kind,
timestamp: hrTimeToMicroseconds(span.startTime),
duration: hrTimeToMicroseconds(span.duration),
attributes: span.attributes,
status: span.status,
events: span.events,
links: span.links,
};
}
/**
* Showing spans in console
* @param spans
* @param done
*/
_sendSpans(spans, done) {
for (const span of spans) {
console.dir(this._exportInfo(span), { depth: 3 });
}
if (done) {
return done({ code: ExportResultCode.SUCCESS });
}
}
}
//# sourceMappingURL=ConsoleSpanExporter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ConsoleSpanExporter.js","sourceRoot":"","sources":["../../../src/export/ConsoleSpanExporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE7E;;;;;GAKG;AAEH,+BAA+B;AAC/B,MAAM,OAAO,mBAAmB;IAC9B;;;;OAIG;IACH,MAAM,CACJ,KAAqB,EACrB,cAA8C;QAE9C,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,IAAkB;QACpC,OAAO;YACL,QAAQ,EAAE;gBACR,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;aACrC;YACD,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO;YACnC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE;YACtD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC;YAC/C,QAAQ,EAAE,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC7C,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,UAAU,CAChB,KAAqB,EACrB,IAAqC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;SACnD;QACD,IAAI,IAAI,EAAE;YACR,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;SACjD;IACH,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { SpanExporter } from './SpanExporter';\nimport type { ReadableSpan } from './ReadableSpan';\nimport type { ExportResult } from '@opentelemetry/core';\nimport { ExportResultCode, hrTimeToMicroseconds } from '@opentelemetry/core';\n\n/**\n * This is implementation of {@link SpanExporter} that prints spans to the\n * console. This class can be used for diagnostic purposes.\n *\n * NOTE: This {@link SpanExporter} is intended for diagnostics use only, output rendered to the console may change at any time.\n */\n\n/* eslint-disable no-console */\nexport class ConsoleSpanExporter implements SpanExporter {\n /**\n * Export spans.\n * @param spans\n * @param resultCallback\n */\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n return this._sendSpans(spans, resultCallback);\n }\n\n /**\n * Shutdown the exporter.\n */\n shutdown(): Promise<void> {\n this._sendSpans([]);\n return this.forceFlush();\n }\n\n /**\n * Exports any pending spans in exporter\n */\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * converts span info into more readable format\n * @param span\n */\n private _exportInfo(span: ReadableSpan) {\n return {\n resource: {\n attributes: span.resource.attributes,\n },\n instrumentationScope: span.instrumentationScope,\n traceId: span.spanContext().traceId,\n parentSpanContext: span.parentSpanContext,\n traceState: span.spanContext().traceState?.serialize(),\n name: span.name,\n id: span.spanContext().spanId,\n kind: span.kind,\n timestamp: hrTimeToMicroseconds(span.startTime),\n duration: hrTimeToMicroseconds(span.duration),\n attributes: span.attributes,\n status: span.status,\n events: span.events,\n links: span.links,\n };\n }\n\n /**\n * Showing spans in console\n * @param spans\n * @param done\n */\n private _sendSpans(\n spans: ReadableSpan[],\n done?: (result: ExportResult) => void\n ): void {\n for (const span of spans) {\n console.dir(this._exportInfo(span), { depth: 3 });\n }\n if (done) {\n return done({ code: ExportResultCode.SUCCESS });\n }\n }\n}\n"]}

View File

@@ -0,0 +1,25 @@
import type { SpanExporter } from './SpanExporter';
import type { ReadableSpan } from './ReadableSpan';
import type { ExportResult } from '@opentelemetry/core';
/**
* This class can be used for testing purposes. It stores the exported spans
* in a list in memory that can be retrieved using the `getFinishedSpans()`
* method.
*/
export declare class InMemorySpanExporter implements SpanExporter {
private _finishedSpans;
/**
* Indicates if the exporter has been "shutdown."
* When false, exported spans will not be stored in-memory.
*/
protected _stopped: boolean;
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
shutdown(): Promise<void>;
/**
* Exports any pending spans in the exporter
*/
forceFlush(): Promise<void>;
reset(): void;
getFinishedSpans(): ReadableSpan[];
}
//# sourceMappingURL=InMemorySpanExporter.d.ts.map

View File

@@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { ExportResultCode } from '@opentelemetry/core';
/**
* This class can be used for testing purposes. It stores the exported spans
* in a list in memory that can be retrieved using the `getFinishedSpans()`
* method.
*/
export class InMemorySpanExporter {
_finishedSpans = [];
/**
* Indicates if the exporter has been "shutdown."
* When false, exported spans will not be stored in-memory.
*/
_stopped = false;
export(spans, resultCallback) {
if (this._stopped)
return resultCallback({
code: ExportResultCode.FAILED,
error: new Error('Exporter has been stopped'),
});
this._finishedSpans.push(...spans);
setTimeout(() => resultCallback({ code: ExportResultCode.SUCCESS }), 0);
}
shutdown() {
this._stopped = true;
this._finishedSpans = [];
return this.forceFlush();
}
/**
* Exports any pending spans in the exporter
*/
forceFlush() {
return Promise.resolve();
}
reset() {
this._finishedSpans = [];
}
getFinishedSpans() {
return this._finishedSpans;
}
}
//# sourceMappingURL=InMemorySpanExporter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"InMemorySpanExporter.js","sourceRoot":"","sources":["../../../src/export/InMemorySpanExporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IACvB,cAAc,GAAmB,EAAE,CAAC;IAC5C;;;OAGG;IACO,QAAQ,GAAG,KAAK,CAAC;IAE3B,MAAM,CACJ,KAAqB,EACrB,cAA8C;QAE9C,IAAI,IAAI,CAAC,QAAQ;YACf,OAAO,cAAc,CAAC;gBACpB,IAAI,EAAE,gBAAgB,CAAC,MAAM;gBAC7B,KAAK,EAAE,IAAI,KAAK,CAAC,2BAA2B,CAAC;aAC9C,CAAC,CAAC;QACL,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAEnC,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { SpanExporter } from './SpanExporter';\nimport type { ReadableSpan } from './ReadableSpan';\nimport type { ExportResult } from '@opentelemetry/core';\nimport { ExportResultCode } from '@opentelemetry/core';\n\n/**\n * This class can be used for testing purposes. It stores the exported spans\n * in a list in memory that can be retrieved using the `getFinishedSpans()`\n * method.\n */\nexport class InMemorySpanExporter implements SpanExporter {\n private _finishedSpans: ReadableSpan[] = [];\n /**\n * Indicates if the exporter has been \"shutdown.\"\n * When false, exported spans will not be stored in-memory.\n */\n protected _stopped = false;\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n if (this._stopped)\n return resultCallback({\n code: ExportResultCode.FAILED,\n error: new Error('Exporter has been stopped'),\n });\n this._finishedSpans.push(...spans);\n\n setTimeout(() => resultCallback({ code: ExportResultCode.SUCCESS }), 0);\n }\n\n shutdown(): Promise<void> {\n this._stopped = true;\n this._finishedSpans = [];\n return this.forceFlush();\n }\n\n /**\n * Exports any pending spans in the exporter\n */\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n\n reset(): void {\n this._finishedSpans = [];\n }\n\n getFinishedSpans(): ReadableSpan[] {\n return this._finishedSpans;\n }\n}\n"]}

View File

@@ -0,0 +1,12 @@
import type { Context } from '@opentelemetry/api';
import type { ReadableSpan } from './ReadableSpan';
import type { Span } from '../Span';
import type { SpanProcessor } from '../SpanProcessor';
/** No-op implementation of SpanProcessor */
export declare class NoopSpanProcessor implements SpanProcessor {
onStart(_span: Span, _context: Context): void;
onEnd(_span: ReadableSpan): void;
shutdown(): Promise<void>;
forceFlush(): Promise<void>;
}
//# sourceMappingURL=NoopSpanProcessor.d.ts.map

View File

@@ -0,0 +1,16 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/** No-op implementation of SpanProcessor */
export class NoopSpanProcessor {
onStart(_span, _context) { }
onEnd(_span) { }
shutdown() {
return Promise.resolve();
}
forceFlush() {
return Promise.resolve();
}
}
//# sourceMappingURL=NoopSpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NoopSpanProcessor.js","sourceRoot":"","sources":["../../../src/export/NoopSpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,4CAA4C;AAC5C,MAAM,OAAO,iBAAiB;IAC5B,OAAO,CAAC,KAAW,EAAE,QAAiB,IAAS,CAAC;IAChD,KAAK,CAAC,KAAmB,IAAS,CAAC;IACnC,QAAQ;QACN,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,UAAU;QACR,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Context } from '@opentelemetry/api';\nimport type { ReadableSpan } from './ReadableSpan';\nimport type { Span } from '../Span';\nimport type { SpanProcessor } from '../SpanProcessor';\n\n/** No-op implementation of SpanProcessor */\nexport class NoopSpanProcessor implements SpanProcessor {\n onStart(_span: Span, _context: Context): void {}\n onEnd(_span: ReadableSpan): void {}\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n"]}

View File

@@ -0,0 +1,24 @@
import type { SpanKind, SpanStatus, Attributes, HrTime, Link, SpanContext } from '@opentelemetry/api';
import type { Resource } from '@opentelemetry/resources';
import type { InstrumentationScope } from '@opentelemetry/core';
import type { TimedEvent } from '../TimedEvent';
export interface ReadableSpan {
readonly name: string;
readonly kind: SpanKind;
readonly spanContext: () => SpanContext;
readonly parentSpanContext?: SpanContext;
readonly startTime: HrTime;
readonly endTime: HrTime;
readonly status: SpanStatus;
readonly attributes: Attributes;
readonly links: Link[];
readonly events: TimedEvent[];
readonly duration: HrTime;
readonly ended: boolean;
readonly resource: Resource;
readonly instrumentationScope: InstrumentationScope;
readonly droppedAttributesCount: number;
readonly droppedEventsCount: number;
readonly droppedLinksCount: number;
}
//# sourceMappingURL=ReadableSpan.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=ReadableSpan.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ReadableSpan.js","sourceRoot":"","sources":["../../../src/export/ReadableSpan.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n SpanKind,\n SpanStatus,\n Attributes,\n HrTime,\n Link,\n SpanContext,\n} from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { InstrumentationScope } from '@opentelemetry/core';\nimport type { TimedEvent } from '../TimedEvent';\n\nexport interface ReadableSpan {\n readonly name: string;\n readonly kind: SpanKind;\n readonly spanContext: () => SpanContext;\n readonly parentSpanContext?: SpanContext;\n readonly startTime: HrTime;\n readonly endTime: HrTime;\n readonly status: SpanStatus;\n readonly attributes: Attributes;\n readonly links: Link[];\n readonly events: TimedEvent[];\n readonly duration: HrTime;\n readonly ended: boolean;\n readonly resource: Resource;\n readonly instrumentationScope: InstrumentationScope;\n readonly droppedAttributesCount: number;\n readonly droppedEventsCount: number;\n readonly droppedLinksCount: number;\n}\n"]}

View File

@@ -0,0 +1,26 @@
import type { Context } from '@opentelemetry/api';
import type { Span } from '../Span';
import type { SpanProcessor } from '../SpanProcessor';
import type { ReadableSpan } from './ReadableSpan';
import type { SpanExporter } from './SpanExporter';
/**
* An implementation of the {@link SpanProcessor} that converts the {@link Span}
* to {@link ReadableSpan} and passes it to the configured exporter.
*
* Only spans that are sampled are converted.
*
* NOTE: This {@link SpanProcessor} exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the {@link BatchSpanProcessor} instead.
*/
export declare class SimpleSpanProcessor implements SpanProcessor {
private readonly _exporter;
private _shutdownOnce;
private _pendingExports;
constructor(exporter: SpanExporter);
forceFlush(): Promise<void>;
onStart(_span: Span, _parentContext: Context): void;
onEnd(span: ReadableSpan): void;
private _doExport;
shutdown(): Promise<void>;
private _shutdown;
}
//# sourceMappingURL=SimpleSpanProcessor.d.ts.map

View File

@@ -0,0 +1,61 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { TraceFlags } from '@opentelemetry/api';
import { internal, ExportResultCode, globalErrorHandler, BindOnceFuture, } from '@opentelemetry/core';
/**
* An implementation of the {@link SpanProcessor} that converts the {@link Span}
* to {@link ReadableSpan} and passes it to the configured exporter.
*
* Only spans that are sampled are converted.
*
* NOTE: This {@link SpanProcessor} exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the {@link BatchSpanProcessor} instead.
*/
export class SimpleSpanProcessor {
_exporter;
_shutdownOnce;
_pendingExports;
constructor(exporter) {
this._exporter = exporter;
this._shutdownOnce = new BindOnceFuture(this._shutdown, this);
this._pendingExports = new Set();
}
async forceFlush() {
await Promise.all(Array.from(this._pendingExports));
if (this._exporter.forceFlush) {
await this._exporter.forceFlush();
}
}
onStart(_span, _parentContext) { }
onEnd(span) {
if (this._shutdownOnce.isCalled) {
return;
}
if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
return;
}
const pendingExport = this._doExport(span).catch(err => globalErrorHandler(err));
// Enqueue this export to the pending list so it can be flushed by the user.
this._pendingExports.add(pendingExport);
void pendingExport.finally(() => this._pendingExports.delete(pendingExport));
}
async _doExport(span) {
if (span.resource.asyncAttributesPending) {
// Ensure resource is fully resolved before exporting.
await span.resource.waitForAsyncAttributes?.();
}
const result = await internal._export(this._exporter, [span]);
if (result.code !== ExportResultCode.SUCCESS) {
throw (result.error ??
new Error(`SimpleSpanProcessor: span export failed (status ${result})`));
}
}
shutdown() {
return this._shutdownOnce.call();
}
_shutdown() {
return this._exporter.shutdown();
}
}
//# sourceMappingURL=SimpleSpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SimpleSpanProcessor.js","sourceRoot":"","sources":["../../../src/export/SimpleSpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAM7B;;;;;;;GAOG;AACH,MAAM,OAAO,mBAAmB;IACb,SAAS,CAAe;IACjC,aAAa,CAAuB;IACpC,eAAe,CAAqB;IAE5C,YAAY,QAAsB;QAChC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,EAAiB,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QACpD,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;YAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;SACnC;IACH,CAAC;IAED,OAAO,CAAC,KAAW,EAAE,cAAuB,IAAS,CAAC;IAEtD,KAAK,CAAC,IAAkB;QACtB,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;YAC/B,OAAO;SACR;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC9D,OAAO;SACR;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CACrD,kBAAkB,CAAC,GAAG,CAAC,CACxB,CAAC;QACF,4EAA4E;QAC5E,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACxC,KAAK,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAC9B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC,CAC3C,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAkB;QACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE;YACxC,sDAAsD;YACtD,MAAM,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,EAAE,CAAC;SAChD;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC,OAAO,EAAE;YAC5C,MAAM,CACJ,MAAM,CAAC,KAAK;gBACZ,IAAI,KAAK,CAAC,mDAAmD,MAAM,GAAG,CAAC,CACxE,CAAC;SACH;IACH,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAEO,SAAS;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Context } from '@opentelemetry/api';\nimport { TraceFlags } from '@opentelemetry/api';\nimport {\n internal,\n ExportResultCode,\n globalErrorHandler,\n BindOnceFuture,\n} from '@opentelemetry/core';\nimport type { Span } from '../Span';\nimport type { SpanProcessor } from '../SpanProcessor';\nimport type { ReadableSpan } from './ReadableSpan';\nimport type { SpanExporter } from './SpanExporter';\n\n/**\n * An implementation of the {@link SpanProcessor} that converts the {@link Span}\n * to {@link ReadableSpan} and passes it to the configured exporter.\n *\n * Only spans that are sampled are converted.\n *\n * NOTE: This {@link SpanProcessor} exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the {@link BatchSpanProcessor} instead.\n */\nexport class SimpleSpanProcessor implements SpanProcessor {\n private readonly _exporter: SpanExporter;\n private _shutdownOnce: BindOnceFuture<void>;\n private _pendingExports: Set<Promise<void>>;\n\n constructor(exporter: SpanExporter) {\n this._exporter = exporter;\n this._shutdownOnce = new BindOnceFuture(this._shutdown, this);\n this._pendingExports = new Set<Promise<void>>();\n }\n\n async forceFlush(): Promise<void> {\n await Promise.all(Array.from(this._pendingExports));\n if (this._exporter.forceFlush) {\n await this._exporter.forceFlush();\n }\n }\n\n onStart(_span: Span, _parentContext: Context): void {}\n\n onEnd(span: ReadableSpan): void {\n if (this._shutdownOnce.isCalled) {\n return;\n }\n\n if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {\n return;\n }\n\n const pendingExport = this._doExport(span).catch(err =>\n globalErrorHandler(err)\n );\n // Enqueue this export to the pending list so it can be flushed by the user.\n this._pendingExports.add(pendingExport);\n void pendingExport.finally(() =>\n this._pendingExports.delete(pendingExport)\n );\n }\n\n private async _doExport(span: ReadableSpan): Promise<void> {\n if (span.resource.asyncAttributesPending) {\n // Ensure resource is fully resolved before exporting.\n await span.resource.waitForAsyncAttributes?.();\n }\n\n const result = await internal._export(this._exporter, [span]);\n if (result.code !== ExportResultCode.SUCCESS) {\n throw (\n result.error ??\n new Error(`SimpleSpanProcessor: span export failed (status ${result})`)\n );\n }\n }\n\n shutdown(): Promise<void> {\n return this._shutdownOnce.call();\n }\n\n private _shutdown(): Promise<void> {\n return this._exporter.shutdown();\n }\n}\n"]}

View File

@@ -0,0 +1,21 @@
import type { ExportResult } from '@opentelemetry/core';
import type { ReadableSpan } from './ReadableSpan';
/**
* An interface that allows different tracing services to export recorded data
* for sampled spans in their own format.
*
* To export data this MUST be register to the Tracer SDK using a optional
* config.
*/
export interface SpanExporter {
/**
* Called to export sampled {@link ReadableSpan}s.
* @param spans the list of sampled Spans to be exported.
*/
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
/** Stops the exporter. */
shutdown(): Promise<void>;
/** Immediately export all spans */
forceFlush?(): Promise<void>;
}
//# sourceMappingURL=SpanExporter.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=SpanExporter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SpanExporter.js","sourceRoot":"","sources":["../../../src/export/SpanExporter.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ExportResult } from '@opentelemetry/core';\nimport type { ReadableSpan } from './ReadableSpan';\n\n/**\n * An interface that allows different tracing services to export recorded data\n * for sampled spans in their own format.\n *\n * To export data this MUST be register to the Tracer SDK using a optional\n * config.\n */\nexport interface SpanExporter {\n /**\n * Called to export sampled {@link ReadableSpan}s.\n * @param spans the list of sampled Spans to be exported.\n */\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void;\n\n /** Stops the exporter. */\n shutdown(): Promise<void>;\n\n /** Immediately export all spans */\n forceFlush?(): Promise<void>;\n}\n"]}

View File

@@ -0,0 +1,20 @@
export { BasicTracerProvider } from './BasicTracerProvider';
export { BatchSpanProcessor, RandomIdGenerator } from './platform';
export { ConsoleSpanExporter } from './export/ConsoleSpanExporter';
export { InMemorySpanExporter } from './export/InMemorySpanExporter';
export type { ReadableSpan } from './export/ReadableSpan';
export { SimpleSpanProcessor } from './export/SimpleSpanProcessor';
export type { SpanExporter } from './export/SpanExporter';
export { NoopSpanProcessor } from './export/NoopSpanProcessor';
export { AlwaysOffSampler } from './sampler/AlwaysOffSampler';
export { AlwaysOnSampler } from './sampler/AlwaysOnSampler';
export { ParentBasedSampler } from './sampler/ParentBasedSampler';
export { TraceIdRatioBasedSampler } from './sampler/TraceIdRatioBasedSampler';
export { SamplingDecision } from './Sampler';
export type { Sampler, SamplingResult } from './Sampler';
export type { Span } from './Span';
export type { SpanProcessor } from './SpanProcessor';
export type { TimedEvent } from './TimedEvent';
export type { BatchSpanProcessorBrowserConfig, BufferConfig, GeneralLimits, SDKRegistrationConfig, SpanLimits, TracerConfig, } from './types';
export type { IdGenerator } from './IdGenerator';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,16 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export { BasicTracerProvider } from './BasicTracerProvider';
export { BatchSpanProcessor, RandomIdGenerator } from './platform';
export { ConsoleSpanExporter } from './export/ConsoleSpanExporter';
export { InMemorySpanExporter } from './export/InMemorySpanExporter';
export { SimpleSpanProcessor } from './export/SimpleSpanProcessor';
export { NoopSpanProcessor } from './export/NoopSpanProcessor';
export { AlwaysOffSampler } from './sampler/AlwaysOffSampler';
export { AlwaysOnSampler } from './sampler/AlwaysOnSampler';
export { ParentBasedSampler } from './sampler/ParentBasedSampler';
export { TraceIdRatioBasedSampler } from './sampler/TraceIdRatioBasedSampler';
export { SamplingDecision } from './Sampler';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { BasicTracerProvider } from './BasicTracerProvider';\nexport { BatchSpanProcessor, RandomIdGenerator } from './platform';\nexport { ConsoleSpanExporter } from './export/ConsoleSpanExporter';\nexport { InMemorySpanExporter } from './export/InMemorySpanExporter';\nexport type { ReadableSpan } from './export/ReadableSpan';\nexport { SimpleSpanProcessor } from './export/SimpleSpanProcessor';\nexport type { SpanExporter } from './export/SpanExporter';\nexport { NoopSpanProcessor } from './export/NoopSpanProcessor';\nexport { AlwaysOffSampler } from './sampler/AlwaysOffSampler';\nexport { AlwaysOnSampler } from './sampler/AlwaysOnSampler';\nexport { ParentBasedSampler } from './sampler/ParentBasedSampler';\nexport { TraceIdRatioBasedSampler } from './sampler/TraceIdRatioBasedSampler';\nexport { SamplingDecision } from './Sampler';\nexport type { Sampler, SamplingResult } from './Sampler';\nexport type { Span } from './Span';\nexport type { SpanProcessor } from './SpanProcessor';\nexport type { TimedEvent } from './TimedEvent';\nexport type {\n BatchSpanProcessorBrowserConfig,\n BufferConfig,\n GeneralLimits,\n SDKRegistrationConfig,\n SpanLimits,\n TracerConfig,\n} from './types';\nexport type { IdGenerator } from './IdGenerator';\n"]}

View File

@@ -0,0 +1,14 @@
import type { IdGenerator } from '../../IdGenerator';
export declare class RandomIdGenerator implements IdGenerator {
/**
* Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
* characters corresponding to 128 bits.
*/
generateTraceId(): string;
/**
* Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex
* characters corresponding to 64 bits.
*/
generateSpanId(): string;
}
//# sourceMappingURL=RandomIdGenerator.d.ts.map

View File

@@ -0,0 +1,51 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
const TRACE_ID_BYTES = 16;
const SPAN_ID_BYTES = 8;
const TRACE_BUFFER = new Uint8Array(TRACE_ID_BYTES);
const SPAN_BUFFER = new Uint8Array(SPAN_ID_BYTES);
// Byte-to-hex lookup is faster than toString(16) in browsers
const HEX = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
/**
* Fills buffer with random bytes, ensuring at least one is non-zero
* per W3C Trace Context spec.
*/
function randomFill(buf) {
for (let i = 0; i < buf.length; i++) {
buf[i] = (Math.random() * 256) >>> 0;
}
// Ensure non-zero
for (let i = 0; i < buf.length; i++) {
if (buf[i] > 0)
return;
}
buf[buf.length - 1] = 1;
}
function toHex(buf) {
let hex = '';
for (let i = 0; i < buf.length; i++) {
hex += HEX[buf[i]];
}
return hex;
}
export class RandomIdGenerator {
/**
* Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
* characters corresponding to 128 bits.
*/
generateTraceId() {
randomFill(TRACE_BUFFER);
return toHex(TRACE_BUFFER);
}
/**
* Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex
* characters corresponding to 64 bits.
*/
generateSpanId() {
randomFill(SPAN_BUFFER);
return toHex(SPAN_BUFFER);
}
}
//# sourceMappingURL=RandomIdGenerator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RandomIdGenerator.js","sourceRoot":"","sources":["../../../../src/platform/browser/RandomIdGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,MAAM,YAAY,GAAG,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;AAElD,6DAA6D;AAC7D,MAAM,GAAG,GAAa,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACzD,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAChC,CAAC;AAEF;;;GAGG;AACH,SAAS,UAAU,CAAC,GAAe;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;KACtC;IACD,kBAAkB;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAAE,OAAO;KACxB;IACD,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,KAAK,CAAC,GAAe;IAC5B,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KACpB;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,iBAAiB;IAC5B;;;OAGG;IACH,eAAe;QACb,UAAU,CAAC,YAAY,CAAC,CAAC;QACzB,OAAO,KAAK,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,UAAU,CAAC,WAAW,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { IdGenerator } from '../../IdGenerator';\n\nconst TRACE_ID_BYTES = 16;\nconst SPAN_ID_BYTES = 8;\n\nconst TRACE_BUFFER = new Uint8Array(TRACE_ID_BYTES);\nconst SPAN_BUFFER = new Uint8Array(SPAN_ID_BYTES);\n\n// Byte-to-hex lookup is faster than toString(16) in browsers\nconst HEX: string[] = Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Fills buffer with random bytes, ensuring at least one is non-zero\n * per W3C Trace Context spec.\n */\nfunction randomFill(buf: Uint8Array): void {\n for (let i = 0; i < buf.length; i++) {\n buf[i] = (Math.random() * 256) >>> 0;\n }\n // Ensure non-zero\n for (let i = 0; i < buf.length; i++) {\n if (buf[i] > 0) return;\n }\n buf[buf.length - 1] = 1;\n}\n\nfunction toHex(buf: Uint8Array): string {\n let hex = '';\n for (let i = 0; i < buf.length; i++) {\n hex += HEX[buf[i]];\n }\n return hex;\n}\n\nexport class RandomIdGenerator implements IdGenerator {\n /**\n * Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex\n * characters corresponding to 128 bits.\n */\n generateTraceId(): string {\n randomFill(TRACE_BUFFER);\n return toHex(TRACE_BUFFER);\n }\n\n /**\n * Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex\n * characters corresponding to 64 bits.\n */\n generateSpanId(): string {\n randomFill(SPAN_BUFFER);\n return toHex(SPAN_BUFFER);\n }\n}\n"]}

View File

@@ -0,0 +1,11 @@
import { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';
import type { SpanExporter } from '../../../export/SpanExporter';
import type { BatchSpanProcessorBrowserConfig } from '../../../types';
export declare class BatchSpanProcessor extends BatchSpanProcessorBase<BatchSpanProcessorBrowserConfig> {
private _visibilityChangeListener?;
private _pageHideListener?;
constructor(_exporter: SpanExporter, config?: BatchSpanProcessorBrowserConfig);
private onInit;
protected onShutdown(): void;
}
//# sourceMappingURL=BatchSpanProcessor.d.ts.map

View File

@@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';
import { globalErrorHandler } from '@opentelemetry/core';
export class BatchSpanProcessor extends BatchSpanProcessorBase {
_visibilityChangeListener;
_pageHideListener;
constructor(_exporter, config) {
super(_exporter, config);
this.onInit(config);
}
onInit(config) {
if (config?.disableAutoFlushOnDocumentHide !== true &&
typeof document !== 'undefined') {
this._visibilityChangeListener = () => {
if (document.visibilityState === 'hidden') {
this.forceFlush().catch(error => {
globalErrorHandler(error);
});
}
};
this._pageHideListener = () => {
this.forceFlush().catch(error => {
globalErrorHandler(error);
});
};
document.addEventListener('visibilitychange', this._visibilityChangeListener);
// use 'pagehide' event as a fallback for Safari; see https://bugs.webkit.org/show_bug.cgi?id=116769
document.addEventListener('pagehide', this._pageHideListener);
}
}
onShutdown() {
if (typeof document !== 'undefined') {
if (this._visibilityChangeListener) {
document.removeEventListener('visibilitychange', this._visibilityChangeListener);
}
if (this._pageHideListener) {
document.removeEventListener('pagehide', this._pageHideListener);
}
}
}
}
//# sourceMappingURL=BatchSpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchSpanProcessor.js","sourceRoot":"","sources":["../../../../../src/platform/browser/export/BatchSpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAGhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,OAAO,kBAAmB,SAAQ,sBAAuD;IACrF,yBAAyB,CAAc;IACvC,iBAAiB,CAAc;IAEvC,YACE,SAAuB,EACvB,MAAwC;QAExC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,MAAwC;QACrD,IACE,MAAM,EAAE,8BAA8B,KAAK,IAAI;YAC/C,OAAO,QAAQ,KAAK,WAAW,EAC/B;YACA,IAAI,CAAC,yBAAyB,GAAG,GAAG,EAAE;gBACpC,IAAI,QAAQ,CAAC,eAAe,KAAK,QAAQ,EAAE;oBACzC,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;wBAC9B,kBAAkB,CAAC,KAAK,CAAC,CAAC;oBAC5B,CAAC,CAAC,CAAC;iBACJ;YACH,CAAC,CAAC;YACF,IAAI,CAAC,iBAAiB,GAAG,GAAG,EAAE;gBAC5B,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;oBAC9B,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC5B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YACF,QAAQ,CAAC,gBAAgB,CACvB,kBAAkB,EAClB,IAAI,CAAC,yBAAyB,CAC/B,CAAC;YAEF,oGAAoG;YACpG,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;SAC/D;IACH,CAAC;IAES,UAAU;QAClB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,IAAI,IAAI,CAAC,yBAAyB,EAAE;gBAClC,QAAQ,CAAC,mBAAmB,CAC1B,kBAAkB,EAClB,IAAI,CAAC,yBAAyB,CAC/B,CAAC;aACH;YACD,IAAI,IAAI,CAAC,iBAAiB,EAAE;gBAC1B,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;aAClE;SACF;IACH,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';\nimport type { SpanExporter } from '../../../export/SpanExporter';\nimport type { BatchSpanProcessorBrowserConfig } from '../../../types';\nimport { globalErrorHandler } from '@opentelemetry/core';\n\nexport class BatchSpanProcessor extends BatchSpanProcessorBase<BatchSpanProcessorBrowserConfig> {\n private _visibilityChangeListener?: () => void;\n private _pageHideListener?: () => void;\n\n constructor(\n _exporter: SpanExporter,\n config?: BatchSpanProcessorBrowserConfig\n ) {\n super(_exporter, config);\n this.onInit(config);\n }\n\n private onInit(config?: BatchSpanProcessorBrowserConfig): void {\n if (\n config?.disableAutoFlushOnDocumentHide !== true &&\n typeof document !== 'undefined'\n ) {\n this._visibilityChangeListener = () => {\n if (document.visibilityState === 'hidden') {\n this.forceFlush().catch(error => {\n globalErrorHandler(error);\n });\n }\n };\n this._pageHideListener = () => {\n this.forceFlush().catch(error => {\n globalErrorHandler(error);\n });\n };\n document.addEventListener(\n 'visibilitychange',\n this._visibilityChangeListener\n );\n\n // use 'pagehide' event as a fallback for Safari; see https://bugs.webkit.org/show_bug.cgi?id=116769\n document.addEventListener('pagehide', this._pageHideListener);\n }\n }\n\n protected onShutdown(): void {\n if (typeof document !== 'undefined') {\n if (this._visibilityChangeListener) {\n document.removeEventListener(\n 'visibilitychange',\n this._visibilityChangeListener\n );\n }\n if (this._pageHideListener) {\n document.removeEventListener('pagehide', this._pageHideListener);\n }\n }\n }\n}\n"]}

View File

@@ -0,0 +1,3 @@
export { BatchSpanProcessor } from './export/BatchSpanProcessor';
export { RandomIdGenerator } from './RandomIdGenerator';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,7 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export { BatchSpanProcessor } from './export/BatchSpanProcessor';
export { RandomIdGenerator } from './RandomIdGenerator';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/platform/browser/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { BatchSpanProcessor } from './export/BatchSpanProcessor';\nexport { RandomIdGenerator } from './RandomIdGenerator';\n"]}

View File

@@ -0,0 +1,2 @@
export { BatchSpanProcessor, RandomIdGenerator } from './node';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export { BatchSpanProcessor, RandomIdGenerator } from './node';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { BatchSpanProcessor, RandomIdGenerator } from './node';\n"]}

View File

@@ -0,0 +1,14 @@
import type { IdGenerator } from '../../IdGenerator';
export declare class RandomIdGenerator implements IdGenerator {
/**
* Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
* characters corresponding to 128 bits.
*/
generateTraceId: () => string;
/**
* Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex
* characters corresponding to 64 bits.
*/
generateSpanId: () => string;
}
//# sourceMappingURL=RandomIdGenerator.d.ts.map

View File

@@ -0,0 +1,39 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
const SPAN_ID_BYTES = 8;
const TRACE_ID_BYTES = 16;
export class RandomIdGenerator {
/**
* Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
* characters corresponding to 128 bits.
*/
generateTraceId = getIdGenerator(TRACE_ID_BYTES);
/**
* Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex
* characters corresponding to 64 bits.
*/
generateSpanId = getIdGenerator(SPAN_ID_BYTES);
}
const SHARED_BUFFER = Buffer.allocUnsafe(TRACE_ID_BYTES);
function getIdGenerator(bytes) {
return function generateId() {
for (let i = 0; i < bytes / 4; i++) {
// unsigned right shift drops decimal part of the number
// it is required because if a number between 2**32 and 2**32 - 1 is generated, an out of range error is thrown by writeUInt32BE
SHARED_BUFFER.writeUInt32BE((Math.random() * 2 ** 32) >>> 0, i * 4);
}
// If buffer is all 0, set the last byte to 1 to guarantee a valid w3c id is generated
for (let i = 0; i < bytes; i++) {
if (SHARED_BUFFER[i] > 0) {
break;
}
else if (i === bytes - 1) {
SHARED_BUFFER[bytes - 1] = 1;
}
}
return SHARED_BUFFER.toString('hex', 0, bytes);
};
}
//# sourceMappingURL=RandomIdGenerator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RandomIdGenerator.js","sourceRoot":"","sources":["../../../../src/platform/node/RandomIdGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,MAAM,OAAO,iBAAiB;IAC5B;;;OAGG;IACH,eAAe,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;IAEjD;;;OAGG;IACH,cAAc,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;CAChD;AAED,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AACzD,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,SAAS,UAAU;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAClC,wDAAwD;YACxD,gIAAgI;YAChI,aAAa,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;SACrE;QAED,sFAAsF;QACtF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;gBACxB,MAAM;aACP;iBAAM,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,EAAE;gBAC1B,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aAC9B;SACF;QAED,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { IdGenerator } from '../../IdGenerator';\n\nconst SPAN_ID_BYTES = 8;\nconst TRACE_ID_BYTES = 16;\n\nexport class RandomIdGenerator implements IdGenerator {\n /**\n * Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex\n * characters corresponding to 128 bits.\n */\n generateTraceId = getIdGenerator(TRACE_ID_BYTES);\n\n /**\n * Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex\n * characters corresponding to 64 bits.\n */\n generateSpanId = getIdGenerator(SPAN_ID_BYTES);\n}\n\nconst SHARED_BUFFER = Buffer.allocUnsafe(TRACE_ID_BYTES);\nfunction getIdGenerator(bytes: number): () => string {\n return function generateId() {\n for (let i = 0; i < bytes / 4; i++) {\n // unsigned right shift drops decimal part of the number\n // it is required because if a number between 2**32 and 2**32 - 1 is generated, an out of range error is thrown by writeUInt32BE\n SHARED_BUFFER.writeUInt32BE((Math.random() * 2 ** 32) >>> 0, i * 4);\n }\n\n // If buffer is all 0, set the last byte to 1 to guarantee a valid w3c id is generated\n for (let i = 0; i < bytes; i++) {\n if (SHARED_BUFFER[i] > 0) {\n break;\n } else if (i === bytes - 1) {\n SHARED_BUFFER[bytes - 1] = 1;\n }\n }\n\n return SHARED_BUFFER.toString('hex', 0, bytes);\n };\n}\n"]}

View File

@@ -0,0 +1,6 @@
import { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';
import type { BufferConfig } from '../../../types';
export declare class BatchSpanProcessor extends BatchSpanProcessorBase<BufferConfig> {
protected onShutdown(): void;
}
//# sourceMappingURL=BatchSpanProcessor.d.ts.map

View File

@@ -0,0 +1,9 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';
export class BatchSpanProcessor extends BatchSpanProcessorBase {
onShutdown() { }
}
//# sourceMappingURL=BatchSpanProcessor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchSpanProcessor.js","sourceRoot":"","sources":["../../../../../src/platform/node/export/BatchSpanProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAGhF,MAAM,OAAO,kBAAmB,SAAQ,sBAAoC;IAChE,UAAU,KAAU,CAAC;CAChC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { BatchSpanProcessorBase } from '../../../export/BatchSpanProcessorBase';\nimport type { BufferConfig } from '../../../types';\n\nexport class BatchSpanProcessor extends BatchSpanProcessorBase<BufferConfig> {\n protected onShutdown(): void {}\n}\n"]}

View File

@@ -0,0 +1,3 @@
export { BatchSpanProcessor } from './export/BatchSpanProcessor';
export { RandomIdGenerator } from './RandomIdGenerator';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,7 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export { BatchSpanProcessor } from './export/BatchSpanProcessor';
export { RandomIdGenerator } from './RandomIdGenerator';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/platform/node/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport { BatchSpanProcessor } from './export/BatchSpanProcessor';\nexport { RandomIdGenerator } from './RandomIdGenerator';\n"]}

View File

@@ -0,0 +1,7 @@
import type { Sampler, SamplingResult } from '../Sampler';
/** Sampler that samples no traces. */
export declare class AlwaysOffSampler implements Sampler {
shouldSample(): SamplingResult;
toString(): string;
}
//# sourceMappingURL=AlwaysOffSampler.d.ts.map

View File

@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { SamplingDecision } from '../Sampler';
/** Sampler that samples no traces. */
export class AlwaysOffSampler {
shouldSample() {
return {
decision: SamplingDecision.NOT_RECORD,
};
}
toString() {
return 'AlwaysOffSampler';
}
}
//# sourceMappingURL=AlwaysOffSampler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AlwaysOffSampler.js","sourceRoot":"","sources":["../../../src/sampler/AlwaysOffSampler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,sCAAsC;AACtC,MAAM,OAAO,gBAAgB;IAC3B,YAAY;QACV,OAAO;YACL,QAAQ,EAAE,gBAAgB,CAAC,UAAU;SACtC,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,kBAAkB,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Sampler, SamplingResult } from '../Sampler';\nimport { SamplingDecision } from '../Sampler';\n\n/** Sampler that samples no traces. */\nexport class AlwaysOffSampler implements Sampler {\n shouldSample(): SamplingResult {\n return {\n decision: SamplingDecision.NOT_RECORD,\n };\n }\n\n toString(): string {\n return 'AlwaysOffSampler';\n }\n}\n"]}

View File

@@ -0,0 +1,7 @@
import type { Sampler, SamplingResult } from '../Sampler';
/** Sampler that samples all traces. */
export declare class AlwaysOnSampler implements Sampler {
shouldSample(): SamplingResult;
toString(): string;
}
//# sourceMappingURL=AlwaysOnSampler.d.ts.map

View File

@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { SamplingDecision } from '../Sampler';
/** Sampler that samples all traces. */
export class AlwaysOnSampler {
shouldSample() {
return {
decision: SamplingDecision.RECORD_AND_SAMPLED,
};
}
toString() {
return 'AlwaysOnSampler';
}
}
//# sourceMappingURL=AlwaysOnSampler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AlwaysOnSampler.js","sourceRoot":"","sources":["../../../src/sampler/AlwaysOnSampler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,uCAAuC;AACvC,MAAM,OAAO,eAAe;IAC1B,YAAY;QACV,OAAO;YACL,QAAQ,EAAE,gBAAgB,CAAC,kBAAkB;SAC9C,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,iBAAiB,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Sampler, SamplingResult } from '../Sampler';\nimport { SamplingDecision } from '../Sampler';\n\n/** Sampler that samples all traces. */\nexport class AlwaysOnSampler implements Sampler {\n shouldSample(): SamplingResult {\n return {\n decision: SamplingDecision.RECORD_AND_SAMPLED,\n };\n }\n\n toString(): string {\n return 'AlwaysOnSampler';\n }\n}\n"]}

View File

@@ -0,0 +1,30 @@
import type { Context, Link, Attributes, SpanKind } from '@opentelemetry/api';
import type { Sampler, SamplingResult } from '../Sampler';
/**
* A composite sampler that either respects the parent span's sampling decision
* or delegates to `delegateSampler` for root spans.
*/
export declare class ParentBasedSampler implements Sampler {
private _root;
private _remoteParentSampled;
private _remoteParentNotSampled;
private _localParentSampled;
private _localParentNotSampled;
constructor(config: ParentBasedSamplerConfig);
shouldSample(context: Context, traceId: string, spanName: string, spanKind: SpanKind, attributes: Attributes, links: Link[]): SamplingResult;
toString(): string;
}
interface ParentBasedSamplerConfig {
/** Sampler called for spans with no parent */
root: Sampler;
/** Sampler called for spans with a remote parent which was sampled. Default AlwaysOn */
remoteParentSampled?: Sampler;
/** Sampler called for spans with a remote parent which was not sampled. Default AlwaysOff */
remoteParentNotSampled?: Sampler;
/** Sampler called for spans with a local parent which was sampled. Default AlwaysOn */
localParentSampled?: Sampler;
/** Sampler called for spans with a local parent which was not sampled. Default AlwaysOff */
localParentNotSampled?: Sampler;
}
export {};
//# sourceMappingURL=ParentBasedSampler.d.ts.map

View File

@@ -0,0 +1,54 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { isSpanContextValid, TraceFlags, trace } from '@opentelemetry/api';
import { globalErrorHandler } from '@opentelemetry/core';
import { AlwaysOffSampler } from './AlwaysOffSampler';
import { AlwaysOnSampler } from './AlwaysOnSampler';
/**
* A composite sampler that either respects the parent span's sampling decision
* or delegates to `delegateSampler` for root spans.
*/
export class ParentBasedSampler {
_root;
_remoteParentSampled;
_remoteParentNotSampled;
_localParentSampled;
_localParentNotSampled;
constructor(config) {
this._root = config.root;
if (!this._root) {
globalErrorHandler(new Error('ParentBasedSampler must have a root sampler configured'));
this._root = new AlwaysOnSampler();
}
this._remoteParentSampled =
config.remoteParentSampled ?? new AlwaysOnSampler();
this._remoteParentNotSampled =
config.remoteParentNotSampled ?? new AlwaysOffSampler();
this._localParentSampled =
config.localParentSampled ?? new AlwaysOnSampler();
this._localParentNotSampled =
config.localParentNotSampled ?? new AlwaysOffSampler();
}
shouldSample(context, traceId, spanName, spanKind, attributes, links) {
const parentContext = trace.getSpanContext(context);
if (!parentContext || !isSpanContextValid(parentContext)) {
return this._root.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
if (parentContext.isRemote) {
if (parentContext.traceFlags & TraceFlags.SAMPLED) {
return this._remoteParentSampled.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
return this._remoteParentNotSampled.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
if (parentContext.traceFlags & TraceFlags.SAMPLED) {
return this._localParentSampled.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
return this._localParentNotSampled.shouldSample(context, traceId, spanName, spanKind, attributes, links);
}
toString() {
return `ParentBased{root=${this._root.toString()}, remoteParentSampled=${this._remoteParentSampled.toString()}, remoteParentNotSampled=${this._remoteParentNotSampled.toString()}, localParentSampled=${this._localParentSampled.toString()}, localParentNotSampled=${this._localParentNotSampled.toString()}}`;
}
}
//# sourceMappingURL=ParentBasedSampler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import type { Sampler, SamplingResult } from '../Sampler';
/** Sampler that samples a given fraction of traces based of trace id deterministically. */
export declare class TraceIdRatioBasedSampler implements Sampler {
private readonly _ratio;
private _upperBound;
constructor(ratio?: number);
shouldSample(context: unknown, traceId: string): SamplingResult;
toString(): string;
private _normalize;
private _accumulate;
}
//# sourceMappingURL=TraceIdRatioBasedSampler.d.ts.map

View File

@@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { isValidTraceId } from '@opentelemetry/api';
import { SamplingDecision } from '../Sampler';
/** Sampler that samples a given fraction of traces based of trace id deterministically. */
export class TraceIdRatioBasedSampler {
_ratio;
_upperBound;
constructor(ratio = 0) {
this._ratio = this._normalize(ratio);
this._upperBound = Math.floor(this._ratio * 0xffffffff);
}
shouldSample(context, traceId) {
return {
decision: isValidTraceId(traceId) && this._accumulate(traceId) < this._upperBound
? SamplingDecision.RECORD_AND_SAMPLED
: SamplingDecision.NOT_RECORD,
};
}
toString() {
return `TraceIdRatioBased{${this._ratio}}`;
}
_normalize(ratio) {
if (typeof ratio !== 'number' || isNaN(ratio))
return 0;
return ratio >= 1 ? 1 : ratio <= 0 ? 0 : ratio;
}
_accumulate(traceId) {
let accumulation = 0;
for (let i = 0; i < traceId.length / 8; i++) {
const pos = i * 8;
const part = parseInt(traceId.slice(pos, pos + 8), 16);
accumulation = (accumulation ^ part) >>> 0;
}
return accumulation;
}
}
//# sourceMappingURL=TraceIdRatioBasedSampler.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TraceIdRatioBasedSampler.js","sourceRoot":"","sources":["../../../src/sampler/TraceIdRatioBasedSampler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,2FAA2F;AAC3F,MAAM,OAAO,wBAAwB;IAClB,MAAM,CAAC;IAChB,WAAW,CAAS;IAE5B,YAAY,KAAK,GAAG,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED,YAAY,CAAC,OAAgB,EAAE,OAAe;QAC5C,OAAO;YACL,QAAQ,EACN,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW;gBACrE,CAAC,CAAC,gBAAgB,CAAC,kBAAkB;gBACrC,CAAC,CAAC,gBAAgB,CAAC,UAAU;SAClC,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,qBAAqB,IAAI,CAAC,MAAM,GAAG,CAAC;IAC7C,CAAC;IAEO,UAAU,CAAC,KAAa;QAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACxD,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACjD,CAAC;IAEO,WAAW,CAAC,OAAe;QACjC,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3C,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,YAAY,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;SAC5C;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { isValidTraceId } from '@opentelemetry/api';\nimport type { Sampler, SamplingResult } from '../Sampler';\nimport { SamplingDecision } from '../Sampler';\n\n/** Sampler that samples a given fraction of traces based of trace id deterministically. */\nexport class TraceIdRatioBasedSampler implements Sampler {\n private readonly _ratio;\n private _upperBound: number;\n\n constructor(ratio = 0) {\n this._ratio = this._normalize(ratio);\n this._upperBound = Math.floor(this._ratio * 0xffffffff);\n }\n\n shouldSample(context: unknown, traceId: string): SamplingResult {\n return {\n decision:\n isValidTraceId(traceId) && this._accumulate(traceId) < this._upperBound\n ? SamplingDecision.RECORD_AND_SAMPLED\n : SamplingDecision.NOT_RECORD,\n };\n }\n\n toString(): string {\n return `TraceIdRatioBased{${this._ratio}}`;\n }\n\n private _normalize(ratio: number): number {\n if (typeof ratio !== 'number' || isNaN(ratio)) return 0;\n return ratio >= 1 ? 1 : ratio <= 0 ? 0 : ratio;\n }\n\n private _accumulate(traceId: string): number {\n let accumulation = 0;\n for (let i = 0; i < traceId.length / 8; i++) {\n const pos = i * 8;\n const part = parseInt(traceId.slice(pos, pos + 8), 16);\n accumulation = (accumulation ^ part) >>> 0;\n }\n return accumulation;\n }\n}\n"]}

View File

@@ -0,0 +1,27 @@
/**
* Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote)
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export declare const ATTR_OTEL_SPAN_PARENT_ORIGIN: "otel.span.parent.origin";
/**
* The result value of the sampler for this span
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export declare const ATTR_OTEL_SPAN_SAMPLING_RESULT: "otel.span.sampling_result";
/**
* The number of created spans with `recording=true` for which the end operation has not been called yet.
*
* @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export declare const METRIC_OTEL_SDK_SPAN_LIVE: "otel.sdk.span.live";
/**
* The number of created spans.
*
* @note Implementations **MUST** record this metric for all spans, even for non-recording ones.
*
* @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export declare const METRIC_OTEL_SDK_SPAN_STARTED: "otel.sdk.span.started";
//# sourceMappingURL=semconv.d.ts.map

View File

@@ -0,0 +1,36 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
/*
* This file contains a copy of unstable semantic convention definitions
* used by this package.
* @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv
*/
/**
* Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote)
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export const ATTR_OTEL_SPAN_PARENT_ORIGIN = 'otel.span.parent.origin';
/**
* The result value of the sampler for this span
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export const ATTR_OTEL_SPAN_SAMPLING_RESULT = 'otel.span.sampling_result';
/**
* The number of created spans with `recording=true` for which the end operation has not been called yet.
*
* @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export const METRIC_OTEL_SDK_SPAN_LIVE = 'otel.sdk.span.live';
/**
* The number of created spans.
*
* @note Implementations **MUST** record this metric for all spans, even for non-recording ones.
*
* @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export const METRIC_OTEL_SDK_SPAN_STARTED = 'otel.sdk.span.started';
//# sourceMappingURL=semconv.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"semconv.js","sourceRoot":"","sources":["../../src/semconv.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAkC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GACzC,2BAAoC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,oBAA6B,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,uBAAgC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/*\n * This file contains a copy of unstable semantic convention definitions\n * used by this package.\n * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv\n */\n\n/**\n * Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote)\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_OTEL_SPAN_PARENT_ORIGIN = 'otel.span.parent.origin' as const;\n\n/**\n * The result value of the sampler for this span\n *\n * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const ATTR_OTEL_SPAN_SAMPLING_RESULT =\n 'otel.span.sampling_result' as const;\n\n/**\n * The number of created spans with `recording=true` for which the end operation has not been called yet.\n *\n * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const METRIC_OTEL_SDK_SPAN_LIVE = 'otel.sdk.span.live' as const;\n\n/**\n * The number of created spans.\n *\n * @note Implementations **MUST** record this metric for all spans, even for non-recording ones.\n *\n * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.\n */\nexport const METRIC_OTEL_SDK_SPAN_STARTED = 'otel.sdk.span.started' as const;\n"]}

View File

@@ -0,0 +1,94 @@
import type { ContextManager, MeterProvider, TextMapPropagator } from '@opentelemetry/api';
import type { Resource } from '@opentelemetry/resources';
import type { IdGenerator } from './IdGenerator';
import type { Sampler } from './Sampler';
import type { SpanProcessor } from './SpanProcessor';
/**
* TracerConfig provides an interface for configuring a Basic Tracer.
*/
export interface TracerConfig {
/**
* Sampler determines if a span should be recorded or should be a NoopSpan.
*/
sampler?: Sampler;
/** General Limits */
generalLimits?: GeneralLimits;
/** Span Limits */
spanLimits?: SpanLimits;
/** Resource associated with trace telemetry */
resource?: Resource;
/**
* Generator of trace and span IDs
* The default idGenerator generates random ids
*/
idGenerator?: IdGenerator;
/**
* How long the forceFlush can run before it is cancelled.
* The default value is 30000ms
*/
forceFlushTimeoutMillis?: number;
/**
* List of SpanProcessor for the tracer
*/
spanProcessors?: SpanProcessor[];
/**
* A meter provider to record trace SDK metrics to.
* @experimental This option is experimental and is subject to breaking changes in minor releases.
*/
meterProvider?: MeterProvider;
}
/**
* Configuration options for registering the API with the SDK.
* Undefined values may be substituted for defaults, and null
* values will not be registered.
*/
export interface SDKRegistrationConfig {
/** Propagator to register as the global propagator */
propagator?: TextMapPropagator | null;
/** Context manager to register as the global context manager */
contextManager?: ContextManager | null;
}
/** Global configuration limits of trace service */
export interface GeneralLimits {
/** attributeValueLengthLimit is maximum allowed attribute value size */
attributeValueLengthLimit?: number;
/** attributeCountLimit is number of attributes per trace */
attributeCountLimit?: number;
}
/** Global configuration of trace service */
export interface SpanLimits {
/** attributeValueLengthLimit is maximum allowed attribute value size */
attributeValueLengthLimit?: number;
/** attributeCountLimit is number of attributes per span */
attributeCountLimit?: number;
/** linkCountLimit is number of links per span */
linkCountLimit?: number;
/** eventCountLimit is number of message events per span */
eventCountLimit?: number;
/** attributePerEventCountLimit is the maximum number of attributes allowed per span event */
attributePerEventCountLimit?: number;
/** attributePerLinkCountLimit is the maximum number of attributes allowed per span link */
attributePerLinkCountLimit?: number;
}
/** Interface configuration for a buffer. */
export interface BufferConfig {
/** The maximum batch size of every export. It must be smaller or equal to
* maxQueueSize. The default value is 512. */
maxExportBatchSize?: number;
/** The delay interval in milliseconds between two consecutive exports.
* The default value is 5000ms. */
scheduledDelayMillis?: number;
/** How long the export can run before it is cancelled.
* The default value is 30000ms */
exportTimeoutMillis?: number;
/** The maximum queue size. After the size is reached spans are dropped.
* The default value is 2048. */
maxQueueSize?: number;
}
/** Interface configuration for BatchSpanProcessor on browser */
export interface BatchSpanProcessorBrowserConfig extends BufferConfig {
/** Disable flush when a user navigates to a new page, closes the tab or the browser, or,
* on mobile, switches to a different app. Auto flush is enabled by default. */
disableAutoFlushOnDocumentHide?: boolean;
}
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1,6 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
export {};
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n ContextManager,\n MeterProvider,\n TextMapPropagator,\n} from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { IdGenerator } from './IdGenerator';\nimport type { Sampler } from './Sampler';\nimport type { SpanProcessor } from './SpanProcessor';\n\n/**\n * TracerConfig provides an interface for configuring a Basic Tracer.\n */\nexport interface TracerConfig {\n /**\n * Sampler determines if a span should be recorded or should be a NoopSpan.\n */\n sampler?: Sampler;\n\n /** General Limits */\n generalLimits?: GeneralLimits;\n\n /** Span Limits */\n spanLimits?: SpanLimits;\n\n /** Resource associated with trace telemetry */\n resource?: Resource;\n\n /**\n * Generator of trace and span IDs\n * The default idGenerator generates random ids\n */\n idGenerator?: IdGenerator;\n\n /**\n * How long the forceFlush can run before it is cancelled.\n * The default value is 30000ms\n */\n forceFlushTimeoutMillis?: number;\n\n /**\n * List of SpanProcessor for the tracer\n */\n spanProcessors?: SpanProcessor[];\n\n /**\n * A meter provider to record trace SDK metrics to.\n * @experimental This option is experimental and is subject to breaking changes in minor releases.\n */\n meterProvider?: MeterProvider;\n}\n\n/**\n * Configuration options for registering the API with the SDK.\n * Undefined values may be substituted for defaults, and null\n * values will not be registered.\n */\nexport interface SDKRegistrationConfig {\n /** Propagator to register as the global propagator */\n propagator?: TextMapPropagator | null;\n\n /** Context manager to register as the global context manager */\n contextManager?: ContextManager | null;\n}\n\n/** Global configuration limits of trace service */\nexport interface GeneralLimits {\n /** attributeValueLengthLimit is maximum allowed attribute value size */\n attributeValueLengthLimit?: number;\n /** attributeCountLimit is number of attributes per trace */\n attributeCountLimit?: number;\n}\n\n/** Global configuration of trace service */\nexport interface SpanLimits {\n /** attributeValueLengthLimit is maximum allowed attribute value size */\n attributeValueLengthLimit?: number;\n /** attributeCountLimit is number of attributes per span */\n attributeCountLimit?: number;\n /** linkCountLimit is number of links per span */\n linkCountLimit?: number;\n /** eventCountLimit is number of message events per span */\n eventCountLimit?: number;\n /** attributePerEventCountLimit is the maximum number of attributes allowed per span event */\n attributePerEventCountLimit?: number;\n /** attributePerLinkCountLimit is the maximum number of attributes allowed per span link */\n attributePerLinkCountLimit?: number;\n}\n\n/** Interface configuration for a buffer. */\nexport interface BufferConfig {\n /** The maximum batch size of every export. It must be smaller or equal to\n * maxQueueSize. The default value is 512. */\n maxExportBatchSize?: number;\n\n /** The delay interval in milliseconds between two consecutive exports.\n * The default value is 5000ms. */\n scheduledDelayMillis?: number;\n\n /** How long the export can run before it is cancelled.\n * The default value is 30000ms */\n exportTimeoutMillis?: number;\n\n /** The maximum queue size. After the size is reached spans are dropped.\n * The default value is 2048. */\n maxQueueSize?: number;\n}\n\n/** Interface configuration for BatchSpanProcessor on browser */\nexport interface BatchSpanProcessorBrowserConfig extends BufferConfig {\n /** Disable flush when a user navigates to a new page, closes the tab or the browser, or,\n * on mobile, switches to a different app. Auto flush is enabled by default. */\n disableAutoFlushOnDocumentHide?: boolean;\n}\n"]}

View File

@@ -0,0 +1,20 @@
import type { Sampler } from './Sampler';
import type { SpanLimits, TracerConfig, GeneralLimits } from './types';
export declare const DEFAULT_ATTRIBUTE_COUNT_LIMIT = 128;
export declare const DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT: number;
/**
* Function to merge Default configuration (as specified in './config') with
* user provided configurations.
*/
export declare function mergeConfig(userConfig: TracerConfig): TracerConfig & {
sampler: Sampler;
spanLimits: SpanLimits;
generalLimits: GeneralLimits;
};
/**
* When general limits are provided and model specific limits are not,
* configures the model specific limits by using the values from the general ones.
* @param userConfig User provided tracer configuration
*/
export declare function reconfigureLimits(userConfig: TracerConfig): TracerConfig;
//# sourceMappingURL=utility.d.ts.map

View File

@@ -0,0 +1,50 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { buildSamplerFromEnv, loadDefaultConfig } from './config';
import { getNumberFromEnv } from '@opentelemetry/core';
export const DEFAULT_ATTRIBUTE_COUNT_LIMIT = 128;
export const DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT = Infinity;
/**
* Function to merge Default configuration (as specified in './config') with
* user provided configurations.
*/
export function mergeConfig(userConfig) {
const perInstanceDefaults = {
sampler: buildSamplerFromEnv(),
};
const DEFAULT_CONFIG = loadDefaultConfig();
const target = Object.assign({}, DEFAULT_CONFIG, perInstanceDefaults, userConfig);
target.generalLimits = Object.assign({}, DEFAULT_CONFIG.generalLimits, userConfig.generalLimits || {});
target.spanLimits = Object.assign({}, DEFAULT_CONFIG.spanLimits, userConfig.spanLimits || {});
return target;
}
/**
* When general limits are provided and model specific limits are not,
* configures the model specific limits by using the values from the general ones.
* @param userConfig User provided tracer configuration
*/
export function reconfigureLimits(userConfig) {
const spanLimits = Object.assign({}, userConfig.spanLimits);
/**
* Reassign span attribute count limit to use first non null value defined by user or use default value
*/
spanLimits.attributeCountLimit =
userConfig.spanLimits?.attributeCountLimit ??
userConfig.generalLimits?.attributeCountLimit ??
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT') ??
getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT') ??
DEFAULT_ATTRIBUTE_COUNT_LIMIT;
/**
* Reassign span attribute value length limit to use first non null value defined by user or use default value
*/
spanLimits.attributeValueLengthLimit =
userConfig.spanLimits?.attributeValueLengthLimit ??
userConfig.generalLimits?.attributeValueLengthLimit ??
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??
getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??
DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT;
return Object.assign({}, userConfig, { spanLimits });
}
//# sourceMappingURL=utility.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utility.js","sourceRoot":"","sources":["../../src/utility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AACjD,MAAM,CAAC,MAAM,oCAAoC,GAAG,QAAQ,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,UAAwB;IAKlD,MAAM,mBAAmB,GAA0B;QACjD,OAAO,EAAE,mBAAmB,EAAE;KAC/B,CAAC;IAEF,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAE3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAC1B,EAAE,EACF,cAAc,EACd,mBAAmB,EACnB,UAAU,CACX,CAAC;IAEF,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAClC,EAAE,EACF,cAAc,CAAC,aAAa,EAC5B,UAAU,CAAC,aAAa,IAAI,EAAE,CAC/B,CAAC;IAEF,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAC/B,EAAE,EACF,cAAc,CAAC,UAAU,EACzB,UAAU,CAAC,UAAU,IAAI,EAAE,CAC5B,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAwB;IACxD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAE5D;;OAEG;IACH,UAAU,CAAC,mBAAmB;QAC5B,UAAU,CAAC,UAAU,EAAE,mBAAmB;YAC1C,UAAU,CAAC,aAAa,EAAE,mBAAmB;YAC7C,gBAAgB,CAAC,iCAAiC,CAAC;YACnD,gBAAgB,CAAC,4BAA4B,CAAC;YAC9C,6BAA6B,CAAC;IAEhC;;OAEG;IACH,UAAU,CAAC,yBAAyB;QAClC,UAAU,CAAC,UAAU,EAAE,yBAAyB;YAChD,UAAU,CAAC,aAAa,EAAE,yBAAyB;YACnD,gBAAgB,CAAC,wCAAwC,CAAC;YAC1D,gBAAgB,CAAC,mCAAmC,CAAC;YACrD,oCAAoC,CAAC;IAEvC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACvD,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { buildSamplerFromEnv, loadDefaultConfig } from './config';\nimport type { Sampler } from './Sampler';\nimport type { SpanLimits, TracerConfig, GeneralLimits } from './types';\nimport { getNumberFromEnv } from '@opentelemetry/core';\n\nexport const DEFAULT_ATTRIBUTE_COUNT_LIMIT = 128;\nexport const DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT = Infinity;\n\n/**\n * Function to merge Default configuration (as specified in './config') with\n * user provided configurations.\n */\nexport function mergeConfig(userConfig: TracerConfig): TracerConfig & {\n sampler: Sampler;\n spanLimits: SpanLimits;\n generalLimits: GeneralLimits;\n} {\n const perInstanceDefaults: Partial<TracerConfig> = {\n sampler: buildSamplerFromEnv(),\n };\n\n const DEFAULT_CONFIG = loadDefaultConfig();\n\n const target = Object.assign(\n {},\n DEFAULT_CONFIG,\n perInstanceDefaults,\n userConfig\n );\n\n target.generalLimits = Object.assign(\n {},\n DEFAULT_CONFIG.generalLimits,\n userConfig.generalLimits || {}\n );\n\n target.spanLimits = Object.assign(\n {},\n DEFAULT_CONFIG.spanLimits,\n userConfig.spanLimits || {}\n );\n\n return target;\n}\n\n/**\n * When general limits are provided and model specific limits are not,\n * configures the model specific limits by using the values from the general ones.\n * @param userConfig User provided tracer configuration\n */\nexport function reconfigureLimits(userConfig: TracerConfig): TracerConfig {\n const spanLimits = Object.assign({}, userConfig.spanLimits);\n\n /**\n * Reassign span attribute count limit to use first non null value defined by user or use default value\n */\n spanLimits.attributeCountLimit =\n userConfig.spanLimits?.attributeCountLimit ??\n userConfig.generalLimits?.attributeCountLimit ??\n getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT') ??\n getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT') ??\n DEFAULT_ATTRIBUTE_COUNT_LIMIT;\n\n /**\n * Reassign span attribute value length limit to use first non null value defined by user or use default value\n */\n spanLimits.attributeValueLengthLimit =\n userConfig.spanLimits?.attributeValueLengthLimit ??\n userConfig.generalLimits?.attributeValueLengthLimit ??\n getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??\n getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??\n DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT;\n\n return Object.assign({}, userConfig, { spanLimits });\n}\n"]}

View File

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

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