10#include <gtest/gtest.h>
28 const std::string& hash,
29 std::chrono::microseconds exec_time,
32 const std::string& error_msg =
"")
36 m.
start_time = std::chrono::steady_clock::now();
55 monitor_ = std::make_shared<performance_monitor>();
60 auto m =
make_query(
"hash1", std::chrono::microseconds(5000),
true);
61 monitor_->record_query_metrics(m);
63 auto summary = monitor_->get_performance_summary();
64 EXPECT_EQ(summary.total_queries, 1u);
65 EXPECT_EQ(summary.successful_queries, 1u);
66 EXPECT_EQ(summary.failed_queries, 0u);
70 monitor_->record_query_metrics(
71 make_query(
"q1", std::chrono::microseconds(1000),
true));
72 monitor_->record_query_metrics(
73 make_query(
"q2", std::chrono::microseconds(2000),
true));
74 monitor_->record_query_metrics(
75 make_query(
"q3", std::chrono::microseconds(3000),
false,
76 database_types::postgres,
"timeout"));
78 auto summary = monitor_->get_performance_summary();
79 EXPECT_EQ(summary.total_queries, 3u);
80 EXPECT_EQ(summary.successful_queries, 2u);
81 EXPECT_EQ(summary.failed_queries, 1u);
82 EXPECT_GT(summary.error_rate, 0.0);
86 monitor_->record_query_metrics(
87 make_query(
"q1", std::chrono::microseconds(1000),
true));
88 monitor_->record_query_metrics(
89 make_query(
"q2", std::chrono::microseconds(3000),
true));
91 auto summary = monitor_->get_performance_summary();
92 EXPECT_EQ(summary.avg_query_time.count(), 2000);
104 monitor_ = std::make_shared<performance_monitor>();
109 monitor_->set_monitoring_enabled(
false);
110 monitor_->record_query_metrics(
111 make_query(
"q1", std::chrono::microseconds(1000),
true));
113 auto summary = monitor_->get_performance_summary();
114 EXPECT_EQ(summary.total_queries, 0u);
118 monitor_->set_monitoring_enabled(
false);
123 monitor_->record_connection_metrics(database_types::postgres, cm);
125 auto retrieved = monitor_->get_connection_metrics(database_types::postgres);
126 EXPECT_EQ(retrieved.total_connections.load(), 0u);
130 monitor_->set_monitoring_enabled(
false);
131 monitor_->update_connection_count(database_types::sqlite, 5, 10);
133 auto retrieved = monitor_->get_connection_metrics(database_types::postgres);
134 EXPECT_EQ(retrieved.total_connections.load(), 0u);
138 monitor_->set_monitoring_enabled(
false);
139 monitor_->record_query_metrics(
140 make_query(
"ignored", std::chrono::microseconds(100),
true));
142 monitor_->set_monitoring_enabled(
true);
143 monitor_->record_query_metrics(
144 make_query(
"recorded", std::chrono::microseconds(200),
true));
146 auto summary = monitor_->get_performance_summary();
147 EXPECT_EQ(summary.total_queries, 1u);
159 monitor_ = std::make_shared<performance_monitor>();
162 make_query(
"pg1", std::chrono::microseconds(1000),
true, database_types::postgres));
164 make_query(
"pg2", std::chrono::microseconds(2000),
true, database_types::postgres));
166 make_query(
"sq1", std::chrono::microseconds(3000),
true, database_types::sqlite));
168 make_query(
"sq2", std::chrono::microseconds(4000),
false,
169 database_types::sqlite,
"connection lost"));
174 auto summary = monitor_->get_performance_summary(database_types::postgres);
175 EXPECT_EQ(summary.total_queries, 2u);
176 EXPECT_EQ(summary.successful_queries, 2u);
177 EXPECT_EQ(summary.failed_queries, 0u);
181 auto summary = monitor_->get_performance_summary(database_types::sqlite);
182 EXPECT_EQ(summary.total_queries, 2u);
183 EXPECT_EQ(summary.successful_queries, 1u);
184 EXPECT_EQ(summary.failed_queries, 1u);
185 EXPECT_DOUBLE_EQ(summary.error_rate, 0.5);
189 auto summary = monitor_->get_performance_summary(database_types::mongodb);
190 EXPECT_EQ(summary.total_queries, 0u);
194 auto summary = monitor_->get_performance_summary();
195 EXPECT_EQ(summary.total_queries, 4u);
207 monitor_ = std::make_shared<performance_monitor>();
212 monitor_->record_query_metrics(
213 make_query(
"q1", std::chrono::microseconds(100),
true));
214 monitor_->record_query_metrics(
215 make_query(
"q2", std::chrono::microseconds(200),
true));
217 auto recent = monitor_->get_recent_queries(std::chrono::minutes(5));
218 EXPECT_EQ(recent.size(), 2u);
222 monitor_->record_query_metrics(
223 make_query(
"q1", std::chrono::microseconds(100),
true));
227 auto recent = monitor_->get_recent_queries(std::chrono::minutes(0));
230 EXPECT_LE(recent.size(), 1u);
234 monitor_->record_query_metrics(
235 make_query(
"fast", std::chrono::microseconds(100),
true));
236 monitor_->record_query_metrics(
237 make_query(
"medium", std::chrono::microseconds(5000),
true));
238 monitor_->record_query_metrics(
239 make_query(
"slow", std::chrono::microseconds(50000),
true));
241 auto slow = monitor_->get_slow_queries(std::chrono::microseconds(4000));
242 EXPECT_EQ(slow.size(), 2u);
246 monitor_->record_query_metrics(
247 make_query(
"fast", std::chrono::microseconds(100),
true));
249 auto slow = monitor_->get_slow_queries(std::chrono::microseconds(1000000));
250 EXPECT_TRUE(slow.empty());
254 auto original =
make_query(
"slow_hash", std::chrono::microseconds(99999),
false,
255 database_types::sqlite,
"timeout");
256 monitor_->record_query_metrics(original);
258 auto slow = monitor_->get_slow_queries(std::chrono::microseconds(1000));
260 EXPECT_EQ(slow[0].query_hash,
"slow_hash");
262 EXPECT_EQ(slow[0].error_message,
"timeout");
263 EXPECT_EQ(slow[0].db_type, database_types::sqlite);
275 monitor_ = std::make_shared<performance_monitor>();
281 monitor_->set_alert_thresholds(0.05, std::chrono::microseconds(100));
283 monitor_->record_query_metrics(
284 make_query(
"slow", std::chrono::microseconds(500),
true));
286 auto alerts = monitor_->get_recent_alerts(std::chrono::minutes(5));
287 ASSERT_GE(alerts.size(), 1u);
289 bool found_slow_query_alert =
false;
290 for (
const auto& alert : alerts) {
291 if (alert.type() == performance_alert::alert_type::slow_query) {
292 found_slow_query_alert =
true;
293 EXPECT_FALSE(alert.message().empty());
296 EXPECT_TRUE(found_slow_query_alert);
300 std::atomic<int> callback_count{0};
302 callback_count.fetch_add(1);
306 monitor_->set_alert_thresholds(0.05, std::chrono::microseconds(10));
307 monitor_->record_query_metrics(
308 make_query(
"slow", std::chrono::microseconds(1000),
true));
310 EXPECT_GE(callback_count.load(), 1);
314 std::atomic<int> handler1_count{0};
315 std::atomic<int> handler2_count{0};
318 handler1_count.fetch_add(1);
321 handler2_count.fetch_add(1);
324 monitor_->set_alert_thresholds(0.05, std::chrono::microseconds(10));
325 monitor_->record_query_metrics(
326 make_query(
"slow", std::chrono::microseconds(1000),
true));
328 EXPECT_GE(handler1_count.load(), 1);
329 EXPECT_GE(handler2_count.load(), 1);
333 auto alerts = monitor_->get_recent_alerts(std::chrono::minutes(5));
334 EXPECT_TRUE(alerts.empty());
338 monitor_->record_slow_query(
"SELECT * FROM huge_table",
339 std::chrono::microseconds(5000000));
341 auto alerts = monitor_->get_recent_alerts(std::chrono::minutes(5));
342 ASSERT_GE(alerts.size(), 1u);
343 EXPECT_EQ(alerts.back().type(), performance_alert::alert_type::slow_query);
351 monitor_->record_connection_metrics(database_types::postgres, cm);
353 auto alerts = monitor_->get_recent_alerts(std::chrono::minutes(5));
354 bool found_pool_alert =
false;
355 for (
const auto& alert : alerts) {
356 if (alert.type() == performance_alert::alert_type::connection_pool_exhaustion) {
357 found_pool_alert =
true;
360 EXPECT_TRUE(found_pool_alert);
372 monitor_ = std::make_shared<performance_monitor>();
377 monitor_->record_query_metrics(
378 make_query(
"q1", std::chrono::microseconds(100),
true));
379 monitor_->update_connection_count(database_types::postgres, 5, 10);
380 monitor_->record_slow_query(
"SELECT 1", std::chrono::microseconds(999999));
382 monitor_->clear_metrics();
384 auto summary = monitor_->get_performance_summary();
385 EXPECT_EQ(summary.total_queries, 0u);
386 EXPECT_EQ(summary.total_connections, 0u);
388 auto alerts = monitor_->get_recent_alerts(std::chrono::minutes(60));
389 EXPECT_TRUE(alerts.empty());
394 monitor_->set_metrics_retention_period(std::chrono::minutes(0));
396 monitor_->record_query_metrics(
397 make_query(
"old", std::chrono::microseconds(100),
true));
399 monitor_->cleanup_old_metrics();
401 auto summary = monitor_->get_performance_summary();
402 EXPECT_EQ(summary.total_queries, 0u);
406 monitor_->set_metrics_retention_period(std::chrono::minutes(60));
408 monitor_->record_query_metrics(
409 make_query(
"recent", std::chrono::microseconds(100),
true));
411 monitor_->cleanup_old_metrics();
413 auto summary = monitor_->get_performance_summary();
414 EXPECT_EQ(summary.total_queries, 1u);
426 monitor_ = std::make_shared<performance_monitor>();
431 monitor_->update_connection_count(database_types::postgres, 5, 10);
433 auto cm = monitor_->get_connection_metrics(database_types::postgres);
434 EXPECT_EQ(cm.active_connections.load(), 5u);
435 EXPECT_EQ(cm.total_connections.load(), 10u);
439 auto cm = monitor_->get_connection_metrics(database_types::sqlite);
440 EXPECT_EQ(cm.total_connections.load(), 0u);
441 EXPECT_EQ(cm.active_connections.load(), 0u);
447 monitor_->record_query_metrics(
448 make_query(
"q1", std::chrono::microseconds(100),
true));
450 monitor_->update_connection_count(database_types::postgres, 3, 10);
451 monitor_->update_connection_count(database_types::sqlite, 2, 5);
453 auto summary = monitor_->get_performance_summary();
454 EXPECT_EQ(summary.total_connections, 15u);
455 EXPECT_EQ(summary.active_connections, 5u);
456 EXPECT_DOUBLE_EQ(summary.connection_utilization, 5.0 / 15.0);
468 monitor_ = std::make_shared<performance_monitor>();
473 monitor_->record_query_metrics(
474 make_query(
"q1", std::chrono::microseconds(1000),
true));
476 std::string json = monitor_->get_metrics_json();
477 EXPECT_NE(json.find(
"total_queries"), std::string::npos);
478 EXPECT_NE(json.find(
"successful_queries"), std::string::npos);
479 EXPECT_NE(json.find(
"failed_queries"), std::string::npos);
480 EXPECT_NE(json.find(
"avg_query_time_us"), std::string::npos);
481 EXPECT_NE(json.find(
"error_rate"), std::string::npos);
482 EXPECT_NE(json.find(
"active_connections"), std::string::npos);
486 std::string json = monitor_->get_metrics_json();
487 EXPECT_FALSE(json.empty());
488 EXPECT_NE(json.find(
"total_queries"), std::string::npos);
498 auto now = std::chrono::steady_clock::now();
500 performance_alert::alert_type::high_latency,
504 EXPECT_EQ(alert.
type(), performance_alert::alert_type::high_latency);
505 EXPECT_EQ(alert.
message(),
"Latency too high");
510 auto now = std::chrono::steady_clock::now();
512 performance_alert::alert_type::high_latency,
513 performance_alert::alert_type::high_error_rate,
514 performance_alert::alert_type::connection_pool_exhaustion,
515 performance_alert::alert_type::slow_query,
516 performance_alert::alert_type::memory_usage,
517 performance_alert::alert_type::cpu_usage
520 for (
auto type : types) {
522 EXPECT_EQ(alert.
type(), type);
536 EXPECT_EQ(metrics_.total_acquisitions.load(), 0u);
537 EXPECT_EQ(metrics_.successful_acquisitions.load(), 0u);
538 EXPECT_EQ(metrics_.failed_acquisitions.load(), 0u);
539 EXPECT_EQ(metrics_.timeouts.load(), 0u);
540 EXPECT_EQ(metrics_.current_active.load(), 0u);
541 EXPECT_EQ(metrics_.current_queued.load(), 0u);
545 metrics_.record_acquisition(500,
true);
547 EXPECT_EQ(metrics_.total_acquisitions.load(), 1u);
548 EXPECT_EQ(metrics_.successful_acquisitions.load(), 1u);
549 EXPECT_EQ(metrics_.failed_acquisitions.load(), 0u);
550 EXPECT_EQ(metrics_.total_wait_time_us.load(), 500u);
551 EXPECT_EQ(metrics_.min_wait_time_us.load(), 500u);
552 EXPECT_EQ(metrics_.max_wait_time_us.load(), 500u);
556 metrics_.record_acquisition(0,
false);
558 EXPECT_EQ(metrics_.total_acquisitions.load(), 1u);
559 EXPECT_EQ(metrics_.successful_acquisitions.load(), 0u);
560 EXPECT_EQ(metrics_.failed_acquisitions.load(), 1u);
564 metrics_.record_acquisition(100,
true);
565 metrics_.record_acquisition(500,
true);
566 metrics_.record_acquisition(200,
true);
568 EXPECT_EQ(metrics_.total_acquisitions.load(), 3u);
569 EXPECT_EQ(metrics_.successful_acquisitions.load(), 3u);
570 EXPECT_EQ(metrics_.total_wait_time_us.load(), 800u);
571 EXPECT_EQ(metrics_.min_wait_time_us.load(), 100u);
572 EXPECT_EQ(metrics_.max_wait_time_us.load(), 500u);
576 metrics_.record_timeout();
577 metrics_.record_timeout();
579 EXPECT_EQ(metrics_.timeouts.load(), 2u);
583 metrics_.update_active(1);
584 metrics_.update_active(1);
585 metrics_.update_active(1);
586 metrics_.update_active(-1);
588 EXPECT_EQ(metrics_.current_active.load(), 2u);
589 EXPECT_EQ(metrics_.peak_active.load(), 3u);
593 metrics_.update_queued(1);
594 metrics_.update_queued(1);
595 metrics_.update_queued(1);
596 metrics_.update_queued(-1);
597 metrics_.update_queued(-1);
599 EXPECT_EQ(metrics_.current_queued.load(), 1u);
600 EXPECT_EQ(metrics_.peak_queued.load(), 3u);
604 metrics_.record_health_check(0);
605 metrics_.record_health_check(2);
606 metrics_.record_health_check(1);
608 EXPECT_EQ(metrics_.health_checks_performed.load(), 3u);
609 EXPECT_EQ(metrics_.unhealthy_connections_removed.load(), 3u);
613 metrics_.record_acquisition(100,
true);
614 metrics_.record_acquisition(300,
true);
617 EXPECT_DOUBLE_EQ(metrics_.average_wait_time_us(), 200.0);
621 EXPECT_DOUBLE_EQ(metrics_.average_wait_time_us(), 0.0);
625 metrics_.record_acquisition(100,
true);
626 metrics_.record_acquisition(200,
true);
627 metrics_.record_acquisition(0,
false);
629 EXPECT_NEAR(metrics_.success_rate(), 66.666, 0.01);
633 EXPECT_DOUBLE_EQ(metrics_.success_rate(), 100.0);
637 metrics_.record_acquisition(500,
true);
638 metrics_.record_timeout();
639 metrics_.update_active(3);
640 metrics_.record_health_check(1);
644 EXPECT_EQ(metrics_.total_acquisitions.load(), 0u);
645 EXPECT_EQ(metrics_.successful_acquisitions.load(), 0u);
646 EXPECT_EQ(metrics_.timeouts.load(), 0u);
647 EXPECT_EQ(metrics_.total_wait_time_us.load(), 0u);
648 EXPECT_EQ(metrics_.min_wait_time_us.load(), UINT64_MAX);
649 EXPECT_EQ(metrics_.max_wait_time_us.load(), 0u);
650 EXPECT_EQ(metrics_.health_checks_performed.load(), 0u);
652 EXPECT_EQ(metrics_.current_active.load(), 3u);
654 EXPECT_EQ(metrics_.peak_active.load(), 3u);
672 EXPECT_NE(output.find(
"database_queries_total 100"), std::string::npos);
673 EXPECT_NE(output.find(
"database_query_duration_microseconds 500"), std::string::npos);
674 EXPECT_NE(output.find(
"database_error_rate 0.02"), std::string::npos);
675 EXPECT_NE(output.find(
"database_connections_active 5"), std::string::npos);
687 std::vector<performance_alert> alerts;
689 performance_alert::alert_type::slow_query,
"test",
690 std::chrono::steady_clock::now());
704 monitor_ = std::make_shared<performance_monitor>();
710 query_timer timer(
"SELECT 1", database_types::postgres, monitor_);
714 auto summary = monitor_->get_performance_summary();
715 EXPECT_EQ(summary.total_queries, 1u);
716 EXPECT_EQ(summary.successful_queries, 1u);
721 query_timer timer(
"SELECT bad", database_types::postgres, monitor_);
725 auto summary = monitor_->get_performance_summary();
726 EXPECT_EQ(summary.total_queries, 1u);
727 EXPECT_EQ(summary.failed_queries, 1u);
732 query_timer timer(
"INSERT INTO test VALUES (1)", database_types::sqlite, monitor_);
736 auto recent = monitor_->get_recent_queries(std::chrono::minutes(5));
738 EXPECT_EQ(recent[0].rows_affected, 42u);
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
std::shared_ptr< performance_monitor > monitor_
Export metrics in Prometheus format.
std::string format_prometheus_metrics(const performance_summary &summary) const
bool export_alerts(const std::vector< performance_alert > &alerts) override
bool export_metrics(const performance_summary &summary) override
RAII timer for measuring query execution time.
void set_error(const std::string &error)
void set_rows_affected(size_t rows)
database_types
Represents various database backends or modes.
Metrics for database connection usage.
std::atomic< size_t > active_connections
std::atomic< size_t > total_connections
Performance metrics for connection pools.
Metrics for individual query execution.
std::chrono::steady_clock::time_point start_time
std::string error_message
std::chrono::steady_clock::time_point end_time
std::chrono::microseconds execution_time
#define ASSERT_EQ(expected, actual, message)