You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.9 KiB

import type {
LingInstance,
LingString
} from '@/ling/lib';
import type {
LogrOptions,
LogEntry,
MessageCategory,
LogFilters,
Logr,
Transport
} from './types.ts';
import { LogLevel } from './types.ts';
import { consoleTransport } from './transports.ts';
// ============================================================================
// ENGINE
// ============================================================================
/**
* Crea una instancia de `Logr` vinculada a una instancia de i18n.
*
* El logger no gestiona el locale internamente — lo delega al sistema i18n.
* Cuando cambia el locale en i18n, los mensajes siguientes se resuelven
* automáticamente al nuevo locale sin ninguna reconfiguración.
*
* Cada entrada se emite a todos los transports registrados.
* Si no se especifican transports, usa `consoleTransport()` por defecto.
*
* @param ling - Instancia de i18n para resolución de mensajes localizados
* @param options - Configuración de nivel, historial y transports
*
* @example
* export const logr = createLogr(i18n, {
* level : LogLevel.WARN,
* transports: [
* consoleTransport(),
* httpTransport({ url: 'https://logs.myapp.com', level: LogLevel.ERROR }),
* ]
* });
*/
export function createLogr(ling: LingInstance, options: LogrOptions = {}): Logr {
let level : LogLevel = options.level ?? LogLevel.WARN;
let maxLogs : number = options.maxLogs ?? 1000;
let transports : Transport[] = options.transports ?? [consoleTransport()];
let entries : LogEntry[] = [];
// -------------------------------------------------------------------------
// Configuración
// -------------------------------------------------------------------------
function setLevel(l: LogLevel): void {
level = l;
}
function setMaxLogs(max: number): void {
maxLogs = max;
}
// -------------------------------------------------------------------------
// Core interno
// -------------------------------------------------------------------------
/**
* Centraliza el procesamiento de todos los niveles.
* Aplica el filtro de nivel, construye la entrada, gestiona el historial
* y emite a todos los transports.
*/
function log(
lvl : LogLevel,
category: MessageCategory,
message : LingString,
context?: Record<string, unknown>
): void {
if (lvl < level) return;
const entry: LogEntry = {
timestamp: new Date(),
level : lvl,
category,
message,
context,
};
// Historial en memoria
entries.push(entry);
if (entries.length > maxLogs) entries.shift();
// Resuelve el mensaje una sola vez y lo emite a todos los transports
const resolvedMessage = ling.ts(entry.message);
transports.forEach(t => t.write(entry, resolvedMessage));
}
// -------------------------------------------------------------------------
// API pública
// -------------------------------------------------------------------------
function debug(category: MessageCategory, message: LingString, context?: Record<string, unknown>): void {
log(LogLevel.DEBUG, category, message, context);
}
function info(category: MessageCategory, message: LingString, context?: Record<string, unknown>): void {
log(LogLevel.INFO, category, message, context);
}
function warn(category: MessageCategory, message: LingString, context?: Record<string, unknown>): void {
log(LogLevel.WARN, category, message, context);
}
function error(category: MessageCategory, message: LingString, context?: Record<string, unknown>): void {
log(LogLevel.ERROR, category, message, context);
}
function getLogs(filters?: LogFilters): LogEntry[] {
let result = entries;
if (filters?.level !== undefined) result = result.filter(e => e.level === filters.level);
if (filters?.category !== undefined) result = result.filter(e => e.category === filters.category);
if (filters?.since !== undefined) result = result.filter(e => e.timestamp >= filters.since!);
return result;
}
function clear(): void {
entries = [];
}
/**
* Los mensajes se resuelven al locale activo en el momento
* de llamar a serialization(), no al momento en que se registraron.
*/
function serialize(): string {
return JSON.stringify(
entries.map(e => ({
...e,
message : ling.ts(e.message),
locale : ling.getLocale(),
timestamp: e.timestamp.toISOString(),
})),
null,
2
);
}
return { debug, info, warn, error, getLogs, clear, serialize, setLevel, setMaxLogs };
}

Powered by TurnKey Linux.