Commit c718ef1
Logging performance: off-thread console writer, buffered file sinks, and quieter defaults (#402)
* logging: quiet console defaults (LogLevel 3->1) + suppress AI/spell debug filters
Stage 1 / Change A increment 1 (config only, no recompile needed).
- LogLevel 3 -> 1: the dist shipped full DEBUG to the console; on Windows the
console is flushed per stdio call, so at level 3 every per-spawn DEBUG/DETAIL
line is a synchronous console write on the world/map-update threads -> the
LivingWorld / playerbot spawn-burst hang.
- LogFilter_AIAndMovegens 0 -> 1 and LogFilter_SpellCast 0 -> 1: these two
filters shipped enabled; in a LivingWorld bitmask-7 baseline they are ~50% of
a LogFileLevel=3 dump (~11k "used AI is" + ~2.7k spell/aura + waypoint). Each
stays re-enablable for targeted debugging.
Recommended runtime mode is now LogLevel=1 + LogFileLevel=3 (quiet console,
buffered DEBUG to file). Spec: docs/logging-perf/SPEC.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* logging: buffer file sinks + atomic, flush-free hot loggers (Stage 1 / Change A)
Increment 2 - make LogFileLevel=3 debug fast/buffered/un-torn so devs can run
full DEBUG without the world thread stalling on per-line file I/O.
- setvbuf(_IOFBF, 64KB) on all file sinks (openLogFile). The four hot loggers
(outString/outBasic/outDetail/outDebug) drop their per-line fflush and write
the timestamp+body+newline under a new m_fileMtx so concurrent map-update
worker threads cannot tear lines.
- Log::Flush() drains the buffered main + packet logs; called ~1/sec from
World::Update and once at shutdown (after "Bye!"). Errors still flush at emit
time and are deliberately NOT under m_fileMtx, so the AntiFreeze watchdog can
never be blocked by it and error lines stay crash-durable (accepted cost: a
rare error/debug line interleave, no corruption).
- Initialize() is now idempotent via CloseLogFiles(), fixing the realmd
double-init handle leak; ~Log() shares the same CloseLogFiles().
- outWorldPacketDump rewritten from one fprintf PER BYTE to a single buffered
fwrite (byte-identical output).
- PacketLoggingEnabled (default off) is the single gate for packet logging:
worldLogfile is opened only when set, IsPacketLoggingEnabled() keys off it,
and both WorldSocket call sites gate on it -> packet logging is off by default
even on legacy configs with WorldLogFile set + LogLevel=3.
Recommended dev mode: LogLevel=1 + LogFileLevel=3 (quiet console, buffered
DEBUG file). Reviewed by a 3-lens adversarial pass (compile / concurrency /
byte-fidelity): SHIP, no compile blockers. Spec: docs/logging-perf/SPEC.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* logging: off-thread console writer (Stage 1 / increment 3)
Move the console emit off the world + map-update threads so live LogLevel=3
console debug no longer stalls them. On Windows the CRT flushes the console per
stdio call, so console writes can't be batched inline - a dedicated thread does
them.
- ConsoleLogWriter (ACE_Based::Runnable, modeled on SqlDelayThread): producers
format the line and Enqueue a by-value ConsoleLogRecord into a LockedQueue; one
writer thread drains it and does Log::SetColor (now static) + OEM transform +
fwrite + ResetColor, per line, off the hot threads. Bounded with drop+count on
overflow (the file sink is durable, so dropped/crash-lost console lines are
harmless). The writer never calls sLog (no reentrancy).
- Every logger's CONSOLE block now routes through Log::ConsoleEmit /
ConsoleEmitBlank (async when the thread runs, synchronous inline fallback
otherwise - startup + shutdown tail). The increment-2 m_fileMtx FILE blocks are
untouched and the public sLog API is unchanged.
- Util::vutf8format returns the formatted OEM/UTF-8 bytes as std::string (same
vsnprintf + Utf8toWStr + CharToOemBuffW chain as vutf8printf; byte-identical).
- mangosd starts the writer after config/InitColors and stops+drains+joins it at
shutdown before the final Flush. realmd (a submodule) is intentionally NOT wired
- it uses the synchronous fallback; its console-thread wiring is a deferred
submodule follow-up.
Built clean (RelWithDebInfo: mangosd + realmd, 0 errors/warnings) and reviewed by
a 3-lens adversarial pass (concurrency/lifecycle, console-fidelity, style),
SHIP_WITH_FIXES: the no-arg error variants now route through the writer, the
drop-notice fwrite is clamped, and the StopConsoleThread quiescence invariant is
documented. Spec: docs/logging-perf/SPEC.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* logging: address Codex final review of fix/logging-perf-speedfix
Adversarial pre-PR review (Codex) flagged correctness/portability issues in
the off-thread console + buffered-file rework. Fixes (no public sLog API
change, core-side only, no submodule edits):
BLOCKING
- SOAP UAF on shutdown: the SOAP listener is a std::thread, not an ACE task,
so ACE_Thread_Manager::wait() never joined it; its shared_ptr deleter joined
only at main() scope exit, AFTER StopConsoleThread() freed the writer -- a
late SOAP log could enqueue into a freed ConsoleLogWriter. Now soapThread is
reset() (joined) before StopConsoleThread(), upholding the quiescence
invariant for SOAP too. (mangosd.cpp)
- ConsoleLogWriter::m_running is now std::atomic<bool>, not volatile bool, so
Stop()/run() synchronise correctly (volatile is not a memory-model fence;
matters on weakly-ordered archs). (ConsoleLogWriter.h)
MAJOR
- Console writer started too early: it was launched before the OpenSSL / PID /
start_db init, whose early-return error paths left the writer thread running
into stdio teardown. Moved StartConsoleThread() to just after start_db()
succeeds -- still before SetInitialWorldSettings() (the spawn-burst hot path)
-- so no fatal early-return leaks a running writer. (mangosd.cpp)
- POSIX truncation regression: vutf8format() clamped to 32 KiB whereas the
legacy POSIX path used unbounded vfprintf. Oversize messages are now rendered
in full via a sized second pass (va_copy). (Util.cpp)
- Console byte-fidelity: the trailing newline was being written INSIDE the
SetColor/ResetColor span; restored the legacy ordering (body -> ResetColor ->
"\n") by keeping the newline off rec.text and appending it after reset in the
writer and the sync fallback. (Log.cpp, ConsoleLogWriter.cpp, Log.h)
MINOR / hygiene
- Writer now owns the stdout flush (one fflush per drain batch, off the world
thread) so redirected/piped consoles stay prompt. (ConsoleLogWriter.cpp)
- Added <utility> for std::move (was relying on a transitive include that GCC/
Clang may not provide). (Log.cpp)
- Refreshed stale config comments (LogLevel now defaults to 1; AIAndMovegens /
SpellCast now ship suppressed) and documented PacketLoggingEnabled.
(mangosd.conf.dist.in)
Note (intentional, not restored): all error console output (timestamp +
message + newline) now goes to stderr consistently. Previously the optional
LogTime timestamp leaked to stdout via outTime() while the message went to
stderr; with the default LogTime=0 the console output is byte-identical to
master.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* logging: bump world ConfVersion for the new logging config keys
The logging-performance change adds PacketLoggingEnabled and flips the
default LogLevel / LogFilter_AIAndMovegens / LogFilter_SpellCast values in
mangosd.conf.dist, so bump MANGOS_WORLD_VER (drives both the generated
ConfVersion and the compiled MANGOSD_CONFIG_VERSION) to today's date. Servers
running an older mangosd.conf now get the "conf out of date" warning.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent e6b8563 commit c718ef1
12 files changed
Lines changed: 726 additions & 346 deletions
File tree
- cmake
- src
- game
- Server
- WorldHandlers
- mangosd
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
657 | 657 | | |
658 | 658 | | |
659 | 659 | | |
660 | | - | |
661 | | - | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
662 | 665 | | |
663 | 666 | | |
664 | 667 | | |
| |||
1051 | 1054 | | |
1052 | 1055 | | |
1053 | 1056 | | |
1054 | | - | |
| 1057 | + | |
1055 | 1058 | | |
1056 | 1059 | | |
1057 | 1060 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1839 | 1839 | | |
1840 | 1840 | | |
1841 | 1841 | | |
| 1842 | + | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
1842 | 1854 | | |
1843 | 1855 | | |
1844 | 1856 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
263 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
264 | 267 | | |
265 | 268 | | |
266 | 269 | | |
| |||
303 | 306 | | |
304 | 307 | | |
305 | 308 | | |
306 | | - | |
| 309 | + | |
307 | 310 | | |
308 | 311 | | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
309 | 316 | | |
310 | 317 | | |
311 | 318 | | |
| |||
318 | 325 | | |
319 | 326 | | |
320 | 327 | | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
321 | 337 | | |
322 | 338 | | |
323 | 339 | | |
| |||
389 | 405 | | |
390 | 406 | | |
391 | 407 | | |
392 | | - | |
| 408 | + | |
393 | 409 | | |
394 | 410 | | |
395 | 411 | | |
| |||
406 | 422 | | |
407 | 423 | | |
408 | 424 | | |
409 | | - | |
| 425 | + | |
410 | 426 | | |
411 | 427 | | |
412 | 428 | | |
413 | | - | |
| 429 | + | |
414 | 430 | | |
415 | 431 | | |
| 432 | + | |
416 | 433 | | |
417 | 434 | | |
418 | 435 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
485 | 485 | | |
486 | 486 | | |
487 | 487 | | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
488 | 496 | | |
489 | 497 | | |
490 | 498 | | |
| |||
677 | 685 | | |
678 | 686 | | |
679 | 687 | | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
680 | 708 | | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
681 | 715 | | |
682 | 716 | | |
683 | 717 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| 112 | + | |
| 113 | + | |
112 | 114 | | |
113 | 115 | | |
114 | 116 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
0 commit comments