【问题标题】:Apache rotate Access and Error logs WindowsApache 轮换访问和错误日​​志 Windows
【发布时间】:2010-09-26 05:24:27
【问题描述】:

如何在 Window 2000 机器上轮换 Apache 访问和错误日​​志?

我在下面包含我的批处理文件作为答案。

有没有办法直接通过 Apache 配置文件执行此操作?我目前正在使用以下 customlog 命令来生成每日日志。

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

【问题讨论】:

    标签: windows apache logging logrotate


    【解决方案1】:

    我稍微扩展了 bat 脚本。您可以将其用于英语和德语日期。您将需要 7za.exe 位于与脚本相同的目录中。用于轮换的 log-dir 和 -files 是可显式设置的。

    @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
    

    【讨论】:

      【解决方案2】:

      这是 DOS 批处理文件,已按注释进行修改。 我每周运行一次,它会保存 8 周的压缩备份。 您需要安装 7 zip。

      我没有对路径进行参数化,请随意。


      @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
      

      【讨论】:

        【解决方案3】:

        我曾经为一个 Windows 2003 机器写过一个 vbs。它使用 zip.exe 进行压缩(可在 info-zip.org 找到)并旋转 apache 日志和 php 日志。日志在大于 MAX_SIZE 时旋转。如果日志计数超过 MAX_ROTATIONS,它将删除最旧的日志。

        请提供有关脚本的反馈。

        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
        

        【讨论】:

          【解决方案4】:

          如前所述,我不认为这是一个严格的编程问题,但 AFAIK Apache 中没有支持日志轮换的内置功能。在 unix 系统上有一个名为 logrotate 的标准实用程序,因此这些功能在这些系统上是多余的。

          如果您重新表述您的问题以询问如何编写批处理文件来处理 Windows 2000 上的 Apache 日志轮换,然后用您的批处理文件源回答自己,这可能对其他人有帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-09-21
            • 2010-12-08
            • 2015-04-20
            • 1970-01-01
            • 2017-09-25
            • 2018-01-14
            • 1970-01-01
            相关资源
            最近更新 更多