Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
logger_adapter.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
5#include "logger_adapter.h"
9
10// Include common_system backend if available
11// HAVE_COMMON_LOGGER_BACKEND is defined by CMake when common_logger_backend.cpp is compiled
12#ifdef HAVE_COMMON_LOGGER_BACKEND
14#endif
15
16#include <algorithm>
17#include <sstream>
18
19namespace database
20{
21namespace integrated
22{
23namespace adapters
24{
25
26// ═══════════════════════════════════════════════════════════════
27// Helper Functions
28// ═══════════════════════════════════════════════════════════════
29
30namespace
31{
32
38std::string sanitize_query(const std::string& query)
39{
40 std::string sanitized = query;
41
42 // Remove password patterns
43 const std::string patterns[]
44 = { "PASSWORD '", "PASSWORD=", "password '", "password=", "PWD=", "pwd=" };
45
46 for (const auto& pattern : patterns)
47 {
48 size_t pos = sanitized.find(pattern);
49 if (pos != std::string::npos)
50 {
51 size_t end = sanitized.find_first_of("' \t\n;", pos + pattern.length());
52 if (end != std::string::npos)
53 {
54 sanitized.replace(pos + pattern.length(), end - (pos + pattern.length()), "***");
55 }
56 }
57 }
58
59 // Truncate if too long
60 const size_t max_length = 500;
61 if (sanitized.length() > max_length)
62 {
63 sanitized = sanitized.substr(0, max_length) + "... [truncated]";
64 }
65
66 return sanitized;
67}
68
69} // anonymous namespace
70
71// ═══════════════════════════════════════════════════════════════
72// Backend Factory
73// ═══════════════════════════════════════════════════════════════
74
75std::unique_ptr<backends::logger_backend> logger_adapter::create_backend(
76 const db_logger_config& config,
78{
79 switch (backend_type)
80 {
82 {
83#ifdef HAVE_COMMON_LOGGER_BACKEND
84 // Try common_system backend first
85 try
86 {
87 auto backend = std::make_unique<backends::common_logger_backend>(config);
88 auto init_result = backend->initialize();
89 if (init_result.is_ok())
90 {
91 return backend;
92 }
93 // If initialization failed, fall back to fallback backend
94 }
95 catch (...)
96 {
97 // If common backend construction/init failed, fall back
98 }
99#endif
100 // Fall back to fallback_logger_backend
101 return std::make_unique<backends::fallback_logger_backend>(config);
102 }
103
105 {
106#ifdef HAVE_COMMON_LOGGER_BACKEND
107 return std::make_unique<backends::common_logger_backend>(config);
108#else
109 throw std::runtime_error(
110 "common_logger_backend not available (common_system not found)");
111#endif
112 }
113
115 return std::make_unique<backends::fallback_logger_backend>(config);
116
118 return std::make_unique<backends::null_logger_backend>(config);
119
120 default:
121 return std::make_unique<backends::fallback_logger_backend>(config);
122 }
123}
124
125// ═══════════════════════════════════════════════════════════════
126// Public Interface Implementation
127// ═══════════════════════════════════════════════════════════════
128
130 const db_logger_config& config,
132 : config_(config)
133 , backend_(create_backend(config, backend_type))
134{
135 // Backend is created and potentially initialized (if auto_select)
136 // If auto_select didn't initialize, caller must call initialize()
138 {
139 // For explicit backend selection, don't auto-initialize
140 // Caller must call initialize() explicitly
141 }
142}
143
145{
146 if (backend_ && backend_->is_initialized())
147 {
148 backend_->shutdown();
149 }
150}
151
153
155{
156 if (!backend_)
157 {
158 return common::VoidResult(
159 common::error_info{ -1, "Backend not created", "" });
160 }
161
162 return backend_->initialize();
163}
164
166{
167 if (!backend_)
168 {
169 return common::ok();
170 }
171
172 return backend_->shutdown();
173}
174
176{
177 return backend_ && backend_->is_initialized();
178}
179
180// ═══════════════════════════════════════════════════════════════
181// Database-Specific Logging
182// ═══════════════════════════════════════════════════════════════
183
185 db_log_level level, const std::string& query, std::chrono::microseconds duration)
186{
187 if (!backend_)
188 {
189 return;
190 }
191
192 // Sanitize query
193 std::string safe_query = sanitize_query(query);
194
195 // Format message
196 std::stringstream ss;
197 ss << "Query executed in " << duration.count() << "Ξs: " << safe_query;
198
199 backend_->log(level, ss.str());
200
201 // Check for slow query
202 auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
204 {
206 }
207}
208
209void logger_adapter::log_slow_query(const std::string& query, std::chrono::microseconds duration,
210 std::chrono::milliseconds threshold)
211{
212 if (!backend_)
213 {
214 return;
215 }
216
217 std::string safe_query = sanitize_query(query);
218
219 std::stringstream ss;
220 ss << "SLOW QUERY detected (threshold: " << threshold.count() << "ms, actual: "
221 << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()
222 << "ms): " << safe_query;
223
224 backend_->log(db_log_level::warning, ss.str());
225}
226
227void logger_adapter::log_connection_event(const std::string& event, const std::string& details)
228{
229 if (!backend_)
230 {
231 return;
232 }
233
234 std::stringstream ss;
235 ss << "Connection event [" << event << "]: " << details;
236
237 backend_->log(db_log_level::debug, ss.str());
238}
239
241 const std::string& operation, bool success, const std::string& details)
242{
243 if (!backend_)
244 {
245 return;
246 }
247
248 std::stringstream ss;
249 ss << "Transaction " << operation << " " << (success ? "SUCCESS" : "FAILED");
250 if (!details.empty())
251 {
252 ss << ": " << details;
253 }
254
256}
257
258void logger_adapter::log_pool_event(const std::string& event, std::size_t active, std::size_t idle)
259{
260 if (!backend_)
261 {
262 return;
263 }
264
265 std::stringstream ss;
266 ss << "Pool event [" << event << "]: active=" << active << ", idle=" << idle
267 << ", total=" << (active + idle);
268
269 backend_->log(db_log_level::info, ss.str());
270}
271
273 const std::string& operation, const std::string& error_msg, const std::string& sql_state)
274{
275 if (!backend_)
276 {
277 return;
278 }
279
280 std::stringstream ss;
281 ss << "ERROR in " << operation << ": " << error_msg;
282 if (!sql_state.empty())
283 {
284 ss << " (SQL state: " << sql_state << ")";
285 }
286
287 backend_->log(db_log_level::error, ss.str());
288}
289
290void logger_adapter::log(db_log_level level, const std::string& message)
291{
292 if (backend_)
293 {
294 backend_->log(level, message);
295 }
296}
297
299{
300 if (backend_)
301 {
302 backend_->flush();
303 }
304}
305
306} // namespace adapters
307} // namespace integrated
308} // namespace database
Unified logging adapter for database operations.
void log_query(db_log_level level, const std::string &query, std::chrono::microseconds duration)
Log a SQL query execution.
common::VoidResult initialize()
Initialize the logger.
logger_adapter(const db_logger_config &config, logger_backend_type backend_type=logger_backend_type::auto_select)
Construct logger adapter with configuration.
void log_slow_query(const std::string &query, std::chrono::microseconds duration, std::chrono::milliseconds threshold)
Log a slow query with warning.
void log_transaction(const std::string &operation, bool success, const std::string &details)
Log a transaction operation.
void log_connection_event(const std::string &event, const std::string &details)
Log a connection pool event.
common::VoidResult shutdown()
Shutdown the logger gracefully.
void log_pool_event(const std::string &event, std::size_t active, std::size_t idle)
Log a connection pool state change.
void log(db_log_level level, const std::string &message)
Generic log message.
static std::unique_ptr< backends::logger_backend > create_backend(const db_logger_config &config, logger_backend_type backend_type)
Create appropriate backend based on type.
void flush()
Flush pending log messages.
void log_error(const std::string &operation, const std::string &error_msg, const std::string &sql_state="")
Log a database error.
std::unique_ptr< backends::logger_backend > backend_
Logger backend implementation.
bool is_initialized() const
Check if logger is initialized.
~logger_adapter()
Destructor - ensures proper shutdown.
Logger backend using common_system's ILogger and GlobalLoggerRegistry.
Fallback logger backend using std::cout and std::ofstream.
Database logging adapter with runtime backend selection.
Abstract interface for logger backends.
VoidResult ok()
Result< std::monostate > VoidResult
logger_backend_type
Logger backend type selection.
@ null
No-op backend (discard all logs)
@ auto_select
Automatically select best available backend.
@ system
Use common_system ILogger (fails if unavailable)
db_log_level
Database logging level enumeration.
@ debug
Debug information for development.
@ info
Informational messages (default)
static std::shared_ptr< core::database_backend > create_backend(backend_type type)
Create database backend instance.
backend_type
Database backend type enumeration.
kcenon::common::VoidResult VoidResult
Primary VoidResult type - use this for void operations.
Definition result.h:33
Null logger backend (no-op)
std::chrono::milliseconds slow_query_threshold
Threshold for considering a query "slow".
bool log_slow_queries
Automatically detect and log slow queries.