Skip to content

Add ClearLog functionality for log management#2954

Open
WybrenKoelmans wants to merge 6 commits into
beyond-all-reason:masterfrom
WybrenKoelmans:truncate-infolog
Open

Add ClearLog functionality for log management#2954
WybrenKoelmans wants to merge 6 commits into
beyond-all-reason:masterfrom
WybrenKoelmans:truncate-infolog

Conversation

@WybrenKoelmans

Copy link
Copy Markdown
Contributor

Introduce a ClearLog feature to manage log files, allowing for both truncation and rotation of logs. This enhancement improves log file handling within the system.

AI usage:
2 shot 100% Claude Opus 4.7

Comment thread rts/System/LogOutput.cpp Outdated
Comment thread rts/System/Log/FileSink.cpp Outdated
Comment thread rts/Game/UnsyncedGameCommands.cpp Outdated
Comment thread rts/System/LogOutput.cpp Outdated
Comment thread rts/System/LogOutput.h Outdated
Comment thread rts/Lua/LuaUnsyncedCtrl.cpp Outdated
Comment thread rts/System/LogOutput.cpp
@WybrenKoelmans

Copy link
Copy Markdown
Contributor Author

Excuse the force push but I think the review comments should be addressed now.

Comment thread rts/System/LogOutput.cpp Outdated
- Introduced helper functions for opening log files with UTF-8 BOM and buffering.
- Updated log file rotation to ensure proper stream handling and error reporting.
- Modified RotateLogFile method to return a boolean indicating success or failure.
Comment thread rts/System/Log/FileSink.cpp
Comment thread rts/System/Log/FileSink.cpp Outdated
Comment thread rts/System/Log/FileSink.h
Comment thread rts/System/LogOutput.cpp
if (!isRegistered)
return 1;

FILE* newStream = log_file_openFreshLogFile(filePath);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a log is attempted in between when we close the old stream/set it to nullptr and when we reopen the fresh file?

I think we might need to be careful about concurrency here, if you imagine multiple threads are logging when game code tries to rotate a file?

@bruno-dasilva bruno-dasilva May 31, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine there will be multiple edge cases there:

  1. separate thread has a handle on oldStream, main thread closes, separate thread tries to write (error or logs lost?)
  2. separate thread has a handle on oldStream, main thread flushes, separate thread tries to write, main thread closes (logs lost)
  3. main thread closes/sets nullptr, separate thread gets stream as nullptr, ??? (do we double open? do we error? do we lose the logs?)
  4. etc.

If you can't tell, I have nightmares from dealing with file writes + concurrency lol.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, because init was handled in main thread on startup before, we didn't really have to worry about concurrency.

But if we're doing these datastructure mutations at the same time we do concurrent LOG()s, we're going to need some sort of synchronization in place. (ie locking/mutexes?)

(for ex. did you know that calling vector.erase(iter) will break other thread's pointers that are doing for (auto iter : vector)? It can make them run off the bounds of the array into memory)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Practically that probably means making the whole log_file:: namespace thread safe. Which is probably suited for a separate PR to merge before this one? just spit balling.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #2840

@bruno-dasilva bruno-dasilva May 31, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice. would probably need to extend that pr to use the mutex in more places but glad to see there's prior art already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you (plural) agree that we can probably merge this PR without implementing a mutex for now? Perhaps as it can be done as part of that other linked Issue if really needed.

Comment thread rts/System/LogOutput.h Outdated
Use idiomatic C++ instead of raw pointers
@WybrenKoelmans

Copy link
Copy Markdown
Contributor Author

I don't the thread safety has to be part of this PR, so I'd like to offer it for merging.

@bruno-dasilva

Copy link
Copy Markdown
Collaborator

I don't the thread safety has to be part of this PR

why not? or at least, is it safe enough to prevent engine crashes?

@WybrenKoelmans

Copy link
Copy Markdown
Contributor Author

Well im no expert on the multi-threading nature of Recoil, but from my assumption that the Lua will run on a single thread I would think it'll be unlikely to crash the engine.

@bruno-dasilva

Copy link
Copy Markdown
Collaborator

Well im no expert on the multi-threading nature of Recoil, but from my assumption that the Lua will run on a single thread I would think it'll be unlikely to crash the engine.

I guess what im worried about most is clearlog doing things to log files while background threads (eg pathfinding threads) write logs. I'm not sure whether that is safe against crashes (if it does happen) or never occurs at all.

@sprunk sprunk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the existing code has no mutex I think it's ok to merge (on the assumption that whatever makes it work correctly will keep doing so) and just yell at you if something explodes.

@bruno-dasilva

bruno-dasilva commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

There is definitely some undefined behaviour on truncate/rotate + other threads (eg. sound thread) logging at the same time. Whether that's an issue in practice is a 🤷 depends on when this is called.

Let's see if we can land this pr first? Then this PR just needs to grab the mutex in the truncate/rotate bits. #3050

@lostsquirrel1

Copy link
Copy Markdown
Collaborator

@bruno-dasilva, I have a question about where we use logging in multiple threads. It may be easier for us to forbid that from happening.

@sprunk

sprunk commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Somebody in the future might want to add logging to debug whatever problem they are facing and I'm fairly sure they will just add LOG(...) and (apparently incorrectly) assume it's safe. So prevention via code would ideally somehow address that.

@bruno-dasilva

Copy link
Copy Markdown
Collaborator

@bruno-dasilva, I have a question about where we use logging in multiple threads. It may be easier for us to forbid that from happening.

@lostsquirrel1 two places i saw that emit logs on non-main threads are sound thread and GameServer thread, but there may be more.

Somebody in the future might want to add logging to debug whatever problem they are facing and I'm fairly sure they will just add LOG(...) and (apparently incorrectly) assume it's safe. So prevention via code would ideally somehow address that.

Very good point.

One option is we can log to a per-thread file... but that removes the convenience of a single infolog.

@WybrenKoelmans

Copy link
Copy Markdown
Contributor Author

Note that nearly all logging would still go to the same infolog.txt if we keep that filename for the main thread. The rare logs off the main thread will safely land in a different file not crashing the engine, and still reasonable discoverable. Using a tool like lnav will recombine the logs easily in order (even now I would highly recommend that tool for looking at the logs!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants