happy-server/sources/utils/log.ts
2025-08-15 19:13:45 -07:00

118 lines
3.8 KiB
TypeScript

import pino from 'pino';
import { mkdirSync } from 'fs';
import { join } from 'path';
// Single log file name created once at startup
let consolidatedLogFile: string | undefined;
if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING) {
const logsDir = join(process.cwd(), '.logs');
try {
mkdirSync(logsDir, { recursive: true });
// Create filename once at startup
const now = new Date();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hour = String(now.getHours()).padStart(2, '0');
const min = String(now.getMinutes()).padStart(2, '0');
const sec = String(now.getSeconds()).padStart(2, '0');
consolidatedLogFile = join(logsDir, `${month}-${day}-${hour}-${min}-${sec}.log`);
console.log(`[PINO] Remote debugging logs enabled - writing to ${consolidatedLogFile}`);
} catch (error) {
console.error('Failed to create logs directory:', error);
}
}
// Format time as HH:MM:ss.mmm in local time
function formatLocalTime(timestamp?: number) {
const date = timestamp ? new Date(timestamp) : new Date();
const hours = String(date.getHours()).padStart(2, '0');
const mins = String(date.getMinutes()).padStart(2, '0');
const secs = String(date.getSeconds()).padStart(2, '0');
const ms = String(date.getMilliseconds()).padStart(3, '0');
return `${hours}:${mins}:${secs}.${ms}`;
}
const transports: any[] = [];
transports.push({
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss.l',
ignore: 'pid,hostname',
messageFormat: '{levelLabel} {msg} | [{time}]',
errorLikeObjectKeys: ['err', 'error'],
},
});
if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && consolidatedLogFile) {
transports.push({
target: 'pino/file',
options: {
destination: consolidatedLogFile,
mkdir: true,
messageFormat: '{levelLabel} {msg} | [server time: {time}]',
},
});
}
// Main server logger with local time formatting
export const logger = pino({
level: 'debug',
transport: {
targets: transports,
},
formatters: {
log: (object: any) => {
// Add localTime to every log entry
return {
...object,
localTime: formatLocalTime(typeof object.time === 'number' ? object.time : undefined),
};
}
},
timestamp: () => `,"time":${Date.now()},"localTime":"${formatLocalTime()}"`,
});
// Optional file-only logger for remote logs from CLI/mobile
export const fileConsolidatedLogger = process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && consolidatedLogFile ?
pino({
level: 'debug',
transport: {
targets: [{
target: 'pino/file',
options: {
destination: consolidatedLogFile,
mkdir: true,
},
}],
},
formatters: {
log: (object: any) => {
// Add localTime to every log entry
// Note: source property already exists from CLI/mobile logs
return {
...object,
localTime: formatLocalTime(typeof object.time === 'number' ? object.time : undefined),
};
}
},
timestamp: () => `,"time":${Date.now()},"localTime":"${formatLocalTime()}"`,
}) : undefined;
export function log(src: any, ...args: any[]) {
logger.info(src, ...args);
}
export function warn(src: any, ...args: any[]) {
logger.warn(src, ...args);
}
export function error(src: any, ...args: any[]) {
logger.error(src, ...args);
}
export function debug(src: any, ...args: any[]) {
logger.debug(src, ...args);
}