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
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
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
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
As stated I don't think this is strictly a programming question, but AFAIK there is no built-in functionality in Apache to support log rotation. There's a standard utility on unix systems called logrotate
, so that functionality would be redundant on those systems.
If you rephrase your question to ask how you can write a batch file to handle Apache log rotation on Windows 2000, then answer yourself with your batch file source, that might be helpful to others.