Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
file_writer.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
9#include <filesystem>
10#include <iostream>
11
12namespace kcenon::logger {
13
14file_writer::file_writer(const std::string& filename,
15 bool append,
16 std::unique_ptr<log_formatter_interface> formatter)
17 : filename_(filename)
18 , append_mode_(append)
19 , formatter_(formatter ? std::move(formatter) : std::make_unique<timestamp_formatter>()) {
20 std::lock_guard<std::mutex> lock(mutex_);
22}
23
25 std::lock_guard<std::mutex> lock(mutex_);
27}
28
30 std::lock_guard<std::mutex> lock(mutex_);
31
33 // Check precondition
34 if (!is_open_) {
36 }
37
38 // Format and write
39 std::string formatted = format_entry(entry);
40 file_stream_ << formatted << '\n';
41 bytes_written_.fetch_add(formatted.size() + 1); // +1 for newline
42
43 // Verify stream state
45 });
46}
47
49 std::lock_guard<std::mutex> lock(mutex_);
50
52 if (is_open_) {
53 file_stream_.flush();
55 }
56 return common::ok();
58}
59
61 std::lock_guard<std::mutex> lock(mutex_);
63 return common::ok();
64}
65
67 return is_open_ && file_stream_.good();
68}
69
70std::string file_writer::format_entry(const log_entry& entry) const {
71 if (!formatter_) {
72 // Fallback if formatter is somehow null
73 return entry.message.to_string();
74 }
75 return formatter_->format(entry);
76}
77
79 // IMPORTANT: Caller must hold the mutex before calling this method
80
82 // Create directory if it doesn't exist
83 std::filesystem::path file_path(filename_);
84 std::filesystem::path dir = file_path.parent_path();
85
86 auto dir_result = utils::ensure_directory_exists(dir);
87 if (dir_result.is_err()) return dir_result;
88
89 // Open file
90 auto mode = append_mode_ ? std::ios::app : std::ios::trunc;
91 file_stream_.open(filename_, std::ios::out | mode);
92
93 // Check if file opened successfully
94 auto check = utils::check_condition(
95 file_stream_.is_open(),
97 "Failed to open file: " + filename_
98 );
99 if (check.is_err()) return check;
100
101 // Get current file size if appending
102 if (append_mode_) {
103 file_stream_.seekp(0, std::ios::end);
105 } else {
106 bytes_written_ = 0;
107 }
108
109 is_open_ = true;
110 return common::ok();
111 });
112}
113
115 // IMPORTANT: Caller must hold the mutex before calling this method
116
117 if (is_open_) {
118 if (file_stream_.is_open()) {
119 file_stream_.flush();
120 file_stream_.close();
121 }
122 is_open_ = false;
123 }
124}
125
126} // namespace kcenon::logger
~file_writer() override
Destructor.
common::VoidResult open_internal()
Open the file (internal, caller must hold mutex)
void close_internal()
Close the file (internal, caller must hold mutex)
std::unique_ptr< log_formatter_interface > formatter_
common::VoidResult write(const log_entry &entry) override
Write a log entry to file.
file_writer(const std::string &filename, bool append=true, std::unique_ptr< log_formatter_interface > formatter=nullptr)
Constructor.
std::atomic< size_t > bytes_written_
std::string format_entry(const log_entry &entry) const
Format a log entry using the current formatter.
std::atomic< bool > is_open_
common::VoidResult close() override
Close the file.
bool is_healthy() const override
Check if writer is healthy.
common::VoidResult flush() override
Flush file stream.
std::string to_string() const
Convert to std::string.
Default formatter with human-readable timestamp format.
Structured error context for debugging log system failures.
File writer for logging to files with optional buffering.
Data structures for representing log entries and source locations kcenon.
VoidResult ok()
common::VoidResult check_stream_state(const Stream &stream, const std::string &operation_name="operation")
Stream state verification helper.
common::VoidResult try_open_operation(F &&operation)
Error handling helper for file open operations.
common::VoidResult try_write_operation(F &&operation, logger_error_code default_error_code=logger_error_code::file_write_failed)
Error handling helper for write operations.
common::VoidResult check_condition(bool condition, logger_error_code error_code, const std::string &message)
Condition verification helper.
common::VoidResult ensure_directory_exists(const std::filesystem::path &dir)
Directory creation helper.
common::VoidResult make_logger_void_result(logger_error_code code, const std::string &message="")
Represents a single log entry with all associated metadata.
Definition log_entry.h:155
small_string_256 message
The actual log message.
Definition log_entry.h:169
Default human-readable formatter with timestamps kcenon.