CodeGym /Cursos /JAVA 25 SELF /Fundamentos del registro (logging): java.util.logging, Lo...

Fundamentos del registro (logging): java.util.logging, Log4j, SLF4J

JAVA 25 SELF
Nivel 63, Lección 0
Disponible

1. Por qué hace falta el logging

El logging ≠ la salida por consola

Cuando empiezas a programar, parece que para buscar problemas basta con meter por todas partes System.out.println("¡He estado aquí!"). Esto funciona mientras el programa sea pequeño y lo ejecutes en tu ordenador. Pero imagina un proyecto grande, un servidor que funciona 24/7, o una aplicación que usan miles de personas — no te vas a sentar detrás de cada usuario mirando su consola, ¿verdad?

El logging no es solo imprimir mensajes. Es el registro sistemático de información sobre el funcionamiento de una aplicación: errores, advertencias, eventos de negocio, detalles técnicos. Los logs se guardan en archivos, bases de datos, pueden enviarse por la red — y permiten analizar cómo funciona el programa después de su ejecución o incluso en el propio proceso.

Para qué sirven los logs

  • Diagnóstico de problemas: si algo sale mal, los logs son tu principal aliado. Con ellos puedes entender dónde y por qué se produjo el error.
  • Auditoría y seguridad: los logs registran acciones importantes de los usuarios, lo que ayuda a investigar incidentes.
  • Depuración: a veces los bugs solo aparecen en condiciones concretas y sin logs es imposible cazarlos.
  • Monitorización: mediante los logs puedes seguir el estado de la aplicación, su rendimiento y su «salud».

Ejemplo de la vida real

Si los aviones no tuvieran «cajas negras» (logs de vuelo), investigar las causas de los accidentes sería casi imposible. En programación, los logs son tus cajas negras.

2. Niveles básicos de logging

En logging es habitual usar niveles (levels) de mensajes. Es como un semáforo: rojo — peligro, amarillo — precaución, verde — todo bien.

Niveles principales (del más «ruidoso» al más «silencioso»):

Nivel Descripción
ERROR
Error crítico, la aplicación no puede continuar
WARN
Advertencia: algo ha ido mal, pero la aplicación sigue funcionando
INFO
Mensaje informativo sobre eventos normales
DEBUG
Información detallada para depuración (visible solo para desarrolladores)
TRACE
La información más detallada — para un diagnóstico profundo

Ejemplo:

  • Un usuario no pudo iniciar sesión por una contraseña incorrecta — es WARN.
  • Se cayó la base de datos — es ERROR.
  • La aplicación se ha iniciado — es INFO.
  • Imprimir el valor de una variable en un bucle — es DEBUG o TRACE.

Cómo elegir el nivel

No conviene escribirlo todo en nivel ERROR — de lo contrario te ahogarás entre los errores reales. Usa los niveles con cabeza: solo los fallos realmente críticos deberían ser errores.

3. Logging estándar en Java (java.util.logging)

Java viene con un sistema de logging integrado — el paquete java.util.logging (abreviado JUL). Es la herramienta «nativa» que siempre está, incluso si no has añadido ninguna biblioteca.

Clases principales:

  • Logger — la clase principal para escribir logs.
  • Level — enumeración de niveles de logging (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST).
  • Handler — manejador que indica adónde escribir los logs (archivo, consola, etc.).
  • Formatter — responsable del formato de los mensajes.

Ejemplo de uso de JUL

import java.util.logging.Logger;
import java.util.logging.Level;

public class LoggingExample {
    // Obtenemos el logger por el nombre de la clase
    private static final Logger logger = Logger.getLogger(LoggingExample.class.getName());

    public static void main(String[] args) {
        logger.info("La aplicación se ha iniciado");
        logger.warning("¡Esto es una advertencia!");
        logger.severe("¡Y esto ya es un error!");

        int x = 42;
        logger.fine("Variable de depuración x=" + x); // No se muestra por defecto
    }
}

Punto importante: por defecto JUL muestra solo los niveles INFO y superiores. Para ver fine y otros mensajes detallados, hay que configurar el nivel de logging.

Configuración mediante archivo

JUL puede configurarse a través del archivo logging.properties (suele estar en la carpeta de la JRE). Ahí puedes indicar:

  • Nivel mínimo para el logger
  • Adónde escribir los logs (archivo, consola)
  • Formato de los mensajes

Ejemplo de línea en logging.properties:

.level=INFO

4. Bibliotecas de logging externas

Log4j (Apache)

Log4j es una de las bibliotecas de logging más conocidas para Java. Es flexible, potente, admite distintos formatos, escritura asíncrona, rotación de archivos y mucho más.

Ejemplo de configuración más simple de Log4j 2 (XML):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Ejemplo de uso de Log4j 2 en código:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jExample {
    private static final Logger logger = LogManager.getLogger(Log4jExample.class);

    public static void main(String[] args) {
        logger.info("Hello from Log4j!");
        logger.error("Este es un error con Log4j");
    }
}

Para que funcione, hay que añadir las dependencias de Log4j a tu proyecto (por ejemplo, con Maven o Gradle).

SLF4J: fachada de logging

SLF4J (Simple Logging Facade for Java) no es un sistema de logging independiente, sino una «capa» entre tu código y una implementación concreta (Log4j, Logback, JUL, etc.).

La fachada sirve para escribir el código una sola vez y, si hace falta, cambiar el sistema de logging real sin reescribir el código, incluso aunque distintas bibliotecas usen loggers diferentes.

Ejemplo de uso de SLF4J:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4jExample {
    private static final Logger logger = LoggerFactory.getLogger(Slf4jExample.class);

    public static void main(String[] args) {
        logger.info("¡Hola, logging a través de SLF4J!");
        logger.warn("Atención: algo puede salir mal");
        logger.error("Error a través de SLF4J");
    }
}

