Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
kcenon::monitoring::prometheus_exporter Class Reference

Prometheus metric exporter implementation. More...

#include <metric_exporters.h>

Inheritance diagram for kcenon::monitoring::prometheus_exporter:
Inheritance graph
Collaboration diagram for kcenon::monitoring::prometheus_exporter:
Collaboration graph

Public Member Functions

 prometheus_exporter (const metric_export_config &config)
 
std::vector< prometheus_metric_dataconvert_monitoring_data (const monitoring_data &data) const
 Convert monitoring_data to Prometheus format.
 
std::vector< prometheus_metric_dataconvert_snapshot (const metrics_snapshot &snapshot) const
 Convert metrics_snapshot to Prometheus format.
 
common::VoidResult export_metrics (const std::vector< monitoring_data > &metrics) override
 Export a batch of metrics.
 
common::VoidResult export_snapshot (const metrics_snapshot &snapshot) override
 Export a single metrics snapshot.
 
std::string get_metrics_text () const
 Get current metrics in Prometheus format (for HTTP endpoint)
 
common::VoidResult flush () override
 Flush any pending metrics.
 
common::VoidResult shutdown () override
 Shutdown the exporter.
 
std::unordered_map< std::string, std::size_t > get_stats () const override
 Get exporter statistics.
 
- Public Member Functions inherited from kcenon::monitoring::metric_exporter_interface
virtual ~metric_exporter_interface ()=default
 
virtual common::VoidResult start ()
 Start the exporter (for pull-based systems)
 
virtual common::VoidResult stop ()
 Stop the exporter.
 

Private Member Functions

std::string sanitize_metric_name (const std::string &name) const
 
std::string sanitize_label_name (const std::string &name) const
 
metric_type infer_metric_type (const std::string &name, double) const
 

Private Attributes

metric_export_config config_
 
std::atomic< std::size_t > exported_metrics_ {0}
 
std::atomic< std::size_t > failed_exports_ {0}
 
std::atomic< std::size_t > scrape_requests_ {0}
 
std::vector< prometheus_metric_datacurrent_metrics_
 
std::mutex metrics_mutex_
 

Detailed Description

Prometheus metric exporter implementation.

Definition at line 286 of file metric_exporters.h.

Constructor & Destructor Documentation

◆ prometheus_exporter()

kcenon::monitoring::prometheus_exporter::prometheus_exporter ( const metric_export_config & config)
inlineexplicit

Definition at line 296 of file metric_exporters.h.

297 : config_(config) {}

Member Function Documentation

◆ convert_monitoring_data()

std::vector< prometheus_metric_data > kcenon::monitoring::prometheus_exporter::convert_monitoring_data ( const monitoring_data & data) const
inline

Convert monitoring_data to Prometheus format.

Definition at line 302 of file metric_exporters.h.

302 {
303 std::vector<prometheus_metric_data> prom_metrics;
304
305 for (const auto& [name, value] : data.get_metrics()) {
306 prometheus_metric_data metric;
307 metric.name = sanitize_metric_name(name);
308 metric.type = infer_metric_type(name, value);
309 metric.value = value;
310 metric.timestamp = data.get_timestamp();
311 metric.help_text = "Metric from " + data.get_component_name();
312
313 // Add component name as label
314 metric.labels["component"] = data.get_component_name();
315
316 // Add custom labels from config
317 for (const auto& [key, label_value] : config_.labels) {
318 metric.labels[key] = label_value;
319 }
320
321 // Add tags as labels
322 for (const auto& [key, tag_value] : data.get_tags()) {
323 metric.labels[sanitize_label_name(key)] = tag_value;
324 }
325
326 if (!config_.instance_id.empty()) {
327 metric.labels["instance"] = config_.instance_id;
328 }
329
330 prom_metrics.push_back(std::move(metric));
331 }
332
333 return prom_metrics;
334 }
metric_type infer_metric_type(const std::string &name, double) const
std::string sanitize_metric_name(const std::string &name) const
std::string sanitize_label_name(const std::string &name) const
std::unordered_map< std::string, std::string > labels
Default labels/tags.
std::string instance_id
Instance identifier.

References config_, kcenon::monitoring::monitoring_data::get_component_name(), kcenon::monitoring::monitoring_data::get_metrics(), kcenon::monitoring::monitoring_data::get_tags(), kcenon::monitoring::monitoring_data::get_timestamp(), infer_metric_type(), kcenon::monitoring::metric_export_config::instance_id, kcenon::monitoring::metric_export_config::labels, kcenon::monitoring::metric::name, sanitize_label_name(), sanitize_metric_name(), kcenon::monitoring::metric::timestamp, kcenon::monitoring::metric::type, and kcenon::monitoring::metric::value.

Referenced by export_metrics(), TEST_F(), and TEST_F().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_snapshot()

std::vector< prometheus_metric_data > kcenon::monitoring::prometheus_exporter::convert_snapshot ( const metrics_snapshot & snapshot) const
inline

Convert metrics_snapshot to Prometheus format.

Definition at line 339 of file metric_exporters.h.

339 {
340 std::vector<prometheus_metric_data> prom_metrics;
341
342 for (const auto& metric_val : snapshot.metrics) {
343 prometheus_metric_data metric;
344 metric.name = sanitize_metric_name(metric_val.name);
345 metric.type = infer_metric_type(metric_val.name, metric_val.value);
346 metric.value = metric_val.value;
347 metric.timestamp = metric_val.timestamp;
348 metric.help_text = "System metric";
349
350 // Add source as label
351 if (!snapshot.source_id.empty()) {
352 metric.labels["source"] = snapshot.source_id;
353 }
354
355 // Add custom labels from config
356 for (const auto& [key, label_value] : config_.labels) {
357 metric.labels[key] = label_value;
358 }
359
360 // Add tags as labels
361 for (const auto& [key, tag_value] : metric_val.tags) {
362 metric.labels[sanitize_label_name(key)] = tag_value;
363 }
364
365 if (!config_.instance_id.empty()) {
366 metric.labels["instance"] = config_.instance_id;
367 }
368
369 prom_metrics.push_back(std::move(metric));
370 }
371
372 return prom_metrics;
373 }

References config_, infer_metric_type(), kcenon::monitoring::metric_export_config::instance_id, kcenon::monitoring::metric_export_config::labels, kcenon::monitoring::metrics_snapshot::metrics, kcenon::monitoring::metric::name, sanitize_label_name(), sanitize_metric_name(), kcenon::monitoring::metrics_snapshot::source_id, kcenon::monitoring::metric::timestamp, kcenon::monitoring::metric::type, and kcenon::monitoring::metric::value.

Referenced by export_snapshot(), and TEST_F().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_metrics()

common::VoidResult kcenon::monitoring::prometheus_exporter::export_metrics ( const std::vector< monitoring_data > & metrics)
inlineoverridevirtual

Export a batch of metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 375 of file metric_exporters.h.

375 {
376 try {
377 std::lock_guard<std::mutex> lock(metrics_mutex_);
378 current_metrics_.clear();
379
380 for (const auto& data : metrics) {
381 auto prom_metrics = convert_monitoring_data(data);
383 prom_metrics.begin(), prom_metrics.end());
384 }
385
386 exported_metrics_ += metrics.size();
387 return common::ok();
388
389 } catch (const std::exception& e) {
391 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
392 "Prometheus export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
393 }
394 }
std::atomic< std::size_t > exported_metrics_
std::atomic< std::size_t > failed_exports_
std::vector< prometheus_metric_data > convert_monitoring_data(const monitoring_data &data) const
Convert monitoring_data to Prometheus format.
std::vector< prometheus_metric_data > current_metrics_

References convert_monitoring_data(), current_metrics_, exported_metrics_, failed_exports_, metrics_mutex_, kcenon::monitoring::operation_failed, and kcenon::monitoring::error_info::to_common_error().

Referenced by TEST_F(), and TEST_F().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_snapshot()

common::VoidResult kcenon::monitoring::prometheus_exporter::export_snapshot ( const metrics_snapshot & snapshot)
inlineoverridevirtual

Export a single metrics snapshot.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 396 of file metric_exporters.h.

396 {
397 try {
398 std::lock_guard<std::mutex> lock(metrics_mutex_);
399 auto prom_metrics = convert_snapshot(snapshot);
401 prom_metrics.begin(), prom_metrics.end());
402
404 return common::ok();
405
406 } catch (const std::exception& e) {
408 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
409 "Prometheus snapshot export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
410 }
411 }
std::vector< prometheus_metric_data > convert_snapshot(const metrics_snapshot &snapshot) const
Convert metrics_snapshot to Prometheus format.

References convert_snapshot(), current_metrics_, exported_metrics_, failed_exports_, metrics_mutex_, kcenon::monitoring::operation_failed, and kcenon::monitoring::error_info::to_common_error().

Referenced by TEST_F(), and TEST_F().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush()

common::VoidResult kcenon::monitoring::prometheus_exporter::flush ( )
inlineoverridevirtual

Flush any pending metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 430 of file metric_exporters.h.

430 {
431 // Prometheus is pull-based, so flush is a no-op
432 return common::ok();
433 }

Referenced by shutdown(), and TEST_F().

Here is the caller graph for this function:

◆ get_metrics_text()

std::string kcenon::monitoring::prometheus_exporter::get_metrics_text ( ) const
inline

Get current metrics in Prometheus format (for HTTP endpoint)

Definition at line 416 of file metric_exporters.h.

416 {
417 std::lock_guard<std::mutex> lock(metrics_mutex_);
418 std::ostringstream ss;
419
420 for (const auto& metric : current_metrics_) {
421 ss << metric.to_prometheus_text();
422 }
423
424 // Increment scrape counter
425 const_cast<std::atomic<std::size_t>&>(scrape_requests_)++;
426
427 return ss.str();
428 }
std::atomic< std::size_t > scrape_requests_

References current_metrics_, metrics_mutex_, and scrape_requests_.

Referenced by TEST_F().

Here is the caller graph for this function:

◆ get_stats()

std::unordered_map< std::string, std::size_t > kcenon::monitoring::prometheus_exporter::get_stats ( ) const
inlineoverridevirtual

Get exporter statistics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 439 of file metric_exporters.h.

439 {
440 return {
441 {"exported_metrics", exported_metrics_.load()},
442 {"failed_exports", failed_exports_.load()},
443 {"scrape_requests", scrape_requests_.load()},
444 {"current_metrics_count", current_metrics_.size()}
445 };
446 }

References current_metrics_, exported_metrics_, failed_exports_, and scrape_requests_.

Referenced by TEST_F(), and TEST_F().

Here is the caller graph for this function:

◆ infer_metric_type()

metric_type kcenon::monitoring::prometheus_exporter::infer_metric_type ( const std::string & name,
double  ) const
inlineprivate

Definition at line 477 of file metric_exporters.h.

477 {
478 // Simple heuristics for metric type inference
479 std::string lower_name = name;
480 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower);
481
482 if (lower_name.find("count") != std::string::npos ||
483 lower_name.find("total") != std::string::npos ||
484 lower_name.find("requests") != std::string::npos) {
486 } else if (lower_name.find("histogram") != std::string::npos ||
487 lower_name.find("bucket") != std::string::npos) {
489 } else if (lower_name.find("summary") != std::string::npos ||
490 lower_name.find("quantile") != std::string::npos) {
492 } else {
493 return metric_type::gauge; // Default to gauge
494 }
495 }
@ gauge
Instantaneous value that can go up and down.
@ counter
Monotonically increasing counter.
@ summary
Pre-calculated quantiles and count/sum.
@ histogram
Distribution of values with buckets.

References kcenon::monitoring::counter, kcenon::monitoring::gauge, kcenon::monitoring::histogram, and kcenon::monitoring::summary.

Referenced by convert_monitoring_data(), and convert_snapshot().

Here is the caller graph for this function:

◆ sanitize_label_name()

std::string kcenon::monitoring::prometheus_exporter::sanitize_label_name ( const std::string & name) const
inlineprivate

Definition at line 463 of file metric_exporters.h.

463 {
464 std::string sanitized = name;
465 // Replace invalid characters with underscores
466 std::regex invalid_chars("[^a-zA-Z0-9_]");
467 sanitized = std::regex_replace(sanitized, invalid_chars, "_");
468
469 // Ensure it starts with a letter or underscore
470 if (!sanitized.empty() && !std::isalpha(sanitized[0]) && sanitized[0] != '_') {
471 sanitized = "_" + sanitized;
472 }
473
474 return sanitized;
475 }

Referenced by convert_monitoring_data(), and convert_snapshot().

Here is the caller graph for this function:

◆ sanitize_metric_name()

std::string kcenon::monitoring::prometheus_exporter::sanitize_metric_name ( const std::string & name) const
inlineprivate

Definition at line 449 of file metric_exporters.h.

449 {
450 std::string sanitized = name;
451 // Replace invalid characters with underscores
452 std::regex invalid_chars("[^a-zA-Z0-9_:]");
453 sanitized = std::regex_replace(sanitized, invalid_chars, "_");
454
455 // Ensure it starts with a letter or underscore
456 if (!sanitized.empty() && !std::isalpha(sanitized[0]) && sanitized[0] != '_') {
457 sanitized = "_" + sanitized;
458 }
459
460 return sanitized;
461 }

Referenced by convert_monitoring_data(), and convert_snapshot().

Here is the caller graph for this function:

◆ shutdown()

common::VoidResult kcenon::monitoring::prometheus_exporter::shutdown ( )
inlineoverridevirtual

Shutdown the exporter.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 435 of file metric_exporters.h.

435 {
436 return flush();
437 }
common::VoidResult flush() override
Flush any pending metrics.

References flush().

Referenced by TEST_F().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ config_

metric_export_config kcenon::monitoring::prometheus_exporter::config_
private

Definition at line 288 of file metric_exporters.h.

Referenced by convert_monitoring_data(), and convert_snapshot().

◆ current_metrics_

std::vector<prometheus_metric_data> kcenon::monitoring::prometheus_exporter::current_metrics_
private

Definition at line 292 of file metric_exporters.h.

Referenced by export_metrics(), export_snapshot(), get_metrics_text(), and get_stats().

◆ exported_metrics_

std::atomic<std::size_t> kcenon::monitoring::prometheus_exporter::exported_metrics_ {0}
private

Definition at line 289 of file metric_exporters.h.

289{0};

Referenced by export_metrics(), export_snapshot(), and get_stats().

◆ failed_exports_

std::atomic<std::size_t> kcenon::monitoring::prometheus_exporter::failed_exports_ {0}
private

Definition at line 290 of file metric_exporters.h.

290{0};

Referenced by export_metrics(), export_snapshot(), and get_stats().

◆ metrics_mutex_

std::mutex kcenon::monitoring::prometheus_exporter::metrics_mutex_
mutableprivate

Definition at line 293 of file metric_exporters.h.

Referenced by export_metrics(), export_snapshot(), and get_metrics_text().

◆ scrape_requests_

std::atomic<std::size_t> kcenon::monitoring::prometheus_exporter::scrape_requests_ {0}
private

Definition at line 291 of file metric_exporters.h.

291{0};

Referenced by get_metrics_text(), and get_stats().


The documentation for this class was generated from the following file: