feat: Implement log file rotation and maximum lines per file in LoggerService

This commit is contained in:
2026-01-05 05:25:46 +00:00
parent fd4d31dfea
commit 11f837a6bf
3 changed files with 90 additions and 12 deletions

View File

@@ -19,15 +19,12 @@ LogLevel LoggerService::GetLevel() const {
void LoggerService::SetOutputFile(const std::string& filename) {
std::lock_guard<std::mutex> lock(impl_->mutex_);
if (impl_->fileStream_) {
impl_->fileStream_->close();
}
impl_->fileStream_ = std::make_unique<std::ofstream>(filename, std::ios::app);
if (!impl_->fileStream_->is_open()) {
// Fallback to console if file can't be opened
std::cerr << "Failed to open log file: " << filename << std::endl;
impl_->fileStream_.reset();
}
impl_->SetOutputFile(filename);
}
void LoggerService::SetMaxLinesPerFile(size_t maxLines) {
std::lock_guard<std::mutex> lock(impl_->mutex_);
impl_->SetMaxLinesPerFile(maxLines);
}
void LoggerService::EnableConsoleOutput(bool enable) {

View File

@@ -3,6 +3,7 @@
#include "../interfaces/i_logger.hpp"
#include <atomic>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <iostream>
@@ -16,12 +17,23 @@ namespace sdl3cpp::services::impl {
// Implementation class that holds all the logging logic
class LoggerImpl {
public:
static constexpr size_t kDefaultMaxLinesPerFile = 10000;
std::atomic<LogLevel> level_;
bool consoleEnabled_;
std::unique_ptr<std::ofstream> fileStream_;
std::mutex mutex_;
std::filesystem::path baseFilePath_;
size_t maxLinesPerFile_;
size_t currentLineCount_;
size_t currentFileIndex_;
LoggerImpl() : level_(LogLevel::INFO), consoleEnabled_(true) {}
LoggerImpl()
: level_(LogLevel::INFO),
consoleEnabled_(true),
maxLinesPerFile_(kDefaultMaxLinesPerFile),
currentLineCount_(0),
currentFileIndex_(0) {}
~LoggerImpl() {
if (fileStream_) {
@@ -66,8 +78,69 @@ public:
if (fileStream_) {
*fileStream_ << message << std::endl;
fileStream_->flush();
++currentLineCount_;
RotateFileIfNeeded();
}
}
void SetOutputFile(const std::string& filename) {
if (fileStream_) {
fileStream_->close();
}
fileStream_.reset();
baseFilePath_ = filename;
currentLineCount_ = 0;
currentFileIndex_ = 0;
if (!baseFilePath_.empty()) {
OpenLogFile(currentFileIndex_);
}
}
void SetMaxLinesPerFile(size_t maxLines) {
maxLinesPerFile_ = maxLines;
}
std::filesystem::path BuildLogFilePath(size_t index) const {
if (baseFilePath_.empty() || index == 0) {
return baseFilePath_;
}
std::filesystem::path basePath(baseFilePath_);
std::string stem = basePath.stem().string();
std::string extension = basePath.extension().string();
std::string rotatedName = stem + "." + std::to_string(index) + extension;
return basePath.parent_path() / rotatedName;
}
void OpenLogFile(size_t index) {
if (baseFilePath_.empty()) {
return;
}
std::filesystem::path logPath = BuildLogFilePath(index);
fileStream_ = std::make_unique<std::ofstream>(logPath, std::ios::out | std::ios::trunc);
if (!fileStream_->is_open()) {
std::cerr << "Failed to open log file: " << logPath.string() << std::endl;
fileStream_.reset();
}
}
void RotateFileIfNeeded() {
if (maxLinesPerFile_ == 0 || currentLineCount_ < maxLinesPerFile_) {
return;
}
if (fileStream_) {
fileStream_->close();
}
++currentFileIndex_;
currentLineCount_ = 0;
OpenLogFile(currentFileIndex_);
}
};
/**
@@ -85,6 +158,7 @@ public:
void SetLevel(LogLevel level) override;
LogLevel GetLevel() const override;
void SetOutputFile(const std::string& filename) override;
void SetMaxLinesPerFile(size_t maxLines) override;
void EnableConsoleOutput(bool enable) override;
void Log(LogLevel level, const std::string& message) override;
void Trace(const std::string& message) override;
@@ -105,4 +179,4 @@ private:
std::unique_ptr<LoggerImpl> impl_;
};
} // namespace sdl3cpp::services::impl
} // namespace sdl3cpp::services::impl

View File

@@ -44,6 +44,13 @@ public:
*/
virtual void SetOutputFile(const std::string& filename) = 0;
/**
* @brief Set the maximum number of log lines per file before rotation.
*
* @param maxLines Max lines per log file, or 0 to disable rotation
*/
virtual void SetMaxLinesPerFile(size_t maxLines) = 0;
/**
* @brief Enable or disable console output.
*
@@ -125,4 +132,4 @@ public:
virtual void TraceVariable(const std::string& name, double value) = 0;
};
} // namespace sdl3cpp::services
} // namespace sdl3cpp::services