WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
117
src/metrics/index.ts
Normal file
117
src/metrics/index.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { InfluxDB, Point, WriteApi } from '@influxdata/influxdb-client';
|
||||
import { IMetricsProvider } from '../domain/interfaces.js';
|
||||
import { logger } from '../logging/index.js';
|
||||
|
||||
export class InfluxMetricsProvider implements IMetricsProvider {
|
||||
private writeApi: WriteApi | null = null;
|
||||
private influx: InfluxDB | null = null;
|
||||
|
||||
constructor(url: string, token: string, org: string, bucket: string) {
|
||||
try {
|
||||
this.influx = new InfluxDB({ url, token });
|
||||
this.writeApi = this.influx.getWriteApi(org, bucket, 'ms', {
|
||||
writeFailed(error) {
|
||||
logger.error('InfluxDB metrics point write failed', error);
|
||||
},
|
||||
});
|
||||
|
||||
logger.info('InfluxDB metrics provider initialized successfully');
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
'Failed to initialize InfluxDB metrics provider. System will run with degraded/no time-series metrics reporting.',
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private writePoint(point: Point): void {
|
||||
if (!this.writeApi) {
|
||||
logger.debug('InfluxDB write client not initialized, discarding point', {
|
||||
measurement: point.toLineProtocol(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.writeApi.writePoint(point);
|
||||
} catch (error) {
|
||||
logger.error('Error writing point to InfluxDB', error);
|
||||
}
|
||||
}
|
||||
|
||||
recordWalletDetectionLatency(latencyMs: number, wallet: string): void {
|
||||
const p = new Point('wallet_detection_latency')
|
||||
.tag('wallet', wallet)
|
||||
.floatField('latency_ms', latencyMs);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordSignalProcessingLatency(latencyMs: number): void {
|
||||
const p = new Point('signal_processing_latency').floatField('latency_ms', latencyMs);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordQuoteLatency(latencyMs: number, provider: string): void {
|
||||
const p = new Point('quote_latency').tag('provider', provider).floatField('latency_ms', latencyMs);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordExecutionLatency(latencyMs: number, scenario: number): void {
|
||||
const p = new Point('execution_latency')
|
||||
.tag('scenario', `${scenario}ms`)
|
||||
.floatField('latency_ms', latencyMs);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordPrice(tokenMint: string, priceSol: number): void {
|
||||
const p = new Point('token_price').tag('token_mint', tokenMint).floatField('price_sol', priceSol);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordPortfolioBalance(balanceSol: number, scenario: number): void {
|
||||
const p = new Point('portfolio_balance')
|
||||
.tag('scenario', `${scenario}ms`)
|
||||
.floatField('balance_sol', balanceSol);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordTradePnl(pnlSol: number, scenario: number, tokenMint: string): void {
|
||||
const p = new Point('trade_pnl')
|
||||
.tag('scenario', `${scenario}ms`)
|
||||
.tag('token_mint', tokenMint)
|
||||
.floatField('pnl_sol', pnlSol);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
recordExcursion(mfeSol: number, maeSol: number, scenario: number, tokenMint: string): void {
|
||||
const p = new Point('trade_excursion')
|
||||
.tag('scenario', `${scenario}ms`)
|
||||
.tag('token_mint', tokenMint)
|
||||
.floatField('mfe_sol', mfeSol)
|
||||
.floatField('mae_sol', maeSol);
|
||||
this.writePoint(p);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
if (this.writeApi) {
|
||||
logger.info('Closing InfluxDB metrics writer...');
|
||||
try {
|
||||
await this.writeApi.close();
|
||||
logger.info('InfluxDB metrics writer closed.');
|
||||
} catch (error) {
|
||||
logger.error('Error closing InfluxDB metrics writer', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In-Memory/Mock Metrics Provider for local tests and offline dev
|
||||
export class MockMetricsProvider implements IMetricsProvider {
|
||||
recordWalletDetectionLatency(_latencyMs: number, _wallet: string): void {}
|
||||
recordSignalProcessingLatency(_latencyMs: number): void {}
|
||||
recordQuoteLatency(_latencyMs: number, _provider: string): void {}
|
||||
recordExecutionLatency(_latencyMs: number, _scenario: number): void {}
|
||||
recordPrice(_tokenMint: string, _priceSol: number): void {}
|
||||
recordPortfolioBalance(_balanceSol: number, _scenario: number): void {}
|
||||
recordTradePnl(_pnlSol: number, _scenario: number, _tokenMint: string): void {}
|
||||
recordExcursion(_mfeSol: number, _maeSol: number, _scenario: number, _tokenMint: string): void {}
|
||||
}
|
||||
Reference in New Issue
Block a user