Apache rotate Access and Error logs Windows

By : alimack
Source: Stackoverflow.com
Question!

How can I rotate the Apache Access and Error logs on a Window 2000 box?

I include my batch file below as an answer.

Is there a way of doing this directly via the Apache config file? I'm currently using the following customlog command to generate daily logs.

CustomLog '|" "Apache-Path/bin/rotatelogs.exe" "Apache-Path/logs/backup/internet_access_%d-%m-%y.log" 86400' combined

By : alimack


Answers

I've a little bit extend the the bat-script. You can use it for english and german dates. You will need 7za.exe at the same directory like script. The log-dir and -files for rotation are explicitly settable.

@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
:: ========================================================
:: setup variables and parameters
:: ========================================================

:: USE Service Display Name, Services are space-separated -> Syntax: "Display Name 1" "Display Name 2"
SET ROTATE_SERVICES="Apache2.2"

:: setting LOG-directory, log-files in this directory should be rotate
SET ROTATE_LOGDIR=F:\xampp\apache\logs

:: files which should rotate (space separated)
SET ROTATE_FILES=access.log error.log ssl_request.log

:: SET the Number Of Archives To Keep
SET /a keptarchives=5

:: SET delimiter for date format (english "/", german ".")
SET DATEDEL=.
:: ========================================================
:: DO NOT CHANGE ANYTHING
:: ========================================================

:: Check for existing Log-directory
IF NOT EXIST "%ROTATE_LOGDIR%" (
    CALL :LOG Please check your paths to Log Directory
    PAUSE
    GOTO :EOF
)

:: Check for existing Log-files
FOR %%d IN (%ROTATE_FILES%) DO (
    IF NOT EXIST "%ROTATE_LOGDIR%\%%d" (
        CALL :LOG File %ROTATE_LOGDIR%\%ROTATE_LOGFILES% does not exist!
        PAUSE
        GOTO :EOF
    )
)

:: generate date and time variables for execution
FOR /f "tokens=1,2,3 delims=%DATEDEL% " %%i IN ('date /T') DO SET execdate=%%k%%j%%i
FOR /f "tokens=1,2 delims=: " %%i IN ('time /T') DO SET exectime=%%i%%j
SET fullexectime=%execdate%_%exectime%
:: ========================================================


:: ========================================================
:: Operations
:: ========================================================

FOR %%d IN (%ROTATE_SERVICES%) DO (
    NET STOP %%d
)

FOR %%d IN (%ROTATE_FILES%) DO (
    cd /d %ROTATE_LOGDIR%
    IF NOT EXIST OLD (MKDIR OLD) 
    move %%d %ROTATE_LOGDIR%\OLD\%fullexectime%_%%d
)

FOR %%d IN (%ROTATE_SERVICES%) DO (
    NET START %%d
)

:: ========================================================
:: ZIP - LOGFILES
:: ========================================================
cd /d %ROTATE_LOGDIR%\OLD
CALL "%~dp0\7za.exe" a %ROTATE_LOGDIR%\OLD\%fullexectime%_log.zip %ROTATE_LOGDIR%\OLD\%fullexectime%_*.log
    IF %ERRORLEVEL% NEQ 0 (
        CALL :LOG Error while compressing log-file. Log will not deleted and not rotated. Check your OLD-directory!
        PAUSE
        GOTO :EOF
    )
del /Q %fullexectime%_*.log

:: ========================================================
:: ROTATE - ZIPPED LOGFILES
:: ========================================================

:: make list of archive zip files
type NUL > arclist.dat
for /F "tokens=1,2 delims=[] " %%i in ('dir /B *_log.zip ^| find /N "_log.zip"') do echo  %%i = %%j>> arclist.dat

:: count total number of files
for /F "tokens=1 delims=" %%i in ('type arclist.dat ^| find /C "_log.zip"') do set tnof=%%i

:: setup for and create the deletion list
set /a negtk=%keptarchives%*-1
set /a tntd=%tnof% - %keptarchives%

type NUL>dellist.dat
for /L %%i in (%negtk%,1,%tntd%) do find " %%i = " arclist.dat >> dellist.dat

:: del the old files
for /F "tokens=3 delims= " %%i in ('find "_log.zip" dellist.dat') do del /Q %%i

:: remove temp files
del /Q arclist.dat
del /Q dellist.dat


GOTO :EOF

:LOG
    SET MSG=[%DATE%, %TIME: =0%] %*
    ECHO.%MSG%
    SET MSG=
    GOTO :EOF
pause
By : sas900


Here's the DOS batch file, modified as annotated. I run it weekly and it keeps 8 weeks of zipped backups. You'll need to install 7 zip.

I haven't parametrised the paths, feel free to.


@echo off

:: Name - svrlogmng.bat
:: Description - Server Log File Manager
::
:: History
:: Date         Authory    Change
:: 22-May-2005  AGButler   Original
:: 14-Jan-2008  AIMackenzie Changed net stops and paths where necessary

:: ========================================================
:: setup variables and parameters
:: ========================================================

:: generate date and time variables
for /f "tokens=2,3,4 delims=/ " %%i in ('date /T') do set trdt=%%k%%j%%i
for /f "tokens=1,2 delims=: " %%i in ('time /T') do set trtt=%%i%%j
set nftu=%trdt%%trtt%

:: set the Number Of Archives To Keep
set /a noatk=8

:: ========================================================
:: turn over log files
:: ========================================================

:: change to the apache log file directory
cd /D "D:\Program Files\Apache Software Foundation\Apache2.2\logs\"

:: stop Apache Service, Move log files and restart Apache Service
"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -k stop

echo %nftu% >> access.log
move "D:\Program Files\Apache Software Foundation\Apache2.2\logs\access.log" "D:\Program Files\Apache Software Foundation\Apache2.2\logs\%nftu%_access.log"

echo %nftu% >> error.log
move "D:\Program Files\Apache Software Foundation\Apache2.2\logs\error.log" "D:\Program Files\Apache Software Foundation\Apache2.2\logs\%nftu%_error.log"

"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -k start

:: ========================================================
:: zip todays Access and Error log files, then delete old logs
:: ========================================================

:: zip the files
"D:\Program Files\7-Zip\7z.exe" a -tzip %nftu%_logs.zip %nftu%_access.log %nftu%_error.log

:: del the files
del /Q %nftu%_*.log

:: ========================================================
:: rotate the zip files
:: ========================================================

:: make list of archive zip files
type NUL > arclist.dat
for /F "tokens=1,2 delims=[] " %%i in ('dir /B *_logs.zip ^| find /N "_logs.zip"') do echo  %%i = %%j>> arclist.dat

:: count total number of files
for /F "tokens=1 delims=" %%i in ('type arclist.dat ^| find /C "_logs.zip"') do set tnof=%%i

:: setup for and create the deletion list
set /a negtk=%noatk%*-1
set /a tntd=%tnof% - %noatk%

type NUL>dellist.dat
for /L %%i in (%negtk%,1,%tntd%) do find " %%i = " arclist.dat >> dellist.dat

:: del the old files
for /F "tokens=3 delims= " %%i in ('find "_logs.zip" dellist.dat') do del /Q %%i

:: remove temp files
del /Q arclist.dat
del /Q dellist.dat

By : alimack


I wrote a vbs for a Windows 2003 box once. It uses zip.exe for compression (found at info-zip.org) and rotates apache logs and php logs. Logs are rotated when larger than MAX_SIZE. It deletes the oldest logs if log count passes MAX_ROTATIONS.

Please provide feedback on the script.

option explicit

const DEBUG_MODE = false
const MAX_ROTATIONS = 10
const MAX_SIZE = 2097152  ' 2MB
const WEB_LOGS = "c:\path\to\site\logs"
const PHP_LOG = "c:\path\to\phplog"
const APACHE_LOGS = "C:\path\to\Apache2\logs"
const APACHE_SERVICE ="Apache2.2" ' Name of the apache service for restart
const ZIP_APP = "c:\path\to\zip.exe"
const LOGROTATE_LOG = "c:\tmp\logrotate.log"

dim aLogs
aLogs = Array("\error.log","\transfer.log","\sec.log","\phperror.log") 

dim oFSO
set oFSO = CreateObject("Scripting.FileSystemObject")

if (not DEBUG_MODE) then
  dim oLogFile
  set oLogFile = oFSO.CreateTextFile(LOGROTATE_LOG, 2, True)
