borrame.com - Colección particular de recortes de código y documentación para programación web

Canales RSS

Lo más fresco

  1. Bookmarklets Nuevo
  2. Recetario básico para CakePHP/2 Nuevo
  3. Certificado auto-firmado Nuevo

Sugerencias del chef

Lo más visitado

  1. Fecha y hora
  2. Dar formato a un número
  3. Reiniciar secuencia
  4. Vaciar un esquema
  5. Certificado auto-firmado
Compartir esta página

Rotar logs en Windows

Uno de los incordios de usar Apache en Windows es que no trae una forma decente de rotar los logs. La utilidad incluida, rotatelogs, tiene entre otros vicios la desagradable tendencia de ir dejando procesos colgados en memoria. La alternativa que recomiendan en el manual, cronolog, cojea del mismo pie. Hay módulos que no tienen ese fallo (aunque sí otros) pero nunca hay binarios para tu versión de Apache. Un lío, vamos.

Este script *.bat permite rotar los logs de Apache en Windows (instalado como servicio) usando un mecanismo parecido al que emplea el programa de Linux logrotate (no confundir con ninguno de los anteriores), a saber:

  1. Detener Apache
  2. Mover los logs recientes
  3. Iniciar Apache
  4. Comprimir los logs movidos
  5. Ir renombrando los logs como foo.log.1, foo.log.2... y borrar los más antiguos

Para usarlo sólo hay que modificar los valores de las variables si no son los correctos. Se puede automatizar con el programador de tareas de Windows (bastaría con comentar la línea set PAUSA_AL_FINAL=... para que no se quede la ventana abierta). Y en Windows Vista, naturalmente, requiere que se le asignen al ejecutarlo privilegios de administrador.

