Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
base_formatter.h
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
11#pragma once
12
15#include <kcenon/common/interfaces/logger_interface.h>
16#include <sstream>
17#include <iomanip>
18#include <thread>
19
20namespace kcenon::logger {
21
22// Type alias for log_level
23using log_level = common::interfaces::log_level;
24
32public:
33 virtual ~base_formatter() = default;
34
40 virtual std::string format(const log_entry& entry) const override = 0;
41
42protected:
48 std::string level_to_string(log_level level) const {
49 switch (level) {
50 case log_level::critical: return "CRITICAL";
51 case log_level::error: return "ERROR";
52 case log_level::warning: return "WARNING";
53 case log_level::info: return "INFO";
54 case log_level::debug: return "DEBUG";
55 case log_level::trace: return "TRACE";
56 default: return "UNKNOWN";
57 }
58 }
59
65 std::string format_timestamp(const std::chrono::system_clock::time_point& timestamp) const {
66 auto time_t = std::chrono::system_clock::to_time_t(timestamp);
67 std::ostringstream oss;
68 oss << std::put_time(std::gmtime(&time_t), "%Y-%m-%dT%H:%M:%SZ");
69 return oss.str();
70 }
71
76 std::string get_thread_id() const {
77 std::ostringstream oss;
78 oss << std::this_thread::get_id();
79 return oss.str();
80 }
81};
82
88public:
89 std::string format(const log_entry& entry) const override {
90 std::ostringstream oss;
91
92 // Format: [TIMESTAMP] [LEVEL] [THREAD] MESSAGE [FILE:LINE:FUNCTION]
93 oss << "[" << format_timestamp(entry.timestamp) << "] ";
94 oss << "[" << level_to_string(entry.level) << "] ";
95
96 if (entry.thread_id) {
97 oss << "[" << std::string_view(*entry.thread_id) << "] ";
98 } else {
99 oss << "[" << get_thread_id() << "] ";
100 }
101
102 oss << std::string_view(entry.message);
103
104 if (entry.location) {
105 oss << " [" << std::string_view(entry.location->file)
106 << ":" << entry.location->line
107 << ":" << std::string_view(entry.location->function) << "]";
108 }
109
110 return oss.str();
111 }
112
113 std::string get_format_type() const override {
114 return "plain";
115 }
116};
117
122class json_formatter : public base_formatter {
123public:
124 std::string format(const log_entry& entry) const override {
125 std::ostringstream oss;
126
127 oss << "{";
128 oss << "\"timestamp\":\"" << format_timestamp(entry.timestamp) << "\",";
129 oss << "\"level\":\"" << level_to_string(entry.level) << "\",";
130 oss << "\"message\":\"" << escape_json(entry.message) << "\",";
131 oss << "\"thread\":\"" << (entry.thread_id ? std::string(*entry.thread_id) : get_thread_id()) << "\"";
132
133 if (entry.location) {
134 oss << ",\"location\":{";
135 oss << "\"file\":\"" << escape_json(entry.location->file) << "\",";
136 oss << "\"line\":" << entry.location->line << ",";
137 oss << "\"function\":\"" << escape_json(entry.location->function) << "\"";
138 oss << "}";
139 }
140
141 if (entry.category) {
142 oss << ",\"category\":\"" << escape_json(*entry.category) << "\"";
143 }
144
145 oss << "}";
146
147 return oss.str();
148 }
149
150 std::string get_format_type() const override {
151 return "json";
152 }
153
154private:
155 template<typename StringType>
156 std::string escape_json(const StringType& str) const {
157 std::ostringstream escaped;
158 for (unsigned char c : str) {
159 if (c == '"') escaped << "\\\"";
160 else if (c == '\\') escaped << "\\\\";
161 else if (c == '\n') escaped << "\\n";
162 else if (c == '\r') escaped << "\\r";
163 else if (c == '\t') escaped << "\\t";
164 else if (c == '\b') escaped << "\\b";
165 else if (c == '\f') escaped << "\\f";
166 // Escape all other control characters (0x00-0x1F) as \uXXXX
167 else if (c >= 0x00 && c <= 0x1F) {
168 escaped << "\\u"
169 << std::hex << std::setw(4) << std::setfill('0')
170 << static_cast<int>(c);
171 }
172 else escaped << c;
173 }
174 return escaped.str();
175 }
176};
177
183public:
184 std::string format(const log_entry& entry) const override {
185 std::ostringstream oss;
186
187 // Ultra-compact format: LEVEL|MESSAGE
188 oss << level_to_string(entry.level)[0] << "|" << entry.message.to_string();
189
190 return oss.str();
191 }
192
193 std::string get_format_type() const override {
194 return "compact";
195 }
196};
197
198} // namespace kcenon::logger
Base implementation for log formatters.
virtual ~base_formatter()=default
virtual std::string format(const log_entry &entry) const override=0
Format a log entry into a string.
std::string level_to_string(log_level level) const
Convert log level to string.
std::string format_timestamp(const std::chrono::system_clock::time_point &timestamp) const
Format timestamp to ISO8601 string.
std::string get_thread_id() const
Get current thread ID as string.
Compact formatter for minimal output.
std::string format(const log_entry &entry) const override
Format a log entry into a string.
std::string get_format_type() const override
std::string get_format_type() const override
std::string escape_json(const StringType &str) const
std::string format(const log_entry &entry) const override
Format a log entry into a string.
Abstract interface for log message formatters.
Simple plain text formatter.
std::string format(const log_entry &entry) const override
Format a log entry into a string.
std::string get_format_type() const override
std::string to_string() const
Convert to std::string.
Data structures for representing log entries and source locations kcenon.
Interface for log message formatters (Strategy Pattern) kcenon.
common::interfaces::log_level log_level
Represents a single log entry with all associated metadata.
Definition log_entry.h:155
std::optional< source_location > location
Optional source code location information.
Definition log_entry.h:183
std::optional< small_string_64 > thread_id
Optional thread identifier.
Definition log_entry.h:190
log_level level
Severity level of the log message.
Definition log_entry.h:162
std::optional< small_string_128 > category
Optional category for log filtering and routing.
Definition log_entry.h:197
small_string_256 message
The actual log message.
Definition log_entry.h:169
std::chrono::system_clock::time_point timestamp
Timestamp when the log entry was created.
Definition log_entry.h:175