@dexwox-labs/a2a-core
Version:
Core types, validation and telemetry for Google's Agent-to-Agent (A2A) protocol - shared foundation for client and server implementations
126 lines • 3.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelemetryService = void 0;
const api_1 = require("@opentelemetry/api");
const config_1 = require("./config");
/**
* Telemetry service for collecting and exporting metrics and traces
*/
class TelemetryService {
static instance;
config;
meter;
resource = {};
isInitialized = false;
constructor(config = {}) {
this.config = { ...config_1.DEFAULT_TELEMETRY_CONFIG, ...config };
this.resource = {
'service.name': this.config.serviceName,
'service.version': this.config.serviceVersion,
...this.config.attributes,
};
this.meter = api_1.metrics.getMeter(this.config.serviceName, this.config.serviceVersion);
}
/**
* Initialize the telemetry service
*/
static initialize(config = {}) {
// Always create a new instance if one doesn't exist
if (!TelemetryService.instance) {
TelemetryService.instance = new TelemetryService(config);
TelemetryService.instance.isInitialized = true;
}
else if (config.enabled !== undefined) {
// If instance exists but config has explicit enabled flag, update it
TelemetryService.instance.updateConfig({ enabled: config.enabled });
}
return TelemetryService.instance;
}
/**
* Get the singleton instance of the telemetry service
*/
static getInstance() {
if (!TelemetryService.instance) {
return TelemetryService.initialize();
}
return TelemetryService.instance;
}
/**
* Check if telemetry is enabled
*/
isEnabled() {
return this.isInitialized &&
this.config.enabled !== false &&
this.config.collectionLevel !== 'off';
}
/**
* Create a new span
*/
startSpan(name, parentContext) {
if (!this.isEnabled()) {
return {
span: {
end: () => { },
setStatus: () => { },
recordException: () => { }
},
ctx: api_1.context.active()
};
}
const tracer = api_1.trace.getTracer(this.config.serviceName, this.config.serviceVersion);
const ctx = parentContext || api_1.context.active();
const span = tracer.startSpan(name, undefined, ctx);
const spanContext = api_1.trace.setSpan(ctx, span);
// Store the span in the context
return { span, ctx: spanContext };
}
/**
* End a span
*/
endSpan(span, error) {
if (!span || !this.isEnabled())
return;
if (error) {
span.recordException(error);
span.setStatus({ code: 2, message: error.message }); // ERROR status
}
else {
span.setStatus({ code: 1 }); // OK status
}
span.end();
}
/**
* Record a metric
*/
recordMetric(name, value, attributes) {
if (!this.isEnabled())
return;
const counter = this.meter.createCounter(name);
counter.add(value, attributes);
}
/**
* Record a duration metric
*/
recordDuration(name, startTime, attributes) {
if (!this.isEnabled())
return;
const duration = Date.now() - startTime;
const histogram = this.meter.createHistogram(name);
histogram.record(duration, attributes);
}
/**
* Update the configuration
*/
updateConfig(config) {
this.config = { ...this.config, ...config };
}
/**
* Shutdown the telemetry service
*/
async shutdown() {
// TODO: Implement proper shutdown logic when we have exporters
this.isInitialized = false;
}
}
exports.TelemetryService = TelemetryService;
//# sourceMappingURL=service.js.map