98e40dac97
CLI Smoke Test / smoke-test-linux (20) (push) Has been cancelled
CLI Smoke Test / smoke-test-linux (24) (push) Has been cancelled
CLI Smoke Test / smoke-test-windows (20) (push) Has been cancelled
CLI Smoke Test / smoke-test-windows (24) (push) Has been cancelled
Expo App TypeScript typecheck / typecheck (push) Has been cancelled
103 lines
3.9 KiB
TypeScript
103 lines
3.9 KiB
TypeScript
import pino from 'pino';
|
|
import pretty from 'pino-pretty';
|
|
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}`;
|
|
}
|
|
|
|
// IMPORTANT: do NOT use pino's `transport` option here.
|
|
//
|
|
// pino transports run the target (pino-pretty, pino/file) in a worker_thread,
|
|
// which resolves the module from a real path on disk. happy-server ships as a
|
|
// single-file `bun build --compile` binary (see happy-cli `happy server`); inside
|
|
// Bun's virtual $bunfs there is no node_modules/pino-pretty for the worker to
|
|
// load, so the threaded transport crashes at startup.
|
|
//
|
|
// Synchronous in-process streams (pino-pretty as a stream + pino.destination,
|
|
// composed with pino.multistream) need no worker and no on-disk resolution, so
|
|
// they work identically whether bundled or run from source.
|
|
const prettyStream = pretty({
|
|
colorize: true,
|
|
translateTime: 'HH:MM:ss.l',
|
|
ignore: 'pid,hostname',
|
|
messageFormat: '{levelLabel} {msg} | [{time}]',
|
|
errorLikeObjectKeys: ['err', 'error'],
|
|
});
|
|
|
|
const loggerStreams: pino.StreamEntry[] = [{ level: 'debug', stream: prettyStream }];
|
|
|
|
if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && consolidatedLogFile) {
|
|
loggerStreams.push({
|
|
level: 'debug',
|
|
stream: pino.destination({ dest: consolidatedLogFile, mkdir: true }),
|
|
});
|
|
}
|
|
|
|
// Shared core options: both loggers add localTime to every entry and emit the
|
|
// same timestamp shape. Stream selection (pretty/file) is layered on top.
|
|
const baseOptions = {
|
|
level: 'debug',
|
|
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()}"`,
|
|
} satisfies pino.LoggerOptions;
|
|
|
|
// Main server logger with local time formatting
|
|
export const logger = pino(baseOptions, pino.multistream(loggerStreams));
|
|
|
|
// 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(baseOptions, pino.destination({ dest: consolidatedLogFile, mkdir: true })) : 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);
|
|
}
|