¿Cómo funciona?

  • Escribes el código a través de SLF4J.
  • Añades al classpath la implementación que necesites (por ejemplo, Logback o Log4j).
  • SLF4J redirige las llamadas a la implementación elegida.

Interacción de SLF4J con otros loggers: SLF4J puede trabajar sobre JUL, Log4j, Logback, etc., lo que permite migrar fácilmente sin reescribir el código.

5. Práctica: comparar System.out.println y el logging

Ejemplo 1: System.out.println

public class PrintlnExample {
    public static void main(String[] args) {
        System.out.println("La aplicación se ha iniciado");
        System.out.println("Ocurrió un error: algo salió mal");
    }
}

Qué falla aquí:

  • No hay nivel del mensaje (error, información, advertencia — todo es igual).
  • No hay hora, nombre de clase, hilo.
  • Todos los mensajes van al mismo saco.
  • No se puede configurar la salida de forma flexible (por ejemplo, escribir solo errores).

Ejemplo 2: Logging mediante SLF4J + Logback

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggingVsPrintln {
    private static final Logger logger = LoggerFactory.getLogger(LoggingVsPrintln.class);

    public static void main(String[] args) {
        logger.info("La aplicación se ha iniciado");
        logger.error("Ocurrió un error: algo salió mal");
    }
}

Ventajas:

  • Cada mensaje va acompañado de hora, nivel, nombre de clase e hilo.
  • Se pueden filtrar los mensajes por nivel.
  • Se pueden escribir los logs a archivo, enviarlos por la red, formatearlos, archivarlos.
  • El logging es seguro para hilos (relevante para aplicaciones multihilo).

Demostración de la diferencia

System.out.println
Logging (SLF4J/Logback)
La aplicación se ha iniciado 12:34:56 [main] INFO LoggingVsPrintln - La aplicación se ha iniciado
Ocurrió un error: algo salió mal 12:34:56 [main] ERROR LoggingVsPrintln - Ocurrió un error: algo salió mal

6. Cómo añadir logging a tu proyecto

Para el logger estándar (JUL)

Todo ya está en el JDK; puedes usarlo de inmediato:

import java.util.logging.Logger;

public class MyApp {
    private static final Logger logger = Logger.getLogger(MyApp.class.getName());

    public static void main(String[] args) {
        logger.info("Este es un mensaje informativo");
    }
}

Para Log4j o SLF4J

  1. Añade las dependencias (por ejemplo, con Maven).

    Para Log4j 2:

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.20.0</version>
    </dependency>
    

    Para SLF4J + Logback:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.0.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.4.7</version>
    </dependency>
    
  2. Crea el archivo de configuración (por ejemplo, logback.xml para Logback o log4j2.xml para Log4j).
  3. Usa el logger en tu código (véase los ejemplos anteriores).

7. Miniaplicación: añadimos logging

Supongamos que tenemos una aplicación sencilla — una calculadora de línea de comandos. Vamos a añadirle logging.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Scanner;

public class CalculatorApp {
    private static final Logger logger = LoggerFactory.getLogger(CalculatorApp.class);

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        logger.info("La calculadora se ha iniciado");

        try {
            System.out.print("Introduzca el primer número: ");
            int a = Integer.parseInt(scanner.nextLine());
            logger.debug("Se introdujo el primer número: {}", a);

            System.out.print("Introduzca el segundo número: ");
            int b = Integer.parseInt(scanner.nextLine());
            logger.debug("Se introdujo el segundo número: {}", b);

            int sum = a + b;
            logger.info("Suma de los números: {}", sum);
            System.out.println("Resultado: " + sum);
        } catch (NumberFormatException ex) {
            logger.error("Error al introducir el número", ex);
            System.out.println("Error: ¡introduzca un número válido!");
        } catch (Exception ex) {
            logger.error("Error desconocido", ex);
            System.out.println("¡Se produjo un error!");
        }
        logger.info("La calculadora ha terminado");
    }
}

Qué pasa aquí:

  • Todos los eventos clave se registran en el log.
  • Los errores se registran con nivel ERROR y con el stack trace completo.
  • Toda la información queda disponible para su análisis tras la ejecución del programa.

8. Errores típicos al trabajar con logging

Error n.º 1: Usar solo System.out.println para depuración y diagnóstico.
Es cómodo al principio, pero no sirve para aplicaciones reales. No podrás controlar el nivel de los mensajes, no verás la hora y no podrás analizar los logs si el programa se ejecuta en un servidor.

Error n.º 2: Registrar demasiada información en nivel ERROR.
Si escribes todo como error, dejarás de distinguir qué es realmente importante y qué es solo información para depurar.

Error n.º 3: Registrar datos sensibles (contraseñas, tokens, números de tarjeta).
¡Los logs deben ser seguros! No escribas ahí lo que otros no deberían ver.

Error n.º 4: Falta de configuración del logging.
Si no configuras los niveles, el formato y el lugar de almacenamiento de los logs, puedes «ahogarte» inesperadamente en gigabytes de información innecesaria o no ver el error en absoluto.

Error n.º 5: No usar una fachada de logging (SLF4J) en proyectos grandes.
Si tu proyecto crece y cambias de una biblioteca a otra, sin una fachada será doloroso. SLF4J permite cambiar fácilmente el «motor» de logging sin reescribir el código.

1
Tarea
JAVA 25 SELF, nivel 63, lección 0
Bloqueada
Ingeniero en la planta
Ingeniero en la planta
1
Tarea
JAVA 25 SELF, nivel 63, lección 0
Bloqueada
Nuevo desarrollador
Nuevo desarrollador
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION