Skip to content

Commit 2c1fc2b

Browse files
author
Omer Bulut
committed
FreshLogger: fix unit-test segfault, remove unused config, RAII stderr guard; silence edge-case console output; all tests green locally
1 parent cba7c45 commit 2c1fc2b

2 files changed

Lines changed: 34 additions & 32 deletions

File tree

EdgeCaseTests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ TEST_F(EdgeCaseTest, ExtremelyLongMessages) {
3838
Logger::Config config;
3939
config.logFilePath = "edge_test_logs/long_messages.log";
4040
config.asyncLogging = false;
41+
config.consoleOutput = false;
4142

4243
Logger logger(config);
4344

@@ -58,6 +59,7 @@ TEST_F(EdgeCaseTest, EmptyMessages) {
5859
Logger::Config config;
5960
config.logFilePath = "edge_test_logs/empty_messages.log";
6061
config.asyncLogging = false;
62+
config.consoleOutput = false;
6163

6264
Logger logger(config);
6365

@@ -76,6 +78,7 @@ TEST_F(EdgeCaseTest, SpecialCharacters) {
7678
Logger::Config config;
7779
config.logFilePath = "edge_test_logs/special_chars.log";
7880
config.asyncLogging = false;
81+
config.consoleOutput = false;
7982

8083
Logger logger(config);
8184

@@ -95,6 +98,7 @@ TEST_F(EdgeCaseTest, UnicodeCharacters) {
9598
Logger::Config config;
9699
config.logFilePath = "edge_test_logs/unicode.log";
97100
config.asyncLogging = false;
101+
config.consoleOutput = false;
98102

99103
Logger logger(config);
100104

@@ -115,6 +119,7 @@ TEST_F(EdgeCaseTest, VeryHighFrequencyLogging) {
115119
config.logFilePath = "edge_test_logs/high_freq.log";
116120
config.asyncLogging = true;
117121
config.queueSize = 100000; // Large queue
122+
config.consoleOutput = false;
118123

119124
Logger logger(config);
120125

@@ -144,6 +149,7 @@ TEST_F(EdgeCaseTest, ConfigurationEdgeCases) {
144149
config.maxFileSize = 100; // 100 bytes - very small
145150
config.maxFiles = 1; // Only 1 file
146151
config.asyncLogging = false;
152+
config.consoleOutput = false;
147153

148154
Logger logger(config);
149155

@@ -162,6 +168,7 @@ TEST_F(EdgeCaseTest, MemoryBoundaryConditions) {
162168
Logger::Config config;
163169
config.logFilePath = "edge_test_logs/memory_test.log";
164170
config.asyncLogging = false;
171+
config.consoleOutput = false;
165172

166173
Logger logger(config);
167174

@@ -190,6 +197,7 @@ TEST_F(EdgeCaseTest, ExtremeThreadSafety) {
190197
config.logFilePath = "edge_test_logs/extreme_threads.log";
191198
config.asyncLogging = true;
192199
config.queueSize = 50000;
200+
config.consoleOutput = false;
193201

194202
Logger logger(config);
195203

@@ -246,6 +254,7 @@ TEST_F(EdgeCaseTest, FileSystemEdgeCases) {
246254
Logger::Config config;
247255
config.logFilePath = longPath;
248256
config.asyncLogging = false;
257+
config.consoleOutput = false;
249258

250259
Logger logger(config);
251260

@@ -262,6 +271,7 @@ TEST_F(EdgeCaseTest, PerformanceUnderMemoryPressure) {
262271
config.logFilePath = "edge_test_logs/memory_pressure.log";
263272
config.asyncLogging = true;
264273
config.queueSize = 1000; // Smaller queue to create pressure
274+
config.consoleOutput = false;
265275

266276
Logger logger(config);
267277

Logger.hpp

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,20 @@
3232
namespace {
3333
struct SpdlogErrorHandlerInitializer {
3434
SpdlogErrorHandlerInitializer() {
35-
// Set spdlog to be completely silent about file rotation issues
36-
spdlog::set_error_handler([](const std::string& msg) {
37-
// Suppress ALL spdlog errors to avoid CI/CD noise
38-
// This is intentional for production stability
39-
});
40-
41-
// Set global log level to critical only
42-
spdlog::set_level(spdlog::level::critical);
35+
try {
36+
// Set spdlog to be completely silent about file rotation issues
37+
spdlog::set_error_handler([](const std::string&) {
38+
// Suppress ALL spdlog errors to avoid CI/CD noise
39+
// This is intentional for production stability
40+
});
41+
42+
// Set global log level to critical only
43+
spdlog::set_level(spdlog::level::critical);
44+
} catch (...) {
45+
// Ignore any initialization errors
46+
}
4347
}
48+
4449
};
4550

4651
// Static instance to ensure error handler is set before any logger creation
@@ -74,7 +79,6 @@ class Logger {
7479
std::string pattern; ///< Log message pattern
7580
size_t queueSize; ///< Queue size for async logging
7681
size_t flushInterval; ///< Flush interval in seconds
77-
bool safeFileRotation; ///< Enable safe file rotation (prevents errors)
7882

7983
// Default constructor with default values
8084
Config() :
@@ -86,8 +90,7 @@ class Logger {
8690
maxFiles(5),
8791
pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v"),
8892
queueSize(8192),
89-
flushInterval(3),
90-
safeFileRotation(true) {}
93+
flushInterval(3) {}
9194
};
9295

9396
/**
@@ -179,14 +182,15 @@ class Logger {
179182
// File sink setup
180183
if (!config.logFilePath.empty()) {
181184
try {
182-
// Suppress spdlog file rotation errors by setting environment variables
183-
setenv("SPDLOG_LEVEL", "error", 1); // Only show errors, not warnings
184-
setenv("SPDLOG_ERROR_LEVEL", "critical", 1); // Only show critical errors
185-
186185
// Temporarily redirect stderr to suppress file rotation errors
187186
std::stringstream buffer;
188-
std::streambuf* old_stderr = std::cerr.rdbuf();
189-
std::cerr.rdbuf(buffer.rdbuf());
187+
struct StderrRedirectGuard {
188+
std::ostream& stream;
189+
std::streambuf* old;
190+
explicit StderrRedirectGuard(std::ostream& s, std::streambuf* nb)
191+
: stream(s), old(s.rdbuf(nb)) {}
192+
~StderrRedirectGuard() { stream.rdbuf(old); }
193+
} guard(std::cerr, buffer.rdbuf());
190194

191195
// Ensure directory exists and is writable
192196
std::filesystem::path logPath(config.logFilePath);
@@ -210,8 +214,7 @@ class Logger {
210214
throw std::runtime_error("Cannot create test file in log directory");
211215
}
212216
} catch (const std::exception& ex) {
213-
// Restore stderr before printing warning
214-
std::cerr.rdbuf(old_stderr);
217+
// stderr will be restored by guard destructor
215218
std::cerr << "Warning: Log directory not writable: " << logDir << " - " << ex.what() << std::endl;
216219
// Fall back to console only
217220
if (sinks.empty()) {
@@ -233,8 +236,7 @@ class Logger {
233236

234237
sinks.push_back(file_sink);
235238

236-
// Restore stderr after file sink creation
237-
std::cerr.rdbuf(old_stderr);
239+
// stderr will be restored automatically when guard goes out of scope
238240

239241
} catch (const std::exception& ex) {
240242
// Fallback to console if file creation fails
@@ -306,17 +308,7 @@ class Logger {
306308
}
307309
}
308310

309-
LogLevel convertLevel(spdlog::level::level_enum level) const {
310-
switch (level) {
311-
case spdlog::level::trace: return LogLevel::TRACE;
312-
case spdlog::level::debug: return LogLevel::DEBUG;
313-
case spdlog::level::info: return LogLevel::INFO;
314-
case spdlog::level::warn: return LogLevel::WARNING;
315-
case spdlog::level::err: return LogLevel::ERROR;
316-
case spdlog::level::critical: return LogLevel::FATAL;
317-
default: return LogLevel::INFO;
318-
}
319-
}
311+
320312

321313
std::shared_ptr<spdlog::logger> m_logger; ///< Underlying spdlog logger instance
322314
Config m_config; ///< Current logger configuration

0 commit comments

Comments
 (0)