Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
monitoring.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
21#include <iostream>
22#include <iomanip>
23#include <thread>
24#include <chrono>
25
26using namespace database::integrated;
27using namespace std::chrono;
28
29void print_header(const std::string& title) {
30 std::cout << "\n" << std::string(70, '=') << "\n";
31 std::cout << title << "\n";
32 std::cout << std::string(70, '=') << "\n\n";
33}
34
36 std::cout << std::string(70, '-') << "\n";
37}
38
42void print_health_check(const health_check& health, bool detailed = true) {
43 std::cout << "Health Check Report:\n";
45
46 std::cout << " Overall Status: ";
47 switch (health.status) {
48 case health_status::healthy:
49 std::cout << "āœ… Healthy\n";
50 break;
51 case health_status::degraded:
52 std::cout << "āš ļø Degraded\n";
53 break;
54 case health_status::failed:
55 std::cout << "āŒ Failed\n";
56 break;
57 case health_status::critical:
58 std::cout << "šŸ”„ Critical\n";
59 break;
60 default:
61 std::cout << "ā“ Unknown\n";
62 }
63
64 std::cout << " Database Connected: " << (health.is_connected ? "Yes āœ“" : "No āœ—") << "\n";
65
66 if (detailed) {
67 std::cout << "\n Component Health:\n";
68 std::cout << " Logger: " << (health.logger_healthy ? "āœ“ Healthy" : "āœ— Unhealthy") << "\n";
69 std::cout << " Monitor: " << (health.monitor_healthy ? "āœ“ Healthy" : "āœ— Unhealthy") << "\n";
70 std::cout << " Thread Pool: " << (health.thread_pool_healthy ? "āœ“ Healthy" : "āœ— Unhealthy") << "\n";
71
72 std::cout << "\n Connection Pool:\n";
73 std::cout << " Utilization: " << std::fixed << std::setprecision(1)
74 << (health.connection_pool_utilization * 100) << "%\n";
75 std::cout << " Healthy: " << (health.connection_pool_healthy ? "Yes" : "No") << "\n";
76
77 if (!health.issues.empty()) {
78 std::cout << "\n āš ļø Issues Detected:\n";
79 for (const auto& issue : health.issues) {
80 std::cout << " - " << issue << "\n";
81 }
82 }
83 }
84
86}
87
91void print_metrics(const database_metrics& metrics, bool detailed = true) {
92 std::cout << "Database Metrics:\n";
94
95 std::cout << " Query Statistics:\n";
96 std::cout << " Total Queries: " << std::setw(10) << metrics.total_queries << "\n";
97 std::cout << " Successful: " << std::setw(10) << metrics.successful_queries << "\n";
98 std::cout << " Failed: " << std::setw(10) << metrics.failed_queries << "\n";
99
100 if (metrics.total_queries > 0) {
101 double success_rate = (static_cast<double>(metrics.successful_queries) / metrics.total_queries) * 100;
102 std::cout << " Success Rate: " << std::fixed << std::setprecision(2)
103 << std::setw(9) << success_rate << " %\n";
104 }
105
106 std::cout << "\n Performance:\n";
107 std::cout << " Queries/sec: " << std::fixed << std::setprecision(2)
108 << std::setw(10) << metrics.queries_per_second << "\n";
109 std::cout << " Avg Latency: " << std::fixed << std::setprecision(3)
110 << std::setw(10) << (metrics.average_latency.count() / 1000.0) << " ms\n";
111 std::cout << " Min Latency: " << std::fixed << std::setprecision(3)
112 << std::setw(10) << (metrics.min_latency.count() / 1000.0) << " ms\n";
113 std::cout << " Max Latency: " << std::fixed << std::setprecision(3)
114 << std::setw(10) << (metrics.max_latency.count() / 1000.0) << " ms\n";
115
116 if (detailed) {
117 std::cout << "\n Connection Pool:\n";
118 std::cout << " Pool Size: " << std::setw(10) << metrics.pool_size << "\n";
119 std::cout << " Active: " << std::setw(10) << metrics.active_connections << "\n";
120 std::cout << " Idle: " << std::setw(10) << metrics.idle_connections << "\n";
121 std::cout << " Wait Queue: " << std::setw(10) << metrics.wait_queue_size << "\n";
122
123 std::cout << "\n Transactions:\n";
124 std::cout << " Started: " << std::setw(10) << metrics.transactions_started << "\n";
125 std::cout << " Committed: " << std::setw(10) << metrics.transactions_committed << "\n";
126 std::cout << " Rolled Back: " << std::setw(10) << metrics.transactions_rolled_back << "\n";
127 }
128
130}
131
136 print_header("Example 1: Real-Time Monitoring");
137
138 std::cout << "Monitoring database for 10 seconds...\n";
139 std::cout << "Press Ctrl+C to stop\n\n";
140
141 const int duration_seconds = 10;
142 const int interval_ms = 1000;
143
144 for (int i = 0; i < duration_seconds; ++i) {
145 auto metrics = db.get_metrics();
146
147 std::cout << "[" << std::setw(2) << (i + 1) << "s] "
148 << "QPS: " << std::fixed << std::setprecision(1) << std::setw(6)
149 << metrics.queries_per_second
150 << " | Latency: " << std::fixed << std::setprecision(3) << std::setw(8)
151 << (metrics.average_latency.count() / 1000.0) << " ms"
152 << " | Active: " << std::setw(2) << metrics.active_connections
153 << " | Idle: " << std::setw(2) << metrics.idle_connections
154 << " | Total: " << std::setw(4) << metrics.total_queries
155 << "\n";
156
157 std::this_thread::sleep_for(milliseconds(interval_ms));
158 }
159
160 std::cout << "\nāœ… Monitoring complete\n";
161}
162
167 print_header("Example 2: Health Check Monitoring");
168
169 std::cout << "Performing periodic health checks...\n\n";
170
171 for (int i = 0; i < 3; ++i) {
172 std::cout << "Health Check #" << (i + 1) << ":\n";
173
174 auto health = db.check_health();
175 print_health_check(health, false);
176
177 if (i < 2) {
178 std::this_thread::sleep_for(seconds(2));
179 }
180 }
181
182 std::cout << "\nāœ… Health checks complete\n";
183}
184
189 print_header("Example 3: Performance Profiling");
190
191 std::cout << "Running performance test...\n";
192
193 // Capture initial metrics
194 auto metrics_before = db.get_metrics();
195 auto start = steady_clock::now();
196
197 // Execute test queries
198 const int num_queries = 100;
199 int succeeded = 0;
200 int failed = 0;
201
202 std::cout << "Executing " << num_queries << " test queries...\n";
203
204 for (int i = 0; i < num_queries; ++i) {
205 auto result = db.execute("SELECT 1");
206 if (result.is_ok()) {
207 succeeded++;
208 } else {
209 failed++;
210 }
211
212 // Small delay to simulate realistic workload
213 if (i % 10 == 0) {
214 std::this_thread::sleep_for(milliseconds(10));
215 }
216 }
217
218 auto duration = duration_cast<milliseconds>(steady_clock::now() - start);
219
220 // Capture final metrics
221 auto metrics_after = db.get_metrics();
222
223 std::cout << "\nPerformance Report:\n";
225
226 std::cout << " Execution:\n";
227 std::cout << " Duration: " << duration.count() << " ms\n";
228 std::cout << " Queries Executed: " << num_queries << "\n";
229 std::cout << " Succeeded: " << succeeded << "\n";
230 std::cout << " Failed: " << failed << "\n";
231 std::cout << " Throughput: " << std::fixed << std::setprecision(2)
232 << (num_queries * 1000.0 / duration.count()) << " queries/sec\n";
233
234 std::cout << "\n Metrics Delta:\n";
235 std::cout << " Total Queries: +" << (metrics_after.total_queries - metrics_before.total_queries) << "\n";
236 std::cout << " Successful: +" << (metrics_after.successful_queries - metrics_before.successful_queries) << "\n";
237 std::cout << " Failed: +" << (metrics_after.failed_queries - metrics_before.failed_queries) << "\n";
238
240
241 std::cout << "\nāœ… Performance profiling complete\n";
242}
243
248 print_header("Example 4: Alerting Based on Metrics");
249
250 std::cout << "Monitoring for alert conditions...\n\n";
251
252 // Define alert thresholds
253 const double high_latency_threshold = 100.0; // ms
254 const double high_pool_utilization = 0.8; // 80%
255 const double low_success_rate = 0.95; // 95%
256
257 auto metrics = db.get_metrics();
258 auto health = db.check_health();
259
260 bool alerts_triggered = false;
261
262 // Check for high latency
263 double avg_latency_ms = metrics.average_latency.count() / 1000.0;
264 if (avg_latency_ms > high_latency_threshold) {
265 std::cout << "āš ļø ALERT: High query latency detected!\n";
266 std::cout << " Current: " << std::fixed << std::setprecision(3)
267 << avg_latency_ms << " ms\n";
268 std::cout << " Threshold: " << high_latency_threshold << " ms\n\n";
269 alerts_triggered = true;
270 }
271
272 // Check for high pool utilization
273 if (health.connection_pool_utilization > high_pool_utilization) {
274 std::cout << "āš ļø ALERT: High connection pool utilization!\n";
275 std::cout << " Current: " << (health.connection_pool_utilization * 100) << "%\n";
276 std::cout << " Threshold: " << (high_pool_utilization * 100) << "%\n\n";
277 alerts_triggered = true;
278 }
279
280 // Check for low success rate
281 if (metrics.total_queries > 0) {
282 double success_rate = static_cast<double>(metrics.successful_queries) / metrics.total_queries;
283 if (success_rate < low_success_rate) {
284 std::cout << "āš ļø ALERT: Low query success rate!\n";
285 std::cout << " Current: " << (success_rate * 100) << "%\n";
286 std::cout << " Threshold: " << (low_success_rate * 100) << "%\n\n";
287 alerts_triggered = true;
288 }
289 }
290
291 // Check for unhealthy status
292 if (health.status != health_status::healthy) {
293 std::cout << "āš ļø ALERT: System health degraded!\n";
294 std::cout << " Status: ";
295 switch (health.status) {
296 case health_status::degraded: std::cout << "Degraded\n"; break;
297 case health_status::failed: std::cout << "Failed\n"; break;
298 case health_status::critical: std::cout << "Critical\n"; break;
299 default: std::cout << "Unknown\n";
300 }
301 std::cout << "\n";
302 alerts_triggered = true;
303 }
304
305 if (!alerts_triggered) {
306 std::cout << "āœ… No alerts triggered - system operating normally\n";
307 }
308
309 std::cout << "\nāœ… Alert monitoring complete\n";
310}
311
312int main(int argc, char* argv[]) {
313 print_header("Unified Database System - Monitoring Example");
314
315 // Create database instance with monitoring enabled
316 std::cout << "Creating database instance with monitoring...\n";
317
319 .enable_logging(db_log_level::info, "./logs")
320 .enable_monitoring(true)
321 .enable_async(4)
322 .set_pool_size(5, 20)
323 .set_slow_query_threshold(milliseconds(100))
324 .build();
325
326 if (db_result.is_err()) {
327 std::cerr << "Failed to create database instance: " << db_result.error().message << "\n";
328 return 1;
329 }
330 auto db = std::move(db_result.value());
331
332 std::cout << "āœ… Database instance created\n";
333
334 // Initial health check
335 print_header("Initial Health Check");
336 auto health = db->check_health();
337 print_health_check(health);
338
339 // Initial metrics
340 print_header("Initial Metrics");
341 auto metrics = db->get_metrics();
342 print_metrics(metrics);
343
344 // Connect to database (if connection string provided)
345 if (argc > 1) {
346 std::string conn_string = argv[1];
347 std::cout << "\nConnecting to database...\n";
348
349 auto connect_result = db->connect(conn_string);
350
351 if (connect_result.is_ok()) {
352 std::cout << "āœ… Connected successfully\n";
353
354 // Run monitoring examples
358 example_alerting(*db);
359
360 // Final report
361 print_header("Final Report");
362 health = db->check_health();
363 print_health_check(health);
364
365 metrics = db->get_metrics();
366 print_metrics(metrics);
367
368 // Disconnect
369 db->disconnect();
370 std::cout << "\nāœ… Disconnected\n";
371
372 } else {
373 std::cout << "āŒ Connection failed: " << connect_result.error().message << "\n";
374 std::cout << "\nNote: This example requires a real database connection.\n";
375 }
376
377 } else {
378 std::cout << "\nāŒ No connection string provided.\n";
379 std::cout << "Usage: " << argv[0] << " [connection_string]\n";
380 return 1;
381 }
382
383 print_header("Example Complete");
384 std::cout << "āœ… All monitoring examples completed!\n\n";
385
386 return 0;
387}
builder & enable_monitoring(bool enable=true)
Enable monitoring and metrics collection.
builder & set_pool_size(size_t min_size, size_t max_size)
Set connection pool size.
builder & enable_async(size_t worker_threads=4)
Enable async operations.
builder & set_slow_query_threshold(std::chrono::milliseconds threshold)
Set slow query threshold.
kcenon::common::Result< std::unique_ptr< unified_database_system > > build()
Build and return the configured database system.
builder & enable_logging(db_log_level level, const std::string &log_dir="./logs")
Enable logging.
database_metrics get_metrics() const
Get current performance metrics.
kcenon::common::Result< query_result > execute(const std::string &query, const std::vector< query_param > &params={})
health_check check_health() const
Perform health check.
static builder create_builder()
Create a builder for custom configuration.
void example_health_monitoring(unified_database_system &db)
void example_realtime_monitoring(unified_database_system &db)
void print_health_check(const health_check &health, bool detailed=true)
void print_header(const std::string &title)
void example_alerting(unified_database_system &db)
void print_separator()
void example_performance_profiling(unified_database_system &db)
void print_metrics(const database_metrics &metrics, bool detailed=true)
Zero-configuration database system with integrated adapters (Phase 6)