# 01 — Trazas de Log y Centralización ## Estándar obligatorio de logging para Server Components, Client Components y API Routes > **Uso:** Todo flujo, acción crítica del usuario (login, logout, accesos denegados) o error de integración DEBE registrar un log con el formato estándar del proyecto. --- ## 1. Arquitectura de Logs de Frontend La aplicación utiliza un sistema centralizado de logs que asegura que todas las trazas (tanto del cliente como del servidor) queden consolidadas en el servidor en el archivo `logs/app.log`. ``` [Client Component] (use client) │ (llama a client-logger) ▼ POST /api/logs │ ▼ [Route Handler] (app/api/logs/route.ts) │ ▼ [Server Logger] (lib/logger/server-logger.ts) ──► Escribe en logs/app.log ▲ │ (llamada directa) [Server Component / API Route] ``` --- ## 2. Formato de las Trazas El formato estándar del log es una sola línea estructurada para facilitar búsquedas y parseos: ``` [] [] | ``` ### Niveles Aceptados: - **`[INFO]`**: Acciones exitosas y flujos de negocio normales (ej. Login exitoso, Logout). - **`[WARN]`**: Acciones sospechosas, intentos fallidos o no autorizados (ej. Login fallido, Acceso denegado a dashboard). - **`[ERROR]`**: Fallos técnicos críticos, excepciones de red o integración (ej. Backend Spring Boot caído, fallo de descompresión). --- ## 3. Uso Práctico ### 3.1 Desde Server Components y API Route Handlers En el servidor, importamos y llamamos directamente al `server-logger`: ```typescript import { logInfo, logWarn, logError } from '@/lib/logger/server-logger'; // Registro de flujo regular (INFO) logInfo('Usuario inició sesión exitosamente', { userId: '123', email: 'juan@banesco.com' }); // Intento de acceso fallido (WARN) logWarn('Acceso no autorizado a dashboard', { redirectTo: '/login', path: '/dashboard' }); // Fallo de backend (ERROR) logError('Error al conectar con el backend de Spring Boot', { error: 'ECONNREFUSED', endpoint: '/api/auth/me' }); ``` ### 3.2 Desde Client Components ('use client') En el cliente, importamos `client-logger` que se encarga asíncronamente de enviar la traza al backend local mediante `POST /api/logs`: ```typescript 'use client'; import { logInfo, logWarn, logError } from '@/lib/logger/client-logger'; function FormularioTransferencia() { const handleConfirmar = () => { // Logueamos la acción en el cliente (viajará al servidor automáticamente) logInfo('Click en confirmar transferencia', { monto: 1500, moneda: 'USD' }); }; const handleValidacionFallida = () => { logWarn('Validación de saldo insuficiente en cliente', { saldoDisponible: 200, montoRequerido: 1500 }); }; return ( // ... JSX ); } ``` --- ## 4. Estructura de la API Route de Logs (`app/api/logs/route.ts`) La API `/api/logs` es el proxy encargado de recibir los logs del cliente. Debe validar que la petición no esté vacía y pasarla inmediatamente al `server-logger`: ```typescript import { NextRequest, NextResponse } from 'next/server'; import { logInfo, logWarn, logError } from '@/lib/logger/server-logger'; export async function POST(req: NextRequest) { try { const { level, message, metadata } = await req.json(); switch (level.toUpperCase()) { case 'INFO': logInfo(message, metadata); break; case 'WARN': logWarn(message, metadata); break; case 'ERROR': logError(message, metadata); break; default: logInfo(`[CLIENT-LOG] ${message}`, metadata); } return NextResponse.json({ status: 'success' }, { status: 200 }); } catch (err: any) { return NextResponse.json({ error: 'Fallo al procesar logs en el proxy' }, { status: 500 }); } } ``` --- ## 5. Reglas de Seguridad en Logs - **NUNCA** guardes contraseñas de usuario, tokens JWT, llaves secretas o números de tarjeta de crédito (PAN) completos en los logs. - Aplica mascarado de datos sensibles en el metadata (ej. `{"email": "ju***@banesco.com"}`).