Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
custom_writer_example.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
24#include <kcenon/common/interfaces/logger_interface.h>
25#include <iostream>
26#include <vector>
27#include <map>
28
29using namespace kcenon::logger;
30namespace ci = kcenon::common::interfaces;
31
45public:
46 memory_writer() = default;
47
48 std::string get_name() const override {
49 return "memory";
50 }
51
59 std::vector<std::string> get_entries() const {
60 std::lock_guard<std::mutex> lock(get_mutex());
61 return entries_;
62 }
63
67 size_t size() const {
68 std::lock_guard<std::mutex> lock(get_mutex());
69 return entries_.size();
70 }
71
75 void clear() {
76 std::lock_guard<std::mutex> lock(get_mutex());
77 entries_.clear();
78 }
79
80protected:
91 {
92 std::string formatted = format_log_entry(entry);
93
94 // Store in memory - already protected by base class mutex
95 entries_.push_back(formatted);
96
97 return kcenon::common::ok();
98 }
99
107 // Nothing to flush for memory storage
108 return kcenon::common::ok();
109 }
110
111private:
112 std::vector<std::string> entries_;
113};
114
122public:
124 // Initialize counters for each log level
125 for (int i = 0; i <= static_cast<int>(kcenon::common::interfaces::log_level::trace); ++i) {
126 counts_[static_cast<kcenon::common::interfaces::log_level>(i)] = 0;
127 }
128 }
129
130 std::string get_name() const override {
131 return "counted_console";
132 }
133
137 size_t get_count(kcenon::common::interfaces::log_level level) const {
138 std::lock_guard<std::mutex> lock(get_mutex());
139 auto it = counts_.find(level);
140 return (it != counts_.end()) ? it->second : 0;
141 }
142
146 size_t total_count() const {
147 std::lock_guard<std::mutex> lock(get_mutex());
148 size_t total = 0;
149 for (const auto& [level, count] : counts_) {
150 total += count;
151 }
152 return total;
153 }
154
158 void print_stats() const {
159 std::lock_guard<std::mutex> lock(get_mutex());
160 std::cout << "\n=== Log Statistics ===" << std::endl;
161 std::cout << "Fatal: " << counts_.at(kcenon::common::interfaces::log_level::fatal) << std::endl;
162 std::cout << "Error: " << counts_.at(kcenon::common::interfaces::log_level::error) << std::endl;
163 std::cout << "Warning: " << counts_.at(kcenon::common::interfaces::log_level::warning) << std::endl;
164 std::cout << "Info: " << counts_.at(kcenon::common::interfaces::log_level::info) << std::endl;
165 std::cout << "Debug: " << counts_.at(kcenon::common::interfaces::log_level::debug) << std::endl;
166 std::cout << "Trace: " << counts_.at(kcenon::common::interfaces::log_level::trace) << std::endl;
167 }
168
169protected:
171 {
172 // Convert log_level from logger_system to common::interfaces
173 auto level = static_cast<kcenon::common::interfaces::log_level>(static_cast<int>(entry.level));
174
175 // Increment counter for this level
176 counts_[level]++;
177
178 // Format log entry
179 std::string formatted = format_log_entry(entry);
180
181 // Output to console with color based on level
182 if (use_color()) {
183 switch (level) {
184 case kcenon::common::interfaces::log_level::fatal:
185 case kcenon::common::interfaces::log_level::error:
186 std::cerr << "\033[31m" << formatted << "\033[0m" << std::endl;
187 break;
188 case kcenon::common::interfaces::log_level::warning:
189 std::cout << "\033[33m" << formatted << "\033[0m" << std::endl;
190 break;
191 default:
192 std::cout << formatted << std::endl;
193 break;
194 }
195 } else {
196 if (level <= kcenon::common::interfaces::log_level::error) {
197 std::cerr << formatted << std::endl;
198 } else {
199 std::cout << formatted << std::endl;
200 }
201 }
202
203 return kcenon::common::ok();
204 }
205
207 std::cout.flush();
208 std::cerr.flush();
209 return kcenon::common::ok();
210 }
211
212private:
213 mutable std::map<kcenon::common::interfaces::log_level, size_t> counts_;
214};
215
216int main() {
217 std::cout << "=== Custom Writer Example (thread_safe_writer) ===" << std::endl;
218 std::cout << std::endl;
219
220 // Example 1: Memory Writer
221 std::cout << "--- Example 1: Memory Writer ---" << std::endl;
222 {
223 auto result = logger_builder()
224 .with_min_level(kcenon::common::interfaces::log_level::info)
225 .add_writer("memory", std::make_unique<memory_writer>())
226 .build();
227
228 if (!result.has_value()) {
229 std::cerr << "Failed to create logger" << std::endl;
230 return 1;
231 }
232
233 auto logger = std::move(result.value());
234
235 // Log some messages
236 logger->log(ci::log_level::info, std::string("First message"));
237 logger->log(ci::log_level::warning, std::string("Second message"));
238 logger->log(ci::log_level::error, std::string("Third message"));
239
240 std::cout << "Logged 3 messages to memory writer" << std::endl;
241 }
242
243 std::cout << std::endl;
244
245 // Example 2: Counted Console Writer
246 std::cout << "--- Example 2: Counted Console Writer ---" << std::endl;
247 {
248 auto counted_writer = std::make_unique<counted_console_writer>();
249 auto* counted_ptr = counted_writer.get(); // Keep reference for stats
250
251 auto result = logger_builder()
252 .with_min_level(kcenon::common::interfaces::log_level::debug)
253 .add_writer("counted", std::move(counted_writer))
254 .build();
255
256 if (!result.has_value()) {
257 std::cerr << "Failed to create logger" << std::endl;
258 return 1;
259 }
260
261 auto logger = std::move(result.value());
262
263 // Log messages at different levels
264 logger->log(ci::log_level::debug, std::string("Debug message 1"));
265 logger->log(ci::log_level::debug, std::string("Debug message 2"));
266 logger->log(ci::log_level::info, std::string("Info message"));
267 logger->log(ci::log_level::warning, std::string("Warning message"));
268 logger->log(ci::log_level::error, std::string("Error message"));
269
270 // Print statistics
271 counted_ptr->print_stats();
272 }
273
274 std::cout << std::endl;
275 std::cout << "=== Custom Writer Example Complete ===" << std::endl;
276
277 return 0;
278}
A console writer that counts messages per log level.
kcenon::common::VoidResult flush_impl() override
Implementation of flush operation (override in derived classes)
std::string get_name() const override
kcenon::common::VoidResult write_entry_impl(const log_entry &entry) override
Implementation of structured write operation (override in derived classes)
size_t total_count() const
Get total message count.
void print_stats() const
Print statistics summary.
size_t get_count(kcenon::common::interfaces::log_level level) const
Get count for a specific log level.
std::map< kcenon::common::interfaces::log_level, size_t > counts_
std::string format_log_entry(const log_entry &entry) const
Format a log entry using the current formatter.
bool use_color() const
Get current color output setting.
Builder pattern for logger construction with validation.
logger_builder & with_min_level(log_level level)
result< std::unique_ptr< logger > > build()
logger_builder & add_writer(const std::string &name, log_writer_ptr writer)
Add a writer to the logger.
Base class providing automatic thread-safety for writer implementations.
std::mutex & get_mutex() const
Access the writer mutex for extended operations.
A custom writer that stores log entries in memory.
kcenon::common::VoidResult flush_impl() override
Implementation of flush operation.
std::vector< std::string > entries_
size_t size() const
Get count of stored entries.
kcenon::common::VoidResult write_entry_impl(const log_entry &entry) override
Implementation of write operation.
memory_writer()=default
std::vector< std::string > get_entries() const
Get all stored log entries.
std::string get_name() const override
void clear()
Clear all stored entries.
Console writer for logging to stdout/stderr.
JSON formatter for structured logging kcenon.
Data structures for representing log entries and source locations kcenon.
Builder pattern implementation for flexible logger configuration kcenon.
VoidResult ok()
Represents a single log entry with all associated metadata.
Definition log_entry.h:155
log_level level
Severity level of the log message.
Definition log_entry.h:162
Thread-safe base class for writer implementations kcenon.