end if

dim bHasRotated
bHasRotated = false

Print "Starting log rotation"
Print "====================="
ManageWebLogs()
ManageApacheLogs()
ManagePhpLog()

if (bHasRotated = true) then
  Print "====================="
  RestartService APACHE_SERVICE
end if

Print "====================="
Print "Log rotation finished"

if (not DEBUG_MODE) then
  oLogFile.Close
  set oLogFile = nothing
end if
set oFSO = nothing

'*****************************************************************************
' Loop through all the subfolders in the weblog directory
sub ManageWebLogs()
  dim oLogDirs
  set oLogDirs = oFSO.GetFolder(WEB_LOGS)
  dim oLogDir
  for each oLogDir in oLogDirs.SubFolders
      Print "In " & oLogDir.Name
      RotateLogs(oLogDir)
  next 
  set oLogDir = nothing
end sub

'*****************************************************************************
' Loop through the log files in the Apache logs directory
sub ManageApacheLogs()
  dim oLogDir
  set oLogDir = oFSO.GetFolder(APACHE_LOGS)
  Print "In " & oLogDir.Name
  RotateLogs(oLogDir)
  set oLogDir = nothing
end sub

'*****************************************************************************
' Loop through the log files in the Apache logs directory
sub ManagePhpLog()
  dim oLogDir
  set oLogDir = oFSO.GetFolder(PHP_LOG)
  Print "In " & oLogDir.Name
  RotateLogs(oLogDir)
  set oLogDir = nothing
end sub


'*****************************************************************************
' Traverse through each of the log file types and check if they need rotation
sub RotateLogs(ByVal oFolder)
  dim sLog
  dim oLog
  for each sLog in aLogs
    if oFSO.FileExists(oFolder.Path & sLog) then
      set oLog = oFSO.GetFile(oFolder.Path & sLog)
      if (oLog.Size > MAX_SIZE) then
        RotateLog oFolder.Path & sLog
        ArchiveLog oFolder.Path & sLog
        bHasRotated = true
      end if
    end if
  next
  set oLog = nothing
end sub


'*****************************************************************************
' Rotates the given log, by incrementing the file name
sub RotateLog(ByVal sLog)
  dim i
  dim sOldFile, sNewFile
  for i = MAX_ROTATIONS to 1 step -1
    sOldFile = sLog & "." & i & ".zip"
    sNewFile = sLog & "." & (i+1) & ".zip"
    if oFSO.FileExists(sOldFile) and i = MAX_ROTATIONS then
      ' Delete zipfile        
      Print "-- Deleting " & sOldFile
      oFSO.DeleteFile(sOldFile)
    elseif oFSO.FileExists(sOldFile) then
      ' Rename zipfile
      Print "-- Renaming " & sOldFile & " to " & sNewFile
      oFSO.MoveFile sOldFile, sNewFile
    end if
  next
end sub


'*****************************************************************************
' Zips the current log
sub ArchiveLog(ByVal sLog)
  Dim oShell
  Set oShell = CreateObject("WScript.Shell")
  dim sZipFile 
  sZipFile = sLog & ".1.zip"
  Print "-- Archiving " & sLog & " to " & sZipFile
  oShell.Run "cmd /c " & ZIP_APP & " -jq " & sZipFile & " " & sLog, 0, true
  oFSO.DeleteFile(sLog)
  set oShell = nothing
end sub


' ****************************************************************************
' Restarts a given service (in our case Apache)
private sub RestartService( _
  ByVal sService _
)

  Dim oShell
  Set oShell = CreateObject("WScript.Shell")

  ' Service stopped with 'Net' command
  oShell.Run "cmd /c net stop " & sService, 0, true
  Print sService & " service stopped"

  ' Service started with 'Net' command
  oShell.Run "cmd /c net start " & sService, 0, true
  Print sService & " service restarted"

  set oShell = nothing
end sub


'*****************************************************************************
' Echoes out the given message if in debug mode
sub Print(ByVal sMsg)
  if (DEBUG_MODE) then
    wscript.echo sMsg
  else
    oLogFile.WriteLine sMsg
  end if
end sub
By : chriscena


This video can help you solving your question :)
By: admin