UNPKG

llmxml

Version:

Convert between markdown and LLM-friendly pseudo-XML

111 lines (101 loc) 2.96 kB
import winston from 'winston'; import { EventEmitter } from 'events'; import type { Warning } from '../types'; /** * Event emitter for library-level events */ export const events = new EventEmitter(); /** * Custom transport that emits events for warnings */ class EventTransport extends winston.transports.Stream { constructor(opts?: any) { super({ stream: process.stdout, ...opts }); // @ts-ignore - winston types are incorrect, eol can be boolean this.eol = true; this.level = 'warn'; } log(info: any, callback: () => void) { setImmediate(() => { this.emit('logged', info); }); // Extract the message and metadata const { message, level, timestamp, ...meta } = info; // Emit the warning event with our format if (level === 'warn') { events.emit('warning', { code: meta.code || 'UNKNOWN_WARNING', message: message, details: meta } as Warning); } callback(); } } /** * Centralized logger for the LLMXML library * * In development: * - Logs to console with colors and simple format * * In production: * - Logs errors to error.log * - Logs all levels to combined.log * - Uses JSON format with timestamps * * Respects LLMXML options: * - When warningLevel is 'none', only errors are logged * - When verbose is false, initialization logs are suppressed */ const logger = winston.createLogger({ /** Set by LOG_LEVEL env var or defaults to 'info' */ level: process.env.LOG_LEVEL || 'info', /** Use JSON format with timestamps for structured logging */ format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ /** Console output with colors in development */ new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ), }), /** Event transport for warning events */ new EventTransport(), ], }); // Add file transports in production if (process.env.NODE_ENV === 'production') { /** Log errors to dedicated file */ logger.add( new winston.transports.File({ filename: 'error.log', level: 'error' }) ); /** Log all levels to combined file */ logger.add( new winston.transports.File({ filename: 'combined.log' }) ); } /** * Updates logger level based on LLMXML options * @param options Options from LLMXML instance */ export function configureLogger(options: { warningLevel?: 'all' | 'none' | 'ambiguous-only', verbose?: boolean } = {}) { // Set log level based on warningLevel if (options.warningLevel === 'none') { // When warningLevel is 'none', only log errors logger.level = 'error'; } else if (!options.verbose) { // When not verbose, don't show info logs logger.level = 'warn'; } else { // Default to info level logger.level = process.env.LOG_LEVEL || 'info'; } } export default logger;