How to set up rotating logs and retention on your MU server
Configure automatic rotation, compression and a retention policy for your MU Online server logs to avoid a full disk, keep a useful history and still have a trail to investigate fraud and crashes.
Logs are your MU Online server's memory. When a player accuses another of duplicating items, when the GameServer crashes with no explanation, or when you need to understand why the database went slow at 3 in the morning, the answer is in the logs. The problem is that unmanaged logs become a liabilit
Logs are your MU Online server's memory. When a player accuses another of duplicating items, when the GameServer crashes with no explanation, or when you need to understand why the database went slow at 3 in the morning, the answer is in the logs. The problem is that unmanaged logs become a liability: they grow endlessly, fill the disk and take down the very server they were supposed to help keep up. The solution is to set up rotation (splitting the logs into manageable chunks), compression (reducing the space of old ones) and retention (defining how long to keep each type). This guide shows how to build all of this on Windows, with ready-made scripts and a retention policy designed by category. The values cited are examples that vary by provider/version, so adjust them to your reality.
Prerequisites
To set up rotating logs you need:
- Administrative access to the server (RDP on Windows Server) with permission to create Scheduled Tasks.
- Knowledge of where each component writes its logs: ConnectServer, GameServer, DataServer and SQL Server.
- Enough disk space for at least a few days of logs before the first compression.
- PowerShell available (standard on Windows Server) for the rotation scripts.
- A retention policy decision by log type (we will cover this ahead).
- A working base server. If you are still building, start with how to create a MU Online server.
Step 1: Map all the server logs
Before rotating anything, you need to know what exists and where. A typical MU server generates logs in several places. Take an inventory:
| Source | Typical location (example) | Content |
|---|---|---|
| GameServer | GameServer\Log\ | Login, combat, trading, commands, errors |
| ConnectServer | ConnectServer\Log\ | Connections, server selection |
| DataServer | DataServer\Log\ | Database access, saves |
| SQL Server | the instance's LOG folder | Database errors, deadlocks |
| Site/Panel | the web server's log folder | Accesses, registrations, donations |
The exact paths vary by provider/version of the emulator. Document yours in a reference file; that saves time in every future maintenance.
Step 2: Choose the rotation strategy
There are two main rotation approaches, and you can combine them:
- Date-based rotation: a new file per day (for example,
GameServer-2025-01-31.log). Many emulators already do this natively. It is the simplest and safest, because it never touches the file the process is writing to. - Size-based rotation: when the file reaches a limit (for example, 100 MB), it is closed, renamed and a new one begins. Useful for very verbose logs that grow fast within the same day.
For most servers, date-based rotation is the ideal starting point. If a specific log grows out of control within the day, add size-based rotation for it.
> Check whether your emulator already rotates by date. If so, your job becomes just compressing and retaining. If not, the scripts below handle it.
Step 3: Create the rotation and compression script
The heart of the automation is a PowerShell script that walks the log folder, compresses the old files and deletes those past their deadline. Save something like C:\MuServer\Scripts\RotacionarLogs.ps1:
# Configuration
$pastaLogs = "C:\MuServer\GameServer\Log"
$diasParaZipar = 1 # compress logs older than 1 day
$diasParaApagar = 30 # delete files older than 30 days
$agora = Get-Date
# 1) Compress old logs not yet compressed
Get-ChildItem -Path $pastaLogs -Filter *.log |
Where-Object { $_.LastWriteTime -lt $agora.AddDays(-$diasParaZipar) } |
ForEach-Object {
$zip = "$($_.FullName).zip"
Compress-Archive -Path $_.FullName -DestinationPath $zip -Force
Remove-Item $_.FullName -Force
Write-Output "Compressed: $($_.Name)"
}
# 2) Delete compressed files beyond the retention deadline
Get-ChildItem -Path $pastaLogs -Filter *.zip |
Where-Object { $_.LastWriteTime -lt $agora.AddDays(-$diasParaApagar) } |
ForEach-Object {
Remove-Item $_.FullName -Force
Write-Output "Removed by retention: $($_.Name)"
}
Adjust $diasParaZipar and $diasParaApagar according to the policy defined in the next step. Repeat the block (or parameterize the script) for each mapped log folder.
Step 4: Define the retention policy by category
Not every log has the same value. Treating them all the same is a mistake: either you keep too much junk, or you delete too early what you would need in an investigation. Separate by category and set different retentions.
| Log category | Suggested retention (example) | Rationale |
|---|---|---|
| Security / anti-fraud | Long (months) | Investigations arise late |
| Valuable transactions (items, donations) | Long (months) | Chargebacks and disputes |
| Critical server errors | Medium-long (weeks to months) | Diagnosing recurring bugs |
| Login / connections | Medium (weeks) | Support and access patterns |
| Verbose debug | Short (a few days) | High volume, ephemeral value |
The exact deadlines vary by provider/version and by your disk capacity and legal obligations. The principle is constant: retain longer what is expensive to lose and discard quickly what is cheap to recreate.
Step 5: Schedule the rotation with Scheduled Tasks
With the script ready, schedule it to run automatically every day. Use the Windows Task Scheduler. You can create it through the graphical interface or via the command line:
# Create a daily task at 05:00 to rotate logs
$acao = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File C:\MuServer\Scripts\RotacionarLogs.ps1"
$gatilho = New-ScheduledTaskTrigger -Daily -At 5:00AM
Register-ScheduledTask -TaskName "MU-RotacionarLogs" `
-Action $acao -Trigger $gatilho -RunLevel Highest `
-Description "Compresses and applies retention to the MU logs"
Choose a low-activity time (early morning) so that compression and deletion do not compete for disk I/O with the player peak. This prevents the rotation itself from becoming a cause of lag.
Step 6: Handle the SQL Server log separately
SQL Server has its own mechanisms and should not be managed with file scripts alone. Two points deserve attention:
- SQL Server error log (ERRORLOG): by default SQL Server keeps a few historical files and cycles them on restart. You can increase the number of retained files and force the cycle periodically:
-- Force the creation of a new ERRORLOG file
EXEC sp_cycle_errorlog;
- Database transaction log (.ldf): this is NOT a text log for reading; it is part of the database mechanism. Never delete the
.ldf. Instead, keep the appropriate recovery model and back up the transaction log if you are in FULL mode, so it does not grow indefinitely. The ideal configuration varies by version and by your backup strategy.
> Confusing the SQL transaction log (.ldf) with a disposable text log and deleting it is a serious mistake that can corrupt the database. Handle the .ldf through backups, never through manual deletion.
Step 7: Monitor growth and validate the rotation
Setting it up is not enough; you need to confirm that the rotation is working and that the disk is not at risk. Build a lightweight monitor:
- Periodically check the free disk space on the log partition.
- Confirm that the
.zipfiles are being created and the old ones removed on schedule. - Check the Scheduled Task's own logs to make sure it runs without error.
A quick script to see the space taken by logs in each folder:
$pastas = @(
"C:\MuServer\GameServer\Log",
"C:\MuServer\ConnectServer\Log",
"C:\MuServer\DataServer\Log"
)
foreach ($p in $pastas) {
if (Test-Path $p) {
$tamMB = (Get-ChildItem $p -Recurse -File |
Measure-Object Length -Sum).Sum / 1MB
Write-Output ("{0,-45} {1,8:N1} MB" -f $p, $tamMB)
}
}
If one folder grows much faster than the others, review that component's verbosity level. Often you can reduce the debug log without losing the information that matters.
Common errors and fixes
| Error | Likely cause | Fix |
|---|---|---|
| Disk fills up and the server goes down | No rotation or retention | Automate compression and deletion by age |
| Rotation causes lag at peak | Scheduled at a busy time | Run the rotation in the early morning |
| Lost fraud evidence | Retention too short | Set a long retention for security logs |
Deleted the SQL .ldf file | Confused it with a text log | Never delete the .ldf; use transaction log backups |
| Script fails silently | No check on the Scheduled Task | Monitor the task history and the disk space |
| Compression corrupts the active log | Zipping a file open by the process | Compress only files from previous days |
| All logs with the same retention | A single policy | Separate by category and retain differently |
Launch checklist
- I mapped every log location (GameServer, ConnectServer, DataServer, SQL, site).
- I chose the rotation strategy (by date and, if needed, by size).
- I created the rotation, compression and age-based deletion script.
- I defined a different retention policy per log category.
- I scheduled the rotation for the early morning via Scheduled Tasks.
- I configured the SQL Server ERRORLOG cycle separately.
- I confirmed the transaction log (.ldf) is handled by backup, not deletion.
- I only compress files from previous days, never the active log.
- I set up monitoring of disk space and the task history.
- I validated that old files are compressed and removed on schedule.
Well-managed logs are invisible when everything goes well and priceless when something goes wrong. By rotating by date, compressing the old ones and retaining each category for the right amount of time, you ensure the disk never becomes a bottleneck and that, on the day of the investigation, the trail you need is still there. It is one of those setups that take little effort at the start and prevent a lot of headaches later.
Frequently asked questions
How long should I keep the server logs?
It depends on the type of log. Error and security/anti-fraud logs are worth keeping longer (weeks to months) because investigations arise after the fact. Verbose debug logs can be discarded within a few days. The ideal period varies by provider/version and by your disk capacity, so balance usefulness against space.
Can log rotation be done with the server running?
Yes, in most cases. Date-based strategies create a new file per day without touching the current one. Moving a file that is open by the process may require care, since some emulators keep the handle open. When in doubt, schedule the rotation for the daily restart or test it in a controlled environment.
Do logs really take up much space?
On busy servers, yes. Verbose GameServer and database logs can grow several GB per day. Without rotation and compression, that fills the disk and takes the server down. Compressing old files reduces the size drastically, typically to a fraction of the original, although the ratio varies by content.
Do I need external tools to rotate logs on Windows?
Not always. You can combine Windows Task Scheduler with PowerShell or batch scripts to rename, compress and delete logs by age. Dedicated tools exist and help in larger environments, but the essentials can be built with what already ships with the system.
What should I never delete from the logs?
Avoid discarding too early the security logs, the logs of important transactions (valuable items, trading, donations) and critical errors. These are the ones you will most need in fraud, chargeback or bug investigations. Set a longer retention for them and treat debug logs as disposable.