Usando php para analizar logs de apache

Apache tiene una característica especial que es enviar la salida de sus logs a través de una tubería (pipe). Esto evita configurar syslog para reenviar los registros a un servidor en php.

Los cambios en apache son realmente simples, solo necesitas colocar algo así en la configuración:

LogFormat "%v %A %D \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" milog
CustomLog "|/usr/bin/php5 [PATH_TO_SCRIPT]/apache-stdin.php log" milog
ErrorLog "|/usr/bin/php5 [PATH_TO_SCRIPT]/apache-stdin.php error"

En apache-stdin.php el código es realmente simple, solo necesitas hacer:

<?php
$fp = fopen('php://stdin', 'r');
do {
	//leer una línea de apache, si no tiene datos se bloqueará hasta obtenerla
	$data = fgets($fp);
	$data = trim($data); //quitar espacios y "enters" del mensaje

	if (empty($data)) {
		break; //no envia más datos, así que terminar el script
	}

	//procesar el mensaje
} while(true);

fclose($fp);

Como puedes ver es simplemente leer una línea y procesarla.

He escrito un script de ayuda para esto, que puedes descargar aqui:
https://github.com/danguer/blog-examples/blob/master/php/syslog/apache-stdin.php

A este script le puedes pasar un parámetro adicional para especificar si es un registro normal o un registro de error; será igual que en la configuración de apache que puse anteriormente.

También puedes configurar el script para especificar el format de registro que estás usando en apache para obtener una descripción simple; el formato debe ser literal como:

<?php
$format = '%v %A %D \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"';

Con esto, el script generará un arreglo como:

array(
'hostname' => 'danguer.com',
'local_ip' => 127.0.0.1,
'time_ms' => 0.0002,
'first_line_request' => 'GET / HTTP/1.1',
'status_last' => 200,
'bytes_sent' => 2048
);

Con esto puedes usarlo para almacenarlo en un archivo (es lo que hace sin cambios el script), insertarlo a una base de datos, usar simpledb, etc.

Temas similares