mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 21:55:09 +00:00
feat: Implement log file rotation and maximum lines per file in LoggerService
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user