@echo off rem rem Rotación de logs de Apache - v2015-11-29 rem rem Realiza una rotación de logs de Apache instalado como servicio de Windows rem chcp 1252 > NUL rem Necesario para usar variables en un bucle FOR setlocal enabledelayedexpansion rem Directorio de logs set DIR_LOGS=C:\Apache24\logs rem Definición de los logs que vamos a rotar (debe ser válida dentro de un bucle FOR) set DEF_LOG="%DIR_LOGS%\*access.log" "%DIR_LOGS%\*error.log" rem Nº máximo de logs rotados que se conservarán set MAX_LOGS_ANTIGUOS=8 rem Si esta variable existe se comprimirán los logs rotados (requiere NTFS); rem comentar con REM para desactivar set COMPRIMIR_LOGS=Sí, por favor rem Ejecutable de Apache 2 (ruta completa si la carpeta no está en %PATH%) set APACHE=C:\Apache24\bin\httpd.exe rem Nombre del servicio set SERVICIO=Apache2.4 rem Si esta variable existe se insertará un PAUSE al final para poder leer la salida rem en sesiones no interactivas; comentar con REM para desactivar set PAUSA_AL_FINAL=Sí, por favor rem Sufijo para los archivos temporales set SUFIJO_TMP=.log_rotate_tmp-%RANDOM%%RANDOM% echo ========================================================================== echo Verificando la configuración de Apache... echo. "%APACHE%" -t echo. if %ERRORLEVEL% NEQ 0 (     goto cfg_err ) else (     goto cfg_ok ) :cfg_err echo Se han encontrado errores, no se puede continuar. goto fin :cfg_ok echo La configuración es correcta. echo ========================================================================== echo Deteniendo el servicio "%SERVICIO%"... echo. net stop "%SERVICIO%" if %ERRORLEVEL% NEQ 0 (     goto apagado_err ) else (     goto apagado_ok ) :apagado_err echo Ha fallado el apagado del servicio. goto fin :apagado_ok echo El servicio ha sido detenido con éxito. echo ========================================================================== echo Moviendo los logs recientes del directorio "%DIR_LOGS%"... echo. for %%i in (%DEF_LOG%) do ( set LOG=%%i set NOMBRE=%%~nxi set RUTA=%%~dpi     echo !NOMBRE! -^> !NOMBRE!%SUFIJO_TMP% move /y "!LOG!" "!RUTA!!NOMBRE!%SUFIJO_TMP%" > NUL ) echo. echo Los logs han sido movidos con éxito. echo ========================================================================== echo Arrancando el servicio "%SERVICIO%"... echo. net start "%SERVICIO%" if %ERRORLEVEL% NEQ 0 (     goto arrancado_err ) else (     goto arrancado_ok ) :arrancado_err echo Ha fallado el arrancado del servicio. goto fin :arrancado_ok echo El servicio ha sido arrancado con éxito. if defined COMPRIMIR_LOGS (     echo ==========================================================================     echo Comprimiendo los logs movidos...     echo.     for %%i in (%DEF_LOG%) do (         set NOMBRE=%%~nxi         set RUTA=%%~dpi         echo !NOMBRE!%SUFIJO_TMP%         compact /c "!RUTA!!NOMBRE!%SUFIJO_TMP%" > NUL     )     echo.     echo Los logs han sido comprimidos con éxito.     echo. ) echo ========================================================================== echo Rotando los logs antiguos... echo. rem rem Bucle principal: recorremos cada log en uso rem for %%i in (%DEF_LOG%) do (     set LOG=%%i     set NOMBRE=%%~nxi     set SUFIJO_TMP=%SUFIJO_TMP%     call :rotar ) goto fin_rotar rem rem Bucle interior: dado un log, rotamos todas sus copias rem :rotar     echo Rotando !NOMBRE!     set /a HASTA=!MAX_LOGS_ANTIGUOS!     rem     rem Si ya tenemos el máximo de logs, eliminamos el último     rem     if exist "!LOG!.!HASTA!" (         echo Eliminando !NOMBRE!.!HASTA!         del "!LOG!.!HASTA!"     )     :siguiente_rotar     set /a DESDE=!HASTA!-1     if !DESDE! equ 0 (         rem Log más reciente         echo !NOMBRE!!SUFIJO_TMP! -^> !NOMBRE!.!HASTA!         rename "!LOG!!SUFIJO_TMP!" "!NOMBRE!.!HASTA!"     ) else (         rem Log archivado         if exist "!LOG!.!DESDE!" (             echo !NOMBRE!.!DESDE! -^> !NOMBRE!.!HASTA!             rename "!LOG!.!DESDE!" "!NOMBRE!.!HASTA!"         )     )     set /a HASTA=!HASTA!-1     if !HASTA! neq 0 (         goto siguiente_rotar     ) goto :EOF :fin_rotar echo. echo Los logs han sido rotados con éxito. echo ========================================================================== :fin echo. echo. if defined PAUSA_AL_FINAL (     pause ); endlocal

La compresión (que se puede desactivar) sólo funciona si los logs están en una partición NTFS (utiliza el sistema de compresión integrado en dicho sistema de archivos). Pero... ¿quién ejecuta un servidor web sobre FAT32 en estos tiempos?

Fallos conocidos

Historial

v2015-11-29
Actualizar los valores por defecto para Apache/2.4.
v2014-02-05
Dar un parámetro más sensato a chcp. ¿Quién escribe archivos *.bat en ISO-8859-1?
v2009-03-04
Limitado el tiempo de apagado del servidor web a lo imprescindible.
Posibilidad de comprimir los logs archivados (compresión transparente de NTFS).
Uso de la variable de entorno %ProgramFiles% en las rutas.
La pausa final se puede activar/desactivar con una variable.
v2008-11-25
El nº de logs ahora se refiere sólo a logs archivados (los *.1, *.2, etc.) en lugar de al total; es más intuitivo.
Faltaba el "echo" en uno de los mensajes informativos.
v2008-08-28
Primera versión.

Esta página ha sido impresa el sábado 23 de septiembre de 2017 (02:23:54 +0200) desde http://borrame.com/recortes/apache/log-rotate.html. La última vez que miré contenía HTML válido con CSS fresquito y si tiene flatas de ortografía ha sido sin querer.

borrame.com es el sitio anteriormente conocido como bits.demogracia.com (no confundir con Demogracia, que sólo pasaba por ahí).

© 2005-2017 by Álvaro González (alvaro.es) • Burgos (España) • borrame.com