@wavequery/conductor
Version:
Modular LLM orchestration framework
79 lines • 2.46 kB
JavaScript
export class MetricsCollector {
constructor(config = {}) {
this.metrics = [];
this.flushInterval = null;
this.config = {
flushInterval: 60000, // 1 minute
bufferSize: 1000,
onFlush: async (metrics) => {
console.log("Metrics flushed:", metrics);
},
...config,
};
this.startFlushInterval();
}
static getInstance(config) {
if (!MetricsCollector.instance) {
MetricsCollector.instance = new MetricsCollector(config);
}
return MetricsCollector.instance;
}
record(name, value, tags) {
const metric = {
name,
value,
timestamp: new Date(),
tags,
};
this.metrics.push(metric);
if (this.metrics.length >= this.config.bufferSize) {
this.flush();
}
}
startFlushInterval() {
if (this.flushInterval) {
clearInterval(this.flushInterval);
}
this.flushInterval = setInterval(() => {
this.flush();
}, this.config.flushInterval);
}
async flush() {
if (this.metrics.length === 0)
return;
const metricsToFlush = [...this.metrics];
this.metrics = [];
try {
await this.config.onFlush(metricsToFlush);
}
catch (error) {
// If flush fails, add metrics back to the buffer
this.metrics = [...metricsToFlush, ...this.metrics].slice(0, this.config.bufferSize);
throw error;
}
}
getMetrics() {
return [...this.metrics];
}
summarize(name, fromDate) {
const relevantMetrics = this.metrics
.filter((m) => m.name === name && (!fromDate || m.timestamp >= fromDate))
.map((m) => m.value);
if (relevantMetrics.length === 0) {
return { count: 0, sum: 0, avg: 0, min: 0, max: 0 };
}
return {
count: relevantMetrics.length,
sum: relevantMetrics.reduce((a, b) => a + b, 0),
avg: relevantMetrics.reduce((a, b) => a + b, 0) / relevantMetrics.length,
min: Math.min(...relevantMetrics),
max: Math.max(...relevantMetrics),
};
}
dispose() {
if (this.flushInterval) {
clearInterval(this.flushInterval);
}
}
}
//# sourceMappingURL=metrics-collector.js.map