Trabajo con Logs en PHP

Cuando desarrollamos una aplicación se suceden numerosos flujos de ejecución, peticiones y respuesta, reactividad, etc. y todos son posibles contextos donde se puede ubicar un error, por poner un ejemplo, en una aplicación básica de compra, pueden darse errores en el registro, en las peticiones a la base de datos a la hora de validar un login, al añadir un ítem al carro…

Podemos utilizar los logs (registros) como una forma de controlar esos pequeños flujos dentro del sistema, derivando a un fichero de texto la información relevante.

Tanto el trabajo directo con archivos como el uso de ini_set son métodos para gestionar registros (logs) en PHP, pero tienen diferencias clave en su implementación y uso:

Trabajo directo con archivos:

  • Control completo: Cuando trabajas directamente con archivos, tienes un control completo sobre cómo se gestionan los registros. Puedes personalizar el formato, el contenido y la estructura de los registros según tus necesidades específicas.
  • Flexibilidad: Puedes decidir dónde y cómo se almacenan los registros. Esto te permite guardar registros en diferentes archivos, en diferentes formatos o incluso enviarlos a ubicaciones remotas si es necesario.
  • Requiere más código personalizado: Trabajar con archivos directamente generalmente implica escribir más código personalizado para abrir, escribir y cerrar archivos. Esto puede ser beneficioso si necesitas un alto grado de personalización y control.
  • Posible sobrecarga de recursos: Si se utilizan en exceso, las operaciones de escritura de archivos pueden consumir recursos, especialmente si se accede a los registros con frecuencia. Esto puede afectar el rendimiento de la aplicación.

Un ejemplo de implementación:

<?php
// Mensaje que deseas registrar en el archivo de logs
$logMessage = "Se ha accedido al archivo index.php el " . date("Y-m-d H:i:s") . "\n";

// Ruta al archivo de logs
$logFile = "logs.txt";

// Abre el archivo de logs en modo de escritura (si no existe, se crea)
if ($file = fopen($logFile, "a")) {
    // Escribe el mensaje en el archivo de logs
    fwrite($file, $logMessage);

    // Cierra el archivo
    fclose($file);
} else {
    // Manejo de errores si no se puede abrir el archivo
    echo "No se pudo abrir el archivo de logs.";
}

// Resto de tu código de la aplicación
?>

<!DOCTYPE html>
<html>
<head>
    <title>Mi Página Web</title>
</head>
<body>
    <h1>Bienvenido a mi página web</h1>
    <!-- El contenido de tu página web -->
</body>
</html>

Uso de ini_set con error_log:

  • Configuración global: ini_set te permite cambiar la configuración de PHP de manera global, incluida la configuración relacionada con registros de errores. En particular, puedes usar ini_set para especificar la ubicación del archivo de registro y otros parámetros de registro de errores.
  • Facilidad de uso: Configurar registros con ini_set es más simple y menos propenso a errores en comparación con la gestión manual de archivos. Es una forma rápida de redirigir mensajes de error a un archivo de registro sin tener que escribir mucho código adicional.
  • Menos control personalizado: Aunque puedes configurar la ubicación del archivo de registro y algunos parámetros básicos, tienes menos control sobre el formato y el contenido de los registros. Los registros generados con error_log suelen tener un formato predefinido y pueden ser menos flexibles en ese aspecto.
  • Más limitado para aplicaciones complejas: Para aplicaciones que requieren una lógica de registro personalizada o múltiples archivos de registro, trabajar directamente con archivos puede ser más adecuado que el enfoque de ini_set.

Ejemplo de implementación usando ini_set:

<?php
// Ruta al archivo de registro de errores
$logFile = 'logs.txt';

// Configura PHP para redirigir mensajes de error al archivo de registro
ini_set('log_errors', 1);
ini_set('error_log', $logFile);

// Mensaje de error personalizado
$errorMessage = 'Ha ocurrido un error inesperado en la aplicación.';

// Intenta ejecutar una operación que podría generar un error
$result = dividePorCero(10, 0);

// Verifica si $result contiene un valor booleano falso, lo que indica un error
if ($result === false) {
    // Obtiene información sobre el error actual
    $errorInfo = error_get_last();

    // Verifica si hay un error y si es un error de tipo E_ERROR
    if ($errorInfo !== null && $errorInfo['type'] === E_ERROR) {
        // Registra el mensaje de error en el archivo de registro
        error_log($errorMessage);

        // También puedes imprimir el mensaje de error en el navegador o realizar otras acciones
        echo $errorMessage;
    }
}

// Función personalizada que puede generar un error
function dividePorCero($numerator, $denominator) {
    if ($denominator === 0) {
        // Intentar dividir por cero generará un error
        return false;
    } else {
        return $numerator / $denominator;
    }
}
?>

