Missing file lock in FileLog::find() and FileLog::pruneBytes() resulting in file error logs
Short description of the issue
I came across this post: https://processwire.com/talk/topic/29851-problem-with-log-pruning in the forum because I was looking for a solution to prevent file errors triggered by WireFileTools::unlink() and WireFileTools::rename()
In my particular case, I use a logger for bots/crawlers that is temporarily activated. The logger includes the function FileLog::pruneBytes(). When activated, the logger is heavily used. It can happen that a PHP thread is open that calls FileLog::pruneBytes() and another thread is opened before the first one has finished. This conflict leads to the errors described above, which are logged in files-error.txt.
After digging a little in the code, I found the following: In the FileLog core class, PHP::fopen() is used in write mode by 3 functions: FileLog::save(), FileLog::find() and FileLog::pruneBytes(). While FileLog::save() has flock() included, which is good programming practice, the other 2 functions do not have flock() included.
Expected behavior
no log entries in file-errors.txt
Always use flock() if a file is opened in write mode.
Optional: Suggestion for a possible fix
For testing purposes, I have extended the FileLog class and rewritten FileLog::save(), FileLog::find() and FileLog::pruneBytes(). I added a function FileLog::lockFile(), which is called by each of the 3 functions to lock the log files, in the way that previously only FileLog::save() did.
Result: Seems to work now as expected no errors anymore. Feel free to test the code. https://github.com/kixe/FileLogExtended/blob/main/FileLogExtended.php
For the future
It I would be great to include pruning / truncating by date, lines or bytes directly in the FileLog::save() operation, triggered by an additional option parameter.
Setup/Environment
- ProcessWire version:
- (Optional) PHP version: 8.3
- (Optional) MySQL version: MariaDB 10.11
- (Optional) Any 3rd party modules that are installed and could be related to the issue:
Any chance to get this fixed?