Tag Archives: apache2

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.

Instalando php-fpm y apache2

He leído muchos tutoriales sobre como instalar nginx y php-fpm.
Sigo usando apache2 más que nada debido por la facilidad del archivo .htaccess que permite hacer uso de mod_rewrite y proteger las rutas con un password (así como usar otros módulos como mod_svn, etc)

No he encontrado una manera 100% transparente como ngninx, pero detallo lo que uso para trabajar con php-fpm y apache2. Pasos en debian:

  • echo "deb http://packages.dotdeb.org stable all" >> /etc/apt/sources.list
  • apt-get update
  • apt-get install libapache2-mod-fastcgi apache2-mpm-worker php5-fpm php5-common php5-cli
  • hacer todo los apt-get de todos los módulos php5-* que quieras
  • Agregar lo siguiente a un nuevo archivo: /etc/apache2/mods-enabled/fpm.load
    AddType application/x-httpd-fastphp5 .php .phtml
    Action application/x-httpd-fastphp5 /fast-cgi-fake-handler
  • en /etc/php5/fpm/pool.d/www.conf cambiar:
    listen = 127.0.0.1:9000

    por:

    ; listen = 127.0.0.1:9000
     listen = /var/run/php-fpm.socket

    Esto habilitará el socket de unix que debe ser más eficiente

  • /etc/init.d/php-fpm restart
  • /etc/init.d/apache2 restart

 

Con esto podrás usar php-fpm a través de una url “ficticia”: /fast-cgi-fake-handler si quieres cambiar tu archivo /etc/apache2/sites-enabled/000-default se vería de esta manera:

FastCGIExternalServer /var/www/fast-cgi-fake-handler -socket /var/run/php-fpm.socket
DocumentRoot /var/www

El sistema cambiará la url /index.php por: /fast-cgi-fake-handler/index.php que será enviada a php-fpm mediante fastcgi

Esto tiene dos problemas:

  1. Necesitas especificar FastCGIExternalServer de la forma ${DOCUMENT_ROOT}/fast-cgi-fake-handler en todos tus hosts virtuales para que funcione
  2. Zend framework y otros que utilicen el patron de consumir cualquier url y pasársela a un script index.php no funcionarán porque generarán un ciclo infinito; pero hay una solución sencilla en tu código .htaccess escribe después de RewriteEngine On:
    RewriteRule ^fast-cgi-fake-handler/ - [L,NC]

    Esto evitará procesar todas las ligas que contengan “fast-cgi-fake-handler” como su inicio; o claro puedes usar RewriteCond para evitar esto.