En ambos casos la salida será similar, un registro que almacenará la información que hemos enviado en base al flujo de ejecución del sistema, un ejemplo:

[02-Sep-2023 19:58:43 Europe/Berlin] Error al ejecutar la función 'guardar' para el objeto Pueblo: Error en la ejecución de la consulta SQL: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
[02-Sep-2023 19:58:43 Europe/Berlin] Archivo: C:\xampp\htdocs\Galoria-master\modelos\Pueblo.php
[02-Sep-2023 19:58:43 Europe/Berlin] Línea: 72
[02-Sep-2023 19:58:43 Europe/Berlin] Trace: #0 C:\xampp\htdocs\Galoria-master\controladores\Registro.php(38): Pueblo->guardar()
#1 {main}
[02-Sep-2023 20:04:17 Europe/Berlin] Se ha registrado el usuario: Coque con ID: 
[02-Sep-2023 20:04:17 Europe/Berlin] ID del jugador: 47
[02-Sep-2023 20:04:17 Europe/Berlin] Nombre del pueblo: Pueblo 69
[02-Sep-2023 20:04:17 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[02-Sep-2023 20:04:17 Europe/Berlin] La consulta se ejecutó con éxito.
[04-Sep-2023 20:59:54 Europe/Berlin] Se ha registrado el usuario: Usuario1 con ID: 
[04-Sep-2023 20:59:54 Europe/Berlin] ID del jugador: 48
[04-Sep-2023 20:59:54 Europe/Berlin] Nombre del pueblo: Pueblo 734
[04-Sep-2023 20:59:54 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[04-Sep-2023 20:59:54 Europe/Berlin] La consulta se ejecutó con éxito.
[04-Sep-2023 21:42:25 Europe/Berlin] Se ha registrado el usuario: usuarioTest con ID: 
[04-Sep-2023 21:42:25 Europe/Berlin] ID del jugador: 49
[04-Sep-2023 21:42:25 Europe/Berlin] Nombre del pueblo: Pueblo 116
[04-Sep-2023 21:42:25 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[04-Sep-2023 21:42:25 Europe/Berlin] La consulta se ejecutó con éxito.
[04-Sep-2023 21:42:54 Europe/Berlin] Se ha registrado el usuario: unpaisano con ID: 
[04-Sep-2023 21:42:54 Europe/Berlin] ID del jugador: 50
[04-Sep-2023 21:42:54 Europe/Berlin] Nombre del pueblo: Pueblo 68
[04-Sep-2023 21:42:54 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[04-Sep-2023 21:42:54 Europe/Berlin] La consulta se ejecutó con éxito.
[04-Sep-2023 21:43:31 Europe/Berlin] Se ha registrado el usuario: Archivito con ID: 
[04-Sep-2023 21:43:31 Europe/Berlin] ID del jugador: 51
[04-Sep-2023 21:43:31 Europe/Berlin] Nombre del pueblo: Pueblo 108
[04-Sep-2023 21:43:31 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[04-Sep-2023 21:43:31 Europe/Berlin] La consulta se ejecutó con éxito.
[05-Sep-2023 11:13:21 Europe/Berlin] Se ha registrado el usuario: usuario2 con ID: 
[05-Sep-2023 11:13:21 Europe/Berlin] ID del jugador: 52
[05-Sep-2023 11:13:21 Europe/Berlin] Nombre del pueblo: Pueblo 37
[05-Sep-2023 11:13:21 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[05-Sep-2023 11:13:21 Europe/Berlin] La consulta se ejecutó con éxito.
[05-Sep-2023 11:17:04 Europe/Berlin] Se ha registrado el usuario: martin con ID: 
[05-Sep-2023 11:17:04 Europe/Berlin] ID del jugador: 53
[05-Sep-2023 11:17:04 Europe/Berlin] Nombre del pueblo: Pueblo 34
[05-Sep-2023 11:17:04 Europe/Berlin] Espacios de edificios: , , , , , , , , , , , 

[05-Sep-2023 11:17:04 Europe/Berlin] La consulta se ejecutó con éxito.

En este fragmento de logs, perteneciente a un sistema de registro de usuarios, podemos ver la utilidad de estos sistemas, primero por permitir llevar un control de registro y segundo, por como se ve en las primeras líneas, exponer errores.

En resumen, la elección entre trabajar directamente con archivos y usar ini_set depende de tus necesidades específicas. Si deseas un control completo y flexibilidad en la gestión de registros, trabajar directamente con archivos es la mejor opción. Por otro lado, si deseas una solución rápida y sencilla para redirigir mensajes de error a un archivo de registro, ini_set puede ser más conveniente, ambas opciones son muy eficientes en líneas generales.

En el manual de logs de PHP encontrarás esta información de manera más práctica: logs en PHP.

Ver más sobre PHP.

¿Te ha resultado útil?

Promedio de puntuación 5 / 5. Recuento de votos: 1