88#include < string>
99#include < iostream>
1010#include < filesystem>
11+ #include < fstream>
1112
1213/* *
1314 * @brief Header-only modern thread-safe logger using spdlog library
@@ -55,6 +56,7 @@ class Logger {
5556 std::string pattern; // /< Log message pattern
5657 size_t queueSize; // /< Queue size for async logging
5758 size_t flushInterval; // /< Flush interval in seconds
59+ bool safeFileRotation; // /< Enable safe file rotation (prevents errors)
5860
5961 // Default constructor with default values
6062 Config () :
@@ -66,7 +68,8 @@ class Logger {
6668 maxFiles (5 ),
6769 pattern (" [%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v" ),
6870 queueSize (8192 ),
69- flushInterval (3 ) {}
71+ flushInterval (3 ),
72+ safeFileRotation (true ) {}
7073 };
7174
7275 /* *
@@ -172,7 +175,29 @@ class Logger {
172175 );
173176 file_sink->set_level (convertLevel (config.minLevel ));
174177
175-
178+ // If safe file rotation is enabled, ensure directory exists and handle rotation gracefully
179+ if (config.safeFileRotation ) {
180+ // Ensure the log directory exists and is writable
181+ std::filesystem::path logPath (config.logFilePath );
182+ auto logDir = logPath.parent_path ();
183+ if (!logDir.empty ()) {
184+ try {
185+ if (!std::filesystem::exists (logDir)) {
186+ std::filesystem::create_directories (logDir);
187+ }
188+ // Test write permissions
189+ auto testFile = logDir / " .test_write" ;
190+ std::ofstream testStream (testFile);
191+ if (testStream.is_open ()) {
192+ testStream.close ();
193+ std::filesystem::remove (testFile);
194+ }
195+ } catch (const std::exception& ex) {
196+ // If directory creation fails, fall back to console
197+ std::cerr << " Warning: Could not ensure log directory safety: " << ex.what () << std::endl;
198+ }
199+ }
200+ }
176201
177202 sinks.push_back (file_sink);
178203 } catch (const std::exception& ex) {
0 commit comments