mirror of
https://github.com/mortdeus/legacy-cc.git
synced 2026-10-08 03:42:05 +00:00
175 lines
4.3 KiB
JavaScript
175 lines
4.3 KiB
JavaScript
|
|
import winston from 'winston';
|
|||
|
|
import DailyRotateFile from 'winston-daily-rotate-file';
|
|||
|
|
import chalk from 'chalk';
|
|||
|
|
import { config } from '../config.js';
|
|||
|
|
|
|||
|
|
// Custom format for console output
|
|||
|
|
const consoleFormat = winston.format.combine(
|
|||
|
|
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
|||
|
|
winston.format.printf(({ timestamp, level, message, ...meta }) => {
|
|||
|
|
const levelColors = {
|
|||
|
|
error: chalk.red,
|
|||
|
|
warn: chalk.yellow,
|
|||
|
|
info: chalk.blue,
|
|||
|
|
debug: chalk.gray,
|
|||
|
|
success: chalk.green,
|
|||
|
|
trade: chalk.cyan,
|
|||
|
|
profit: chalk.green,
|
|||
|
|
loss: chalk.red,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const levelIcon = {
|
|||
|
|
error: '❌',
|
|||
|
|
warn: '⚠️',
|
|||
|
|
info: 'ℹ️',
|
|||
|
|
debug: '🔍',
|
|||
|
|
success: '✅',
|
|||
|
|
trade: '💰',
|
|||
|
|
profit: '📈',
|
|||
|
|
loss: '📉',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const color = levelColors[level] || chalk.white;
|
|||
|
|
const icon = levelIcon[level] || '📝';
|
|||
|
|
|
|||
|
|
return `${chalk.gray(timestamp)} ${icon} ${color(level.toUpperCase())}: ${message}`;
|
|||
|
|
})
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// File format for logging to files
|
|||
|
|
const fileFormat = winston.format.combine(
|
|||
|
|
winston.format.timestamp(),
|
|||
|
|
winston.format.errors({ stack: true }),
|
|||
|
|
winston.format.json()
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// Create logger instance
|
|||
|
|
const logger = winston.createLogger({
|
|||
|
|
level: config.logging.level,
|
|||
|
|
format: fileFormat,
|
|||
|
|
defaultMeta: { service: 'solana-trading-bot' },
|
|||
|
|
transports: [
|
|||
|
|
// Daily rotate file transport
|
|||
|
|
new DailyRotateFile({
|
|||
|
|
filename: config.logging.logFilePath.replace('.log', '-%DATE%.log'),
|
|||
|
|
datePattern: 'YYYY-MM-DD',
|
|||
|
|
zippedArchive: true,
|
|||
|
|
maxSize: '20m',
|
|||
|
|
maxFiles: '14d',
|
|||
|
|
level: 'info',
|
|||
|
|
}),
|
|||
|
|
|
|||
|
|
// Error log file
|
|||
|
|
new DailyRotateFile({
|
|||
|
|
filename: config.logging.logFilePath.replace('.log', '-error-%DATE%.log'),
|
|||
|
|
datePattern: 'YYYY-MM-DD',
|
|||
|
|
zippedArchive: true,
|
|||
|
|
maxSize: '20m',
|
|||
|
|
maxFiles: '30d',
|
|||
|
|
level: 'error',
|
|||
|
|
}),
|
|||
|
|
],
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Add console transport if not in production
|
|||
|
|
if (config.logging.debug || process.env.NODE_ENV !== 'production') {
|
|||
|
|
logger.add(new winston.transports.Console({
|
|||
|
|
format: consoleFormat,
|
|||
|
|
level: config.logging.debug ? 'debug' : 'info',
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Custom logging methods
|
|||
|
|
export const logTrade = (message, meta = {}) => {
|
|||
|
|
logger.log('trade', message, meta);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const logProfit = (message, meta = {}) => {
|
|||
|
|
logger.log('profit', message, meta);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const logLoss = (message, meta = {}) => {
|
|||
|
|
logger.log('loss', message, meta);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const logSuccess = (message, meta = {}) => {
|
|||
|
|
logger.log('success', message, meta);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Performance logging
|
|||
|
|
export const logPerformance = (operation, duration, meta = {}) => {
|
|||
|
|
logger.info(`Performance: ${operation} took ${duration}ms`, {
|
|||
|
|
operation,
|
|||
|
|
duration,
|
|||
|
|
...meta,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Trade execution logging
|
|||
|
|
export const logTradeExecution = (tradeType, tokenMint, amount, price, meta = {}) => {
|
|||
|
|
logger.info(`Trade Execution: ${tradeType} ${tokenMint}`, {
|
|||
|
|
tradeType,
|
|||
|
|
tokenMint,
|
|||
|
|
amount,
|
|||
|
|
price,
|
|||
|
|
timestamp: new Date().toISOString(),
|
|||
|
|
...meta,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Error logging with context
|
|||
|
|
export const logError = (error, context = '', meta = {}) => {
|
|||
|
|
logger.error(`Error in ${context}: ${error.message}`, {
|
|||
|
|
error: error.stack,
|
|||
|
|
context,
|
|||
|
|
timestamp: new Date().toISOString(),
|
|||
|
|
...meta,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Wallet balance logging
|
|||
|
|
export const logBalance = (balance, token = 'SOL') => {
|
|||
|
|
logger.info(`Wallet Balance: ${balance} ${token}`);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Position logging
|
|||
|
|
export const logPosition = (action, mint, details, meta = {}) => {
|
|||
|
|
logger.info(`Position ${action}: ${mint}`, {
|
|||
|
|
action,
|
|||
|
|
mint,
|
|||
|
|
details,
|
|||
|
|
timestamp: new Date().toISOString(),
|
|||
|
|
...meta,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Configuration logging
|
|||
|
|
export const logConfig = (configSection, values) => {
|
|||
|
|
logger.debug(`Configuration ${configSection}:`, values);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// API request logging
|
|||
|
|
export const logApiRequest = (method, endpoint, params = {}) => {
|
|||
|
|
logger.debug(`API Request: ${method} ${endpoint}`, {
|
|||
|
|
method,
|
|||
|
|
endpoint,
|
|||
|
|
params,
|
|||
|
|
timestamp: new Date().toISOString(),
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// API response logging
|
|||
|
|
export const logApiResponse = (method, endpoint, status, duration, meta = {}) => {
|
|||
|
|
logger.debug(`API Response: ${method} ${endpoint}`, {
|
|||
|
|
method,
|
|||
|
|
endpoint,
|
|||
|
|
status,
|
|||
|
|
duration,
|
|||
|
|
timestamp: new Date().toISOString(),
|
|||
|
|
...meta,
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Export the main logger
|
|||
|
|
export default logger;
|