Log Watcher¶
The LogWatcher service monitors SCUM server log files in real time and exposes them through the GET /logs HTTP endpoint. It watches both the main SCUM.log and all per-category log files in the SaveFiles/Logs/ directory (chat, login, admin, economy, kill, and more).
How it works¶
-
Startup delay — After the mod loads, LogWatcher waits a configurable number of seconds (default 30) before scanning for log files. This gives the SCUM server time to create its log files.
-
Auto-discovery — If
LogWatcherSourcesis not configured, the watcher automatically discovers all log file prefixes inSaveFiles/Logs/(e.g.chat,login,admin,economy,kill,famepoints,loot,gameplay, etc.) and always includes the mainSCUM.log. -
Polling — Every 1 second, the watcher checks each tracked file for new content. New lines are pushed into a shared ring buffer (max 2000 lines).
-
Backlog — On startup, the watcher seeds the ring buffer with the last N lines from each file (configurable via
LogWatcherBacklog, default 100). -
Rotation detection — If a log file shrinks (e.g.
SCUM.logis rotated on server restart), the watcher resets and begins reading from the start of the new file.
GET /logs¶
Returns log lines that have been captured since a given timestamp. Auth required.
Query parameters
| Parameter | Required | Description |
|---|---|---|
since |
No | Unix timestamp in milliseconds. Only lines with t >= since are returned. Defaults to 0 (all buffered lines). |
sources |
No | Comma-separated list of source names to include (e.g. SCUM,chat,login). Omit to return all sources. |
Response
{
"ok": true,
"lines": [
{
"t": 1710612345123,
"src": "chat",
"line": "2026.03.16-18.22.07: '76561198000000001:PlayerName(1)' 'Local: hello'"
},
{
"t": 1710612346124,
"src": "SCUM",
"line": "[2026.03.16-18.22.07:537][ 42]LogEntitySystem: Auto-save took 0.203ms"
}
],
"next": 1710612346125
}
| Field | Type | Description |
|---|---|---|
lines |
array | Array of log line objects |
lines[].t |
number | Capture timestamp (Unix ms) — use this for the next since value |
lines[].src |
string | Source name (e.g. SCUM, chat, login, admin, economy) |
lines[].line |
string | The raw log line content |
next |
number | Suggested value for since on your next poll (equals max(t) + 1) |
Response — LogWatcher disabled
HTTP 503:
Available sources¶
When auto-discovery is enabled (default), the watcher finds all log file types present in SaveFiles/Logs/. Common sources include:
| Source | Description |
|---|---|
SCUM |
Main server log (SCUM.log) — frame stats, net events, game state |
chat |
Player chat messages (local, global) |
login |
Player login/logout events |
admin |
Admin command executions |
economy |
Currency transactions |
kill |
Player kills |
event_kill |
Event-related kills |
famepoints |
Fame point changes |
loot |
Loot spawning events |
gameplay |
General gameplay events |
violations |
Anti-cheat / rule violations |
base_building_destruction |
Base destruction events |
vehicle_destruction |
Vehicle destruction events |
chest_ownership |
Chest ownership changes |
armor_absorption |
Armor damage absorption |
quests |
Quest-related events |
raid_protection |
Raid protection events |
sentry |
Sentry/turret events |
server_notifications |
Server notification events |
Note
The exact set of sources depends on your server's game version and configuration. New source types added by SCUM updates are discovered automatically.
Configuration¶
The LogWatcher starts automatically — no configuration is needed for basic use. You can configure LogWatcherSources in the panel's Settings tab to filter which log sources are monitored (leave empty to auto-discover all available sources).
The following optional settings are INI-only and must be set in ggCON.ini under the [ggCON] section:
; (Optional) Number of historical lines to load per file on startup.
; Default: 100
; LogWatcherBacklog = 100
; (Optional) Seconds to wait before scanning for log files.
; Default: 30
; LogWatcherStartupDelay = 30
See Config Reference for full details on each key.
Polling example (PowerShell)¶
The following script polls GET /logs every second and prints new lines with color-coded sources:
# Poll-Logs.ps1
# Usage:
# .\Poll-Logs.ps1
# .\Poll-Logs.ps1 -ServerHost 10.0.0.5 -Port 8081 -Password yourpassword
# .\Poll-Logs.ps1 -Sources "chat,login,kill"
param(
[string]$ServerHost = "127.0.0.1",
[int] $Port = 8081,
[string]$Password = "",
[string]$Sources = "" # comma-separated, empty = all
)
$BaseUrl = "http://${ServerHost}:${Port}/logs"
$Headers = @{}
if ($Password -ne "") { $Headers["X-Password"] = $Password }
# Start from now
$Since = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
Write-Host "Polling $BaseUrl every 1s (Ctrl-C to stop)" -ForegroundColor Cyan
if ($Sources -ne "") { Write-Host "Sources filter: $Sources" -ForegroundColor DarkCyan }
Write-Host ""
while ($true) {
try {
$Url = "${BaseUrl}?since=${Since}"
if ($Sources -ne "") {
$Url += "&sources=$([Uri]::EscapeDataString($Sources))"
}
$Response = Invoke-RestMethod -Uri $Url -Headers $Headers `
-Method Get -ErrorAction Stop
if ($Response.lines.Count -gt 0) {
foreach ($entry in $Response.lines) {
$ts = [DateTimeOffset]::FromUnixTimeMilliseconds(
$entry.t).LocalDateTime.ToString("HH:mm:ss.fff")
$src = $entry.src.PadRight(26)
$color = switch ($entry.src) {
"SCUM" { "Gray" }
"login" { "Cyan" }
"admin" { "Yellow" }
"economy" { "Green" }
"kill" { "Red" }
"event_kill" { "DarkRed" }
"chat" { "Magenta" }
"famepoints" { "Blue" }
"loot" { "DarkYellow" }
"gameplay" { "DarkCyan" }
default { "White" }
}
Write-Host "$ts [$src] $($entry.line)" `
-ForegroundColor $color
}
}
$Since = $Response.next
}
catch {
$msg = $_.Exception.Message
Write-Host "$(Get-Date -Format 'HH:mm:ss') ERROR: $msg" `
-ForegroundColor Red
}
Start-Sleep -Seconds 1
}
Example output:
21:34:38.650 [login ] 2026.03.16-19.34.08: '10.0.0.1 76561198000000001:PlayerName(1)' logged in at: X=150991.000 Y=-40018.000 Z=33531.000
21:34:38.651 [chat ] 2026.03.16-19.34.12: '76561198000000001:PlayerName(1)' 'Global: hello everyone'
21:34:38.652 [economy ] 2026.03.16-19.34.15: '76561198000000001:PlayerName(1)' bought item for 500
21:34:39.660 [SCUM ] [2026.03.16-19.34.39:199][ 42]LogSCUM: Global Stats: 32.9ms ( 30.4FPS)
Known limitations¶
-
SaveFiles/Logs latency — SCUM's per-category log files (
SaveFiles/Logs/) do not include a trailing newline on the last written line until the next log entry is appended. ggCON handles this by processing unterminated lines immediately, so there is no additional delay beyond the 1-second poll interval. -
SCUM.log volume — The main
SCUM.logcan be very verbose (frame stats every 5 seconds, net events, etc.). If you only need gameplay events, use thesourcesfilter to excludeSCUM— e.g.?sources=chat,login,kill,admin. -
Ring buffer size — The internal buffer holds up to 2000 lines across all sources. On a busy server with many sources, older lines may be evicted before they are polled. Increase your poll frequency or filter to specific sources if this is a concern.