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,41 @@
import { Context } from '@opentelemetry/api';
import { Span } from '../Span';
import { SpanProcessor } from '../SpanProcessor';
import { BufferConfig } from '../types';
import { ReadableSpan } from './ReadableSpan';
import { 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 _exporter;
private readonly _maxExportBatchSize;
private readonly _maxQueueSize;
private readonly _scheduledDelayMillis;
private readonly _exportTimeoutMillis;
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,210 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { context, diag, TraceFlags } from '@opentelemetry/api';
import { BindOnceFuture, ExportResultCode, getEnv, globalErrorHandler, suppressTracing, unrefTimer, } 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 {
constructor(_exporter, config) {
this._exporter = _exporter;
this._isExporting = false;
this._finishedSpans = [];
this._droppedSpansCount = 0;
const env = getEnv();
this._maxExportBatchSize =
typeof (config === null || config === void 0 ? void 0 : config.maxExportBatchSize) === 'number'
? config.maxExportBatchSize
: env.OTEL_BSP_MAX_EXPORT_BATCH_SIZE;
this._maxQueueSize =
typeof (config === null || config === void 0 ? void 0 : config.maxQueueSize) === 'number'
? config.maxQueueSize
: env.OTEL_BSP_MAX_QUEUE_SIZE;
this._scheduledDelayMillis =
typeof (config === null || config === void 0 ? void 0 : config.scheduledDelayMillis) === 'number'
? config.scheduledDelayMillis
: env.OTEL_BSP_SCHEDULE_DELAY;
this._exportTimeoutMillis =
typeof (config === null || config === void 0 ? void 0 : config.exportTimeoutMillis) === 'number'
? config.exportTimeoutMillis
: env.OTEL_BSP_EXPORT_TIMEOUT;
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 => {
var _a;
clearTimeout(timer);
if (result.code === ExportResultCode.SUCCESS) {
resolve();
}
else {
reject((_a = result.error) !== null && _a !== void 0 ? _a : 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 !== null && pendingResources !== void 0 ? pendingResources : (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);
unrefTimer(this._timer);
}
_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 { SpanExporter } from './SpanExporter';
import { ReadableSpan } from './ReadableSpan';
import { 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,85 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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) {
var _a;
return {
resource: {
attributes: span.resource.attributes,
},
instrumentationScope: span.instrumentationLibrary,
traceId: span.spanContext().traceId,
parentId: span.parentSpanId,
traceState: (_a = span.spanContext().traceState) === null || _a === void 0 ? void 0 : _a.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;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B;;;;;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,sBAAsB;YACjD,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO;YACnC,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,UAAU,EAAE,MAAA,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,0CAAE,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 *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SpanExporter } from './SpanExporter';\nimport { ReadableSpan } from './ReadableSpan';\nimport {\n ExportResult,\n ExportResultCode,\n hrTimeToMicroseconds,\n} 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.instrumentationLibrary,\n traceId: span.spanContext().traceId,\n parentId: span.parentSpanId,\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 { SpanExporter } from './SpanExporter';
import { ReadableSpan } from './ReadableSpan';
import { 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,58 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 {
constructor() {
this._finishedSpans = [];
/**
* Indicates if the exporter has been "shutdown."
* When false, exported spans will not be stored in-memory.
*/
this._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;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAgB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAErE;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAAjC;QACU,mBAAc,GAAmB,EAAE,CAAC;QAC5C;;;WAGG;QACO,aAAQ,GAAG,KAAK,CAAC;IAoC7B,CAAC;IAlCC,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 *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SpanExporter } from './SpanExporter';\nimport { ReadableSpan } from './ReadableSpan';\nimport { ExportResult, 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 { Context } from '@opentelemetry/api';
import { ReadableSpan } from './ReadableSpan';
import { Span } from '../Span';
import { 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,27 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** 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;;;;;;;;;;;;;;GAcG;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 *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Context } from '@opentelemetry/api';\nimport { ReadableSpan } from './ReadableSpan';\nimport { Span } from '../Span';\nimport { 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 { SpanKind, SpanStatus, SpanAttributes, HrTime, Link, SpanContext } from '@opentelemetry/api';
import { IResource } from '@opentelemetry/resources';
import { InstrumentationLibrary } from '@opentelemetry/core';
import { TimedEvent } from '../TimedEvent';
export interface ReadableSpan {
readonly name: string;
readonly kind: SpanKind;
readonly spanContext: () => SpanContext;
readonly parentSpanId?: string;
readonly startTime: HrTime;
readonly endTime: HrTime;
readonly status: SpanStatus;
readonly attributes: SpanAttributes;
readonly links: Link[];
readonly events: TimedEvent[];
readonly duration: HrTime;
readonly ended: boolean;
readonly resource: IResource;
readonly instrumentationLibrary: InstrumentationLibrary;
readonly droppedAttributesCount: number;
readonly droppedEventsCount: number;
readonly droppedLinksCount: number;
}
//# sourceMappingURL=ReadableSpan.d.ts.map

View File

@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};
//# sourceMappingURL=ReadableSpan.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ReadableSpan.js","sourceRoot":"","sources":["../../../src/export/ReadableSpan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SpanKind,\n SpanStatus,\n SpanAttributes,\n HrTime,\n Link,\n SpanContext,\n} from '@opentelemetry/api';\nimport { IResource } from '@opentelemetry/resources';\nimport { InstrumentationLibrary } from '@opentelemetry/core';\nimport { TimedEvent } from '../TimedEvent';\n\nexport interface ReadableSpan {\n readonly name: string;\n readonly kind: SpanKind;\n readonly spanContext: () => SpanContext;\n readonly parentSpanId?: string;\n readonly startTime: HrTime;\n readonly endTime: HrTime;\n readonly status: SpanStatus;\n readonly attributes: SpanAttributes;\n readonly links: Link[];\n readonly events: TimedEvent[];\n readonly duration: HrTime;\n readonly ended: boolean;\n readonly resource: IResource;\n readonly instrumentationLibrary: InstrumentationLibrary;\n readonly droppedAttributesCount: number;\n readonly droppedEventsCount: number;\n readonly droppedLinksCount: number;\n}\n"]}

View File

@@ -0,0 +1,25 @@
import { Context } from '@opentelemetry/api';
import { Span } from '../Span';
import { SpanProcessor } from '../SpanProcessor';
import { ReadableSpan } from './ReadableSpan';
import { 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 _unresolvedExports;
constructor(_exporter: SpanExporter);
forceFlush(): Promise<void>;
onStart(_span: Span, _parentContext: Context): void;
onEnd(span: ReadableSpan): void;
shutdown(): Promise<void>;
private _shutdown;
}
//# sourceMappingURL=SimpleSpanProcessor.d.ts.map

View File

@@ -0,0 +1,83 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 {
constructor(_exporter) {
this._exporter = _exporter;
this._shutdownOnce = new BindOnceFuture(this._shutdown, this);
this._unresolvedExports = new Set();
}
async forceFlush() {
// await unresolved resources before resolving
await Promise.all(Array.from(this._unresolvedExports));
if (this._exporter.forceFlush) {
await this._exporter.forceFlush();
}
}
onStart(_span, _parentContext) { }
onEnd(span) {
var _a, _b;
if (this._shutdownOnce.isCalled) {
return;
}
if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
return;
}
const doExport = () => internal
._export(this._exporter, [span])
.then((result) => {
var _a;
if (result.code !== ExportResultCode.SUCCESS) {
globalErrorHandler((_a = result.error) !== null && _a !== void 0 ? _a : new Error(`SimpleSpanProcessor: span export failed (status ${result})`));
}
})
.catch(error => {
globalErrorHandler(error);
});
// Avoid scheduling a promise to make the behavior more predictable and easier to test
if (span.resource.asyncAttributesPending) {
const exportPromise = (_b = (_a = span.resource).waitForAsyncAttributes) === null || _b === void 0 ? void 0 : _b.call(_a).then(() => {
if (exportPromise != null) {
this._unresolvedExports.delete(exportPromise);
}
return doExport();
}, err => globalErrorHandler(err));
// store the unresolved exports
if (exportPromise != null) {
this._unresolvedExports.add(exportPromise);
}
}
else {
void doExport();
}
}
shutdown() {
return this._shutdownOnce.call();
}
_shutdown() {
return this._exporter.shutdown();
}
}
//# sourceMappingURL=SimpleSpanProcessor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
import { ExportResult } from '@opentelemetry/core';
import { 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,17 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};
//# sourceMappingURL=SpanExporter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SpanExporter.js","sourceRoot":"","sources":["../../../src/export/SpanExporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ExportResult } from '@opentelemetry/core';\nimport { 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"]}