16 std::chrono::steady_clock::time_point timestamp)
17 : type_(type), message_(message), timestamp_(timestamp)
25 std::shared_ptr<performance_monitor> monitor)
26 : start_time_(std::chrono::steady_clock::now())
27 , monitor_(std::move(monitor))
65 bool is_sanitizer_build =
false;
66#if defined(__SANITIZE_THREAD__) || defined(__SANITIZE_ADDRESS__)
68 is_sanitizer_build =
true;
73# if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer) || __has_feature(undefined_behavior_sanitizer)
74 is_sanitizer_build =
true;
78 if (is_sanitizer_build) {
81 std::cout <<
"performance_monitor: background cleanup thread disabled (sanitizer build)" << std::endl;
98 std::chrono::microseconds latency_threshold)
108 bool slow_query =
false;
118 avg_time = std::chrono::microseconds(
119 (avg_time.count() * (count - 1) + metrics.
execution_time.count()) / count);
129 "Slow query detected: " + std::to_string(metrics.
execution_time.count()) +
"μs");
139 bool pool_exhaustion =
false;
156 pool_exhaustion = (total > 0 && (double(active) / total) > 0.9);
159 if (pool_exhaustion) {
161 "Connection pool utilization high: " + std::to_string(active) +
"/" + std::to_string(total));
170 "Slow query: " + query.substr(0, 100) +
"... (" +
171 std::to_string(execution_time.count()) +
"μs)");
190 return m.start_time >= recent_start;
196 std::chrono::microseconds total_time{0};
197 std::chrono::microseconds min_time{std::chrono::microseconds::max()};
198 std::chrono::microseconds max_time{0};
199 size_t successful = 0;
202 if (metrics.start_time < recent_start)
continue;
204 total_time += metrics.execution_time;
205 min_time = std::min(min_time, metrics.execution_time);
206 max_time = std::max(max_time, metrics.execution_time);
208 if (metrics.success) {
226 auto duration_seconds = std::chrono::duration_cast<std::chrono::seconds>(
228 if (duration_seconds > 0) {
233 size_t total_connections = 0;
234 size_t active_connections = 0;
236 total_connections += conn_metrics.total_connections.load();
237 active_connections += conn_metrics.active_connections.load();
242 if (total_connections > 0) {
261 return m.start_time >= recent_start && m.db_type == db_type;
267 std::chrono::microseconds total_time{0};
268 size_t successful = 0;
271 if (metrics.start_time < recent_start || metrics.db_type != db_type)
continue;
273 total_time += metrics.execution_time;
274 if (metrics.success) {
304 auto cutoff = std::chrono::steady_clock::now() - window;
305 std::vector<query_metrics> recent;
309 return m.start_time >= cutoff;
319 std::vector<query_metrics> slow_queries;
322 return m.execution_time >= threshold;
334 metrics.active_connections = active;
335 metrics.total_connections = total;
336 metrics.last_update = std::chrono::steady_clock::now();
367 auto cutoff = std::chrono::steady_clock::now() - window;
368 std::vector<performance_alert> recent;
370 std::copy_if(
alerts_.begin(),
alerts_.end(), std::back_inserter(recent),
372 return alert.timestamp() >= cutoff;
398 return m.start_time < cutoff;
406 return alert.timestamp() < cutoff;
415 std::ostringstream json;
417 json <<
" \"total_queries\": " << summary.total_queries <<
",\n";
418 json <<
" \"successful_queries\": " << summary.successful_queries <<
",\n";
419 json <<
" \"failed_queries\": " << summary.failed_queries <<
",\n";
420 json <<
" \"avg_query_time_us\": " << summary.avg_query_time.count() <<
",\n";
421 json <<
" \"queries_per_second\": " << summary.queries_per_second <<
",\n";
422 json <<
" \"error_rate\": " << summary.error_rate <<
",\n";
423 json <<
" \"total_connections\": " << summary.total_connections <<
",\n";
424 json <<
" \"active_connections\": " << summary.active_connections <<
",\n";
425 json <<
" \"connection_utilization\": " << summary.connection_utilization <<
"\n";
434 const auto cleanup_interval = std::chrono::minutes(5);
435 auto last_cleanup = std::chrono::steady_clock::now();
443 auto now = std::chrono::steady_clock::now();
459 "High error rate: " + std::to_string(summary.error_rate * 100) +
"%");
465 "High average latency: " + std::to_string(summary.avg_query_time.count()) +
"μs");
483 }
catch (
const std::exception& e) {
484 std::cerr <<
"Alert handler exception: " << e.what() << std::endl;
491 return std::to_string(std::hash<std::string>{}(query));
496 : endpoint_(endpoint), port_(port)
504 std::cout <<
"Prometheus metrics:\n" << metrics << std::endl;
511 for (
const auto& alert : alerts) {
512 std::cout <<
"database_alert{type=\"" <<
static_cast<int>(alert.type())
513 <<
"\"} 1 " << std::chrono::duration_cast<std::chrono::milliseconds>(
514 alert.timestamp().time_since_epoch()).count() << std::endl;
521 std::ostringstream metrics;
523 metrics <<
"# HELP database_queries_total Total number of database queries\n";
524 metrics <<
"# TYPE database_queries_total counter\n";
525 metrics <<
"database_queries_total " << summary.
total_queries <<
"\n";
527 metrics <<
"# HELP database_query_duration_microseconds Average query duration in microseconds\n";
528 metrics <<
"# TYPE database_query_duration_microseconds gauge\n";
529 metrics <<
"database_query_duration_microseconds " << summary.
avg_query_time.count() <<
"\n";
531 metrics <<
"# HELP database_error_rate Query error rate\n";
532 metrics <<
"# TYPE database_error_rate gauge\n";
533 metrics <<
"database_error_rate " << summary.
error_rate <<
"\n";
535 metrics <<
"# HELP database_connections_active Active database connections\n";
536 metrics <<
"# TYPE database_connections_active gauge\n";
539 return metrics.str();
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
prometheus_exporter(const std::string &endpoint, int port)
void set_error(const std::string &error)
std::shared_ptr< performance_monitor > monitor_
query_timer(const std::string &query, database_types db_type, std::shared_ptr< performance_monitor > monitor)
Constructor with explicit performance_monitor (recommended)
std::chrono::steady_clock::time_point start_time_
database_types
Represents various database backends or modes.
Metrics for database connection usage.
std::atomic< size_t > idle_connections
std::atomic< size_t > failed_connections
std::atomic< std::chrono::microseconds > max_acquisition_time
std::atomic< std::chrono::microseconds > avg_acquisition_time
std::atomic< size_t > active_connections
std::chrono::steady_clock::time_point last_update
std::atomic< size_t > total_connections
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