fixed all libs to be buildiable and dependency hell from removing some
This commit is contained in:
parent
5c64b1ccf8
commit
a282dac6cd
40 changed files with 4050 additions and 8219 deletions
|
|
@ -1,3 +1,2 @@
|
|||
export * from './dateUtils';
|
||||
export * from './logger';
|
||||
export * from './calculations/index';
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/**
|
||||
* Logger utility with consistent formatting and log levels
|
||||
* Supports console and Loki logging
|
||||
*/
|
||||
import { loggingConfig, lokiConfig } from '@stock-bot/config';
|
||||
|
||||
// Singleton Loki client
|
||||
let lokiClient: LokiClient | null = null;
|
||||
|
||||
function getLokiClient(): LokiClient {
|
||||
if (!lokiClient) {
|
||||
lokiClient = new LokiClient();
|
||||
}
|
||||
return lokiClient;
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
constructor(private serviceName: string, private level: LogLevel = LogLevel.INFO) {}
|
||||
|
||||
debug(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.DEBUG, message, ...args);
|
||||
}
|
||||
|
||||
info(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.INFO, message, ...args);
|
||||
}
|
||||
|
||||
warn(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.WARN, message, ...args);
|
||||
}
|
||||
|
||||
error(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.ERROR, message, ...args);
|
||||
}
|
||||
|
||||
private log(level: LogLevel, message: string, ...args: any[]): void {
|
||||
if (level < this.level) return;
|
||||
|
||||
const timestamp = new Date().toISOString();
|
||||
const levelStr = LogLevel[level].padEnd(5);
|
||||
|
||||
const formattedArgs = args.length ? this.formatArgs(args) : '';
|
||||
const fullMessage = `${message}${formattedArgs}`;
|
||||
const logMessage = `[${timestamp}] [${levelStr}] [${this.serviceName}] ${fullMessage}`;
|
||||
|
||||
// Console logging
|
||||
if (loggingConfig.LOG_CONSOLE) {
|
||||
switch (level) {
|
||||
case LogLevel.ERROR:
|
||||
console.error(logMessage);
|
||||
break;
|
||||
case LogLevel.WARN:
|
||||
console.warn(logMessage);
|
||||
break;
|
||||
case LogLevel.INFO:
|
||||
console.info(logMessage);
|
||||
break;
|
||||
case LogLevel.DEBUG:
|
||||
default:
|
||||
console.debug(logMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Loki logging
|
||||
try {
|
||||
const loki = getLokiClient();
|
||||
loki.log(LogLevel[level].toLowerCase(), fullMessage, this.serviceName);
|
||||
} catch (error) {
|
||||
console.error('Failed to send log to Loki:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private formatArgs(args: any[]): string {
|
||||
try {
|
||||
return args.map(arg => {
|
||||
if (arg instanceof Error) {
|
||||
return ` ${arg.message}\n${arg.stack}`;
|
||||
} else if (typeof arg === 'object') {
|
||||
return ` ${JSON.stringify(arg)}`;
|
||||
} else {
|
||||
return ` ${arg}`;
|
||||
}
|
||||
}).join('');
|
||||
} catch (error) {
|
||||
return ` [Error formatting log arguments: ${error}]`;
|
||||
}
|
||||
}
|
||||
|
||||
setLevel(level: LogLevel): void {
|
||||
this.level = level;
|
||||
}
|
||||
}
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
WARN = 2,
|
||||
ERROR = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new logger instance
|
||||
*/
|
||||
export function createLogger(serviceName: string, level: LogLevel = LogLevel.INFO): Logger {
|
||||
return new Logger(serviceName, level);
|
||||
}
|
||||
|
||||
export class LokiClient {
|
||||
private batchQueue: any[] = [];
|
||||
private flushInterval: NodeJS.Timeout;
|
||||
private lokiUrl: string;
|
||||
private authHeader?: string;
|
||||
|
||||
constructor() {
|
||||
const { LOKI_HOST, LOKI_PORT, LOKI_USERNAME, LOKI_PASSWORD } = lokiConfig;
|
||||
|
||||
this.lokiUrl = `http://${LOKI_HOST}:${LOKI_PORT}/loki/api/v1/push`;
|
||||
|
||||
if (LOKI_USERNAME && LOKI_PASSWORD) {
|
||||
const authString = Buffer.from(`${LOKI_USERNAME}:${LOKI_PASSWORD}`).toString('base64');
|
||||
this.authHeader = `Basic ${authString}`;
|
||||
}
|
||||
|
||||
this.flushInterval = setInterval(
|
||||
() => this.flush(),
|
||||
lokiConfig.LOKI_FLUSH_INTERVAL_MS || 1000 // Default to 1 second if not set
|
||||
);
|
||||
}
|
||||
|
||||
async log(level: string, message: string, serviceName: string, labels: Record<string, string> = {}) {
|
||||
const timestamp = Date.now() * 1000000; // Loki expects nanoseconds
|
||||
|
||||
this.batchQueue.push({
|
||||
streams: [{
|
||||
stream: {
|
||||
level,
|
||||
service: serviceName,
|
||||
...lokiConfig.LOKI_DEFAULT_LABELS ? JSON.parse(lokiConfig.LOKI_DEFAULT_LABELS) : {},
|
||||
...labels,
|
||||
},
|
||||
values: [[`${timestamp}`, message]],
|
||||
}],
|
||||
});
|
||||
|
||||
if (this.batchQueue.length >= lokiConfig.LOKI_BATCH_SIZE) {
|
||||
await this.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private async flush() {
|
||||
if (this.batchQueue.length === 0) return;
|
||||
|
||||
try {
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
|
||||
if (this.authHeader) {
|
||||
headers['Authorization'] = this.authHeader;
|
||||
}
|
||||
|
||||
const response = await fetch(this.lokiUrl, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
streams: this.batchQueue.flatMap(batch => batch.streams),
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`Failed to send logs to Loki: ${response.status} ${response.statusText}`);
|
||||
const text = await response.text();
|
||||
if (text) {
|
||||
console.error(text);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error sending logs to Loki:', error);
|
||||
} finally {
|
||||
this.batchQueue = [];
|
||||
}
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
clearInterval(this.flushInterval);
|
||||
return this.flush();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue