Best Log Rotation Solutions for Windows Web Servers: Native Tools vs Third-Party Alternatives


2 views

Windows doesn't include a dedicated log rotation executable like Unix-based systems have with logrotate. However, the operating system provides several native mechanisms that can achieve similar functionality:

# PowerShell script for basic log rotation
$logPath = "C:\logs\app.log"
$archivePath = "C:\logs\archive\app_$(Get-Date -Format yyyyMMdd).log"
if (Test-Path $logPath) {
    Move-Item $logPath $archivePath -Force
    Start-Process -FilePath "C:\app\webserver.exe" -ArgumentList "--restart-logging"
}

The Event Viewer (eventvwr.msc) includes basic log archival settings:

  • Maximum log size configuration
  • Overwrite events as needed (circular logging)
  • Archive when full options

For more advanced web server log rotation on Windows:

// Sample configuration for NXLog (community edition)
define ROOT C:\Program Files\nxlog
define CERTDIR %ROOT%\cert

<Input in>
    Module  im_file
    File    "C:\\logs\\access.log"
    SavePos TRUE
    Exec    if file_size() > 10M then file_cycle("C:\\logs\\archive\\access.log.%Y-%m-%d");
</Input>

When evaluating tools, consider these technical factors:

  • Compression support (gzip, zip)
  • Time-based vs size-based rotation triggers
  • Post-rotation command execution
  • Permission handling for web server processes

Combine Task Scheduler with PowerShell for custom solutions:

# Scheduled task PowerShell script
$maxDays = 30
$logFolder = "C:\inetpub\logs"
Get-ChildItem "$logFolder\*.log" | Where-Object {
    $_.LastWriteTime -lt (Get-Date).AddDays(-$maxDays)
} | Remove-Item -Force

# Rotate current logs
Get-ChildItem "$logFolder\*.log" | ForEach-Object {
    $newName = "$($_.BaseName)_$(Get-Date -Format yyyyMMdd)$($_.Extension)"
    Compress-Archive -Path $_.FullName -DestinationPath "$logFolder\archive\$newName.zip"
    Clear-Content $_.FullName
}

Unlike Unix-based systems with built-in logrotate utilities, Windows requires third-party solutions for effective log rotation. The native Windows Event Log has limited rotation capabilities and doesn't meet most web server requirements.

Windows offers partial solutions through:
• Event Viewer's archive functionality (limited to Event Logs)
• PowerShell scripts using Limit-EventLog
• Windows Performance Monitor's circular logging

1. NXLog (Enterprise Edition)

NXLog provides robust log rotation with compression and encryption. Example configuration:


define ROOTDIR C:\Program Files\nxlog
define CERTDIR %ROOTDIR%\cert

<Input in>
    Module  im_file
    File    "C:\\logs\\webserver\\access.log"
    SavePos TRUE
    Exec    $FileName = file_name();
            $FilePath = file_path();
</Input>

<Output out>
    Module  om_file
    File    "C:\\logs\\webserver\\archive\\" + 
            strftime(now(), "%Y-%m-%d") + 
            "_" + $FileName
</Output>

2. LogRotateWin (Open Source)

A Windows port of Unix's logrotate with similar configuration syntax:


C:\logs\webserver\*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0640 www-data www-data
    postrotate
        net stop "MyWebService" && net start "MyWebService"
    endscript
}

For custom rotation needs, this PowerShell script handles compression and archival:


# Set your log directory and retention policy
$logPath = "C:\logs\webserver"
$daysToKeep = 30
$archivePath = "C:\logs\archive"

# Create archive directory if not exists
if (-not (Test-Path $archivePath)) {
    New-Item -ItemType Directory -Path $archivePath | Out-Null
}

# Rotate and compress logs older than 1 day
Get-ChildItem -Path "$logPath\*.log" | Where-Object {
    $_.LastWriteTime -lt (Get-Date).AddDays(-1)
} | ForEach-Object {
    $archiveName = "$archivePath\$($_.BaseName)_$(Get-Date -Format 'yyyyMMdd').zip"
    Compress-Archive -Path $_.FullName -DestinationPath $archiveName -Update
    Remove-Item $_.FullName
}

# Clean up old archives
Get-ChildItem -Path "$archivePath\*.zip" | Where-Object {
    $_.LastWriteTime -lt (Get-Date).AddDays(-$daysToKeep)
} | Remove-Item
  • Schedule rotation during low-traffic periods
  • Test compression impact on CPU usage
  • Consider SSD wear for high-volume logging
  • Monitor disk space thresholds with alerts

For IIS, combine with the built-in Failed Request Tracing rotation:
%systemdrive%\inetpub\logs\LogFiles\W3SVC1\u_ex[YYMMDD].log
For Nginx on Windows, configure in nginx.conf:


http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log logs/access.log main;
    
    map $time_iso8601 $logdate {
        '~^(?\d{4}-\d{2}-\d{2})' $ymd;
        default 'nodate';
    }
    
    access_log logs/access-$logdate.log main;
}