1#ifndef _LOGIT_UNIQUE_FILE_LOGGER_HPP_INCLUDED
2#define _LOGIT_UNIQUE_FILE_LOGGER_HPP_INCLUDED
22#include <unordered_map>
67 const std::string& directory,
69 int auto_delete_days = 30,
70 size_t hash_length = 8) {
89 void log(
const LogRecord& record,
const std::string& message)
override {
93 std::lock_guard<std::mutex> lock(
m_mutex);
103 it->second.last_file_path = file_path;
109 }
catch (
const std::exception& e) {
110 std::cerr <<
"Log error: " << e.what() << std::endl;
121 std::lock_guard<std::mutex> lock(
m_mutex);
123 std::string file_path =
write_log(message, timestamp_ms);
128 it->second.last_file_path = file_path;
130 it->second.pending_logs--;
132 if (it->second.pending_logs == 0) {
138 }
catch (
const std::exception& e) {
139 std::cerr <<
"Async log error: " << e.what() << std::endl;
156 return std::string();
221 std::lock_guard<std::mutex> lock(
m_mutex);
225 }
catch (
const std::exception& e) {
226 std::cerr <<
"Initialization error: " << e.what() << std::endl;
250 std::string
write_log(
const std::string& message,
const int64_t& timestamp_ms) {
252 std::ofstream file(file_path, std::ios_base::binary);
253 if (!file.is_open()) {
254 throw std::runtime_error(
"Failed to open log file: " + file_path);
256 file.write(message.data(), message.size());
274 const auto dt = time_shield::to_date_time_ms<time_shield::DateTimeStruct>(timestamp_ms);
275 char buffer[32] = {0};
276 snprintf(buffer,
sizeof(buffer),
"%lld-%.2d-%.2d_%.2d-%.2d-%.2d-%.3d", dt.year, dt.mon, dt.day, dt.hour, dt.min, dt.sec, dt.ms);
277 return std::string(buffer);
284 static const char charset[] =
286 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
287 "abcdefghijklmnopqrstuvwxyz";
288 static thread_local std::mt19937 generator(std::random_device{}());
289 static thread_local std::uniform_int_distribution<size_t> distribution(0,
sizeof(charset) - 2);
292 hash.reserve(length);
293 for (
size_t i = 0; i < length; ++i) {
294 hash += charset[distribution(generator)];
302# if __cplusplus >= 201703L
304 if (!fs::exists(dir_path) || !fs::is_directory(dir_path)) {
307 for (
const auto& entry : fs::directory_iterator(dir_path)) {
308 if (!fs::is_regular_file(entry.status()))
continue;
309 std::string filename = entry.path().filename().string();
312 if (file_ts < threshold_ts) {
313 fs::remove(entry.path());
319 for (
const auto& file_path : file_list) {
323 if (file_ts < threshold_ts) {
324 remove(file_path.c_str());
335 static const std::regex pattern(R
"((\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}-\d{3})-[a-zA-Z0-9]{1,}\.log)");
336 return std::regex_match(filename, pattern);
343 std::string datetime_str = filename.substr(0, 10);
344 return time_shield::ts(datetime_str);
360 auto thread_id = std::this_thread::get_id();
368 return it->second.last_file_name;
370 return std::string();
380 auto thread_id = std::this_thread::get_id();
388 return it->second.last_file_path;
390 return std::string();
Defines the interface for loggers used in the logging system.
Provides various logging macros for different log levels and options.
Defines the TaskExecutor class, which manages task execution in a separate thread.
Interface for loggers that handle log message output.
void add_task(std::function< void()> task)
Adds a task to the queue in a thread-safe manner.
void wait()
Waits for all tasks in the queue to be processed.
static TaskExecutor & get_instance()
Get the singleton instance of the TaskExecutor.
Writes each log message to a unique file with automatic cleanup.
int64_t current_timestamp_ms() const
Gets the current timestamp in milliseconds.
std::string get_directory_path() const
Gets the full path to the logging directory.
std::string generate_fixed_length_hash(size_t length) const
Generates a fixed-length hash string.
void wait() override
Waits for all asynchronous tasks to complete.
int64_t get_last_log_ts() const
Retrieves the timestamp of the last log.
void initialize_directory()
Initializes the logging directory.
double get_float_param(const LoggerParam ¶m) const override
Retrieves a floating-point parameter from the logger.
std::string get_last_log_file_path() const
Retrieves the last log file path for the calling thread.
std::condition_variable m_pending_logs_cv
Condition variable to wait for pending logs to finish.
virtual ~UniqueFileLogger()
std::unordered_map< std::thread::id, ThreadLogInfo > m_thread_log_info
Map to store log information per thread.
UniqueFileLogger(const std::string &directory, bool async=true, int auto_delete_days=30, size_t hash_length=8)
Constructor with directory and asynchronous flag.
Config m_config
Configuration for the unique file logger.
UniqueFileLogger()
Default constructor that uses default configuration.
UniqueFileLogger(const Config &config)
Constructor with custom configuration.
int64_t get_timestamp_from_filename(const std::string &filename) const
Extracts the timestamp from the filename.
void stop_logging()
Stops the logging process by waiting for tasks.
std::atomic< int64_t > m_last_log_ts
Timestamp of the last log.
std::string get_string_param(const LoggerParam ¶m) const override
Retrieves a string parameter from the logger.
void log(const LogRecord &record, const std::string &message) override
Logs a message to a unique file with thread safety.
std::mutex m_mutex
Mutex to protect file operations.
std::string create_unique_file_path(const int64_t ×tamp_ms) const
Creates a unique file path based on the timestamp and a hash.
std::string format_timestamp(const int64_t ×tamp_ms) const
Formats the timestamp into a string with date and time.
std::string get_last_log_file_name() const
Retrieves the last log file name for the calling thread.
void remove_old_logs()
Removes old log files based on the auto-delete days configuration.
void start_logging()
Starts the logging process by initializing the directory and removing old logs.
int64_t get_int_param(const LoggerParam ¶m) const override
Retrieves an integer parameter from the logger.
std::mutex m_thread_log_info_mutex
Mutex to protect access to thread log information.
int64_t get_time_since_last_log() const
Retrieves the time elapsed since the last log.
std::string write_log(const std::string &message, const int64_t ×tamp_ms)
Writes a log message to a unique file.
bool is_valid_log_filename(const std::string &filename) const
Checks if the filename matches the log file naming pattern.
#define LOGIT_CURRENT_TIMESTAMP_MS()
Macro to get the current timestamp in milliseconds. If LOGIT_CURRENT_TIMESTAMP_MS is not defined,...
The primary namespace for the LogIt++ library.
std::string get_exe_path()
Retrieves the directory of the executable file.
std::vector< std::string > get_list_files(const std::string &path)
Recursively retrieves a list of all files in a directory.
void create_directories(const std::string &path)
Creates directories recursively for the given path.
LoggerParam
Enumeration for different logger parameters that can be retrieved.
@ TimeSinceLastLog
The time elapsed since the last log in seconds.
@ LastLogTimestamp
The timestamp of the last log.
@ LastFileName
The name of the last file written to.
@ LastFilePath
The full path of the last file written to.
std::string get_file_name(const std::string &file_path)
Extracts the file name from a full file path.
Utility functions for path manipulation, including relative path computation.
Stores log metadata and content.
std::thread::id thread_id
ID of the logging thread.
const int64_t timestamp_ms
Timestamp in milliseconds.
Configuration for the unique file logger.
int auto_delete_days
Number of days after which old log files are deleted.
std::string directory
Directory where log files are stored.
bool async
Flag indicating whether logging should be asynchronous.
size_t hash_length
Length of the hash used in filenames.
std::string last_file_path
ThreadLogInfo(const int pending_logs, const std::string last_file_path, const std::string last_file_name)
std::string last_file_name