PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::monitoring::pacs_monitor Class Reference

Unified PACS monitoring implementing IMonitor interface. More...

#include <pacs_monitor.h>

Collaboration diagram for kcenon::pacs::monitoring::pacs_monitor:
Collaboration graph

Public Member Functions

 pacs_monitor (const pacs_monitor_config &config={})
 Construct a new PACS monitor.
 
 ~pacs_monitor ()=default
 Destructor.
 
 pacs_monitor (const pacs_monitor &)=delete
 
pacs_monitoroperator= (const pacs_monitor &)=delete
 
 pacs_monitor (pacs_monitor &&)=delete
 
pacs_monitoroperator= (pacs_monitor &&)=delete
 
void record_metric (std::string_view name, double value)
 Record a metric value.
 
void record_metric (std::string_view name, double value, const std::unordered_map< std::string, std::string > &tags)
 Record a metric with tags.
 
metrics_snapshot get_metrics ()
 Get current metrics snapshot.
 
health_check_result check_health ()
 Perform health check.
 
void reset ()
 Reset all metrics.
 
std::string to_prometheus () const
 Export all metrics in Prometheus text format.
 
std::string to_json () const
 Export all metrics as JSON.
 
void register_health_check (std::string_view component, std::function< bool()> check)
 Register a health check for a component.
 
void unregister_health_check (std::string_view component)
 Unregister a health check.
 
const pacs_monitor_configget_config () const
 Get current configuration.
 
void update_config (const pacs_monitor_config &config)
 Update configuration.
 
dicom_association_collectorassociation_collector ()
 Get the association collector.
 
dicom_service_collectorservice_collector ()
 Get the service collector.
 
dicom_storage_collectorstorage_collector ()
 Get the storage collector.
 
dicom_metrics_collectorunified_collector ()
 Get the unified CRTP-based metrics collector.
 
dicom_metrics_snapshot get_unified_snapshot () const
 Get a snapshot from the unified collector.
 

Static Public Member Functions

static pacs_monitorglobal_monitor () noexcept
 Get the global singleton instance.
 

Private Member Functions

void initialize_collectors ()
 
void collect_all_metrics (metrics_snapshot &snapshot)
 

Private Attributes

pacs_monitor_config config_
 
std::shared_mutex config_mutex_
 
std::unique_ptr< dicom_association_collectorassociation_collector_
 
std::unique_ptr< dicom_service_collectorservice_collector_
 
std::unique_ptr< dicom_storage_collectorstorage_collector_
 
std::unique_ptr< dicom_metrics_collectorunified_collector_
 
std::mutex custom_metrics_mutex_
 
std::vector< metric_valuecustom_metrics_
 
std::mutex health_checks_mutex_
 
std::unordered_map< std::string, std::function< bool()> > health_checks_
 

Detailed Description

Unified PACS monitoring implementing IMonitor interface.

This class provides a unified monitoring interface for the PACS system, integrating all DICOM-specific metric collectors and implementing the IMonitor interface from common_system.

Features:

  • DICOM association metrics (active, peak, success rate)
  • DIMSE service metrics (C-ECHO, C-STORE, C-FIND, C-MOVE, C-GET, N-*)
  • Storage metrics (bytes transferred, images stored/retrieved)
  • Object pool metrics (element, dataset, PDU buffer pools)
  • Health check integration
  • Prometheus-compatible metric export

Thread Safety: All public methods are thread-safe.

Definition at line 223 of file pacs_monitor.h.

Constructor & Destructor Documentation

◆ pacs_monitor() [1/3]

kcenon::pacs::monitoring::pacs_monitor::pacs_monitor ( const pacs_monitor_config & config = {})
inlineexplicit

Construct a new PACS monitor.

Parameters
configConfiguration options
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 408 of file pacs_monitor.h.

References initialize_collectors().

Here is the call graph for this function:

◆ ~pacs_monitor()

kcenon::pacs::monitoring::pacs_monitor::~pacs_monitor ( )
default

◆ pacs_monitor() [2/3]

kcenon::pacs::monitoring::pacs_monitor::pacs_monitor ( const pacs_monitor & )
delete

◆ pacs_monitor() [3/3]

kcenon::pacs::monitoring::pacs_monitor::pacs_monitor ( pacs_monitor && )
delete

Member Function Documentation

◆ association_collector()

dicom_association_collector & kcenon::pacs::monitoring::pacs_monitor::association_collector ( )
inlinenodiscard

Get the association collector.

Returns
Reference to the association collector
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 622 of file pacs_monitor.h.

622 {
624}
std::unique_ptr< dicom_association_collector > association_collector_

References association_collector_.

◆ check_health()

health_check_result kcenon::pacs::monitoring::pacs_monitor::check_health ( )
inlinenodiscard

Perform health check.

Returns
Health check result
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 501 of file pacs_monitor.h.

501 {
502 const auto start = std::chrono::steady_clock::now();
503 health_check_result result;
504 result.status = monitor_health_status::healthy;
505
506 std::lock_guard<std::mutex> lock(health_checks_mutex_);
507
508 bool all_healthy = true;
509 bool any_check_failed = false;
510
511 for (const auto& [component, check] : health_checks_) {
512 try {
513 if (!check()) {
514 all_healthy = false;
515 result.metadata[component] = "unhealthy";
516 } else {
517 result.metadata[component] = "healthy";
518 }
519 } catch (const std::exception& e) {
520 any_check_failed = true;
521 result.metadata[component] = std::string("error: ") + e.what();
522 }
523 }
524
525 // Check collectors health
526 if (association_collector_ && !association_collector_->is_healthy()) {
527 all_healthy = false;
528 result.metadata["association_collector"] = "unhealthy";
529 }
530 if (service_collector_ && !service_collector_->is_healthy()) {
531 all_healthy = false;
532 result.metadata["service_collector"] = "unhealthy";
533 }
534 if (storage_collector_ && !storage_collector_->is_healthy()) {
535 all_healthy = false;
536 result.metadata["storage_collector"] = "unhealthy";
537 }
538 if (unified_collector_ && !unified_collector_->is_healthy()) {
539 all_healthy = false;
540 result.metadata["unified_collector"] = "unhealthy";
541 }
542
543 if (any_check_failed) {
544 result.status = monitor_health_status::unhealthy;
545 result.message = "Some health checks threw exceptions";
546 } else if (!all_healthy) {
547 result.status = monitor_health_status::degraded;
548 result.message = "Some components are unhealthy";
549 } else {
550 result.message = "All components healthy";
551 }
552
553 const auto end = std::chrono::steady_clock::now();
554 result.check_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
555
556 return result;
557}
std::unique_ptr< dicom_storage_collector > storage_collector_
std::unordered_map< std::string, std::function< bool()> > health_checks_
std::unique_ptr< dicom_metrics_collector > unified_collector_
std::unique_ptr< dicom_service_collector > service_collector_

References association_collector_, kcenon::pacs::monitoring::health_check_result::check_duration, kcenon::pacs::monitoring::degraded, health_checks_, health_checks_mutex_, kcenon::pacs::monitoring::healthy, kcenon::pacs::monitoring::health_check_result::message, kcenon::pacs::monitoring::health_check_result::metadata, service_collector_, kcenon::pacs::monitoring::health_check_result::status, storage_collector_, kcenon::pacs::monitoring::unhealthy, and unified_collector_.

◆ collect_all_metrics()

void kcenon::pacs::monitoring::pacs_monitor::collect_all_metrics ( metrics_snapshot & snapshot)
inlineprivate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 459 of file pacs_monitor.h.

459 {
460 std::shared_lock<std::shared_mutex> config_lock(config_mutex_);
461
462 // Collect association metrics
464 for (const auto& m : association_collector_->collect()) {
465 snapshot.add_metric(
466 m.name,
467 m.value,
468 m.type == "counter" ? metric_type::counter : metric_type::gauge);
469 }
470 }
471
472 // Collect service metrics
474 for (const auto& m : service_collector_->collect()) {
475 snapshot.add_metric(
476 m.name,
477 m.value,
478 m.type == "counter" ? metric_type::counter : metric_type::gauge);
479 }
480 }
481
482 // Collect storage metrics
484 for (const auto& m : storage_collector_->collect()) {
485 snapshot.add_metric(
486 m.name,
487 m.value,
488 m.type == "counter" ? metric_type::counter : metric_type::gauge);
489 }
490 }
491
492 // Add custom metrics
493 {
494 std::lock_guard<std::mutex> lock(custom_metrics_mutex_);
495 for (const auto& m : custom_metrics_) {
496 snapshot.metrics.push_back(m);
497 }
498 }
499}
std::vector< metric_value > custom_metrics_
@ gauge
Instant value that can go up or down.
@ counter
Monotonic increasing value.
bool enable_association_metrics
Enable association metrics collection.
bool enable_service_metrics
Enable DIMSE service metrics collection.
bool enable_storage_metrics
Enable storage metrics collection.

References kcenon::pacs::monitoring::metrics_snapshot::add_metric(), association_collector_, config_, config_mutex_, kcenon::pacs::monitoring::counter, custom_metrics_, custom_metrics_mutex_, kcenon::pacs::monitoring::pacs_monitor_config::enable_association_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_service_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_storage_metrics, kcenon::pacs::monitoring::gauge, kcenon::pacs::monitoring::metrics_snapshot::metrics, service_collector_, and storage_collector_.

Referenced by get_metrics().

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

◆ get_config()

const pacs_monitor_config & kcenon::pacs::monitoring::pacs_monitor::get_config ( ) const
inlinenodiscard

Get current configuration.

Returns
Current monitor configuration
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 592 of file pacs_monitor.h.

592 {
593 std::shared_lock<std::shared_mutex> lock(config_mutex_);
594 return config_;
595}

References config_, and config_mutex_.

◆ get_metrics()

metrics_snapshot kcenon::pacs::monitoring::pacs_monitor::get_metrics ( )
inlinenodiscard

Get current metrics snapshot.

Returns
Metrics snapshot containing all collected metrics
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 452 of file pacs_monitor.h.

452 {
453 metrics_snapshot snapshot;
454 snapshot.source_id = config_.ae_title;
455 collect_all_metrics(snapshot);
456 return snapshot;
457}
void collect_all_metrics(metrics_snapshot &snapshot)
std::string ae_title
Application Entity title for metric labels.

References kcenon::pacs::monitoring::pacs_monitor_config::ae_title, collect_all_metrics(), config_, and kcenon::pacs::monitoring::metrics_snapshot::source_id.

Here is the call graph for this function:

◆ get_unified_snapshot()

dicom_metrics_snapshot kcenon::pacs::monitoring::pacs_monitor::get_unified_snapshot ( ) const
inlinenodiscard

Get a snapshot from the unified collector.

Returns
Metrics snapshot with all DICOM metrics
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 638 of file pacs_monitor.h.

638 {
639 if (unified_collector_) {
640 return unified_collector_->get_snapshot();
641 }
642 return dicom_metrics_snapshot{};
643}

References unified_collector_.

◆ global_monitor()

static pacs_monitor & kcenon::pacs::monitoring::pacs_monitor::global_monitor ( )
inlinestaticnodiscardnoexcept

Get the global singleton instance.

Returns
Reference to the global monitor instance

Thread-safe lazy initialization using Meyer's singleton pattern.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 246 of file pacs_monitor.h.

246 {
247 static pacs_monitor instance;
248 return instance;
249 }

◆ initialize_collectors()

void kcenon::pacs::monitoring::pacs_monitor::initialize_collectors ( )
inlineprivate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 413 of file pacs_monitor.h.

413 {
414 association_collector_ = std::make_unique<dicom_association_collector>(config_.ae_title);
415 service_collector_ = std::make_unique<dicom_service_collector>(config_.ae_title);
416 storage_collector_ = std::make_unique<dicom_storage_collector>(config_.ae_title);
417 unified_collector_ = std::make_unique<dicom_metrics_collector>(config_.ae_title);
418
419 // Initialize all collectors
420 std::unordered_map<std::string, std::string> collector_config;
421 collector_config["ae_title"] = config_.ae_title;
422
423 (void)association_collector_->initialize(collector_config);
424 (void)service_collector_->initialize(collector_config);
425 (void)storage_collector_->initialize(collector_config);
426 storage_collector_->set_pool_metrics_enabled(config_.enable_pool_metrics);
427
428 // Initialize unified CRTP-based collector
429 config_map unified_config;
430 unified_config["ae_title"] = config_.ae_title;
431 unified_config["collect_associations"] = config_.enable_association_metrics ? "true" : "false";
432 unified_config["collect_transfers"] = config_.enable_storage_metrics ? "true" : "false";
433 unified_config["collect_storage"] = config_.enable_storage_metrics ? "true" : "false";
434 unified_config["collect_queries"] = config_.enable_service_metrics ? "true" : "false";
435 unified_config["collect_pools"] = config_.enable_pool_metrics ? "true" : "false";
436 (void)unified_collector_->initialize(unified_config);
437}
bool enable_pool_metrics
Enable object pool metrics.

References kcenon::pacs::monitoring::pacs_monitor_config::ae_title, association_collector_, config_, kcenon::pacs::monitoring::pacs_monitor_config::enable_association_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_pool_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_service_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_storage_metrics, service_collector_, storage_collector_, and unified_collector_.

Referenced by pacs_monitor().

Here is the caller graph for this function:

◆ operator=() [1/2]

pacs_monitor & kcenon::pacs::monitoring::pacs_monitor::operator= ( const pacs_monitor & )
delete

◆ operator=() [2/2]

pacs_monitor & kcenon::pacs::monitoring::pacs_monitor::operator= ( pacs_monitor && )
delete

◆ record_metric() [1/2]

void kcenon::pacs::monitoring::pacs_monitor::record_metric ( std::string_view name,
double value )
inline

Record a metric value.

Parameters
nameMetric name
valueMetric value
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 439 of file pacs_monitor.h.

439 {
440 std::lock_guard<std::mutex> lock(custom_metrics_mutex_);
441 custom_metrics_.emplace_back(std::string(name), value);
442}
std::string_view name

References custom_metrics_, custom_metrics_mutex_, and name.

◆ record_metric() [2/2]

void kcenon::pacs::monitoring::pacs_monitor::record_metric ( std::string_view name,
double value,
const std::unordered_map< std::string, std::string > & tags )
inline

Record a metric with tags.

Parameters
nameMetric name
valueMetric value
tagsAdditional metadata tags

Definition at line 444 of file pacs_monitor.h.

447 {
448 std::lock_guard<std::mutex> lock(custom_metrics_mutex_);
449 custom_metrics_.emplace_back(std::string(name), value, metric_type::gauge, tags);
450}

References custom_metrics_, custom_metrics_mutex_, kcenon::pacs::monitoring::gauge, and name.

◆ register_health_check()

void kcenon::pacs::monitoring::pacs_monitor::register_health_check ( std::string_view component,
std::function< bool()> check )
inline

Register a health check for a component.

Parameters
componentComponent name
checkFunction that returns true if healthy
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 580 of file pacs_monitor.h.

582 {
583 std::lock_guard<std::mutex> lock(health_checks_mutex_);
584 health_checks_[std::string(component)] = std::move(check);
585}

References health_checks_, and health_checks_mutex_.

◆ reset()

void kcenon::pacs::monitoring::pacs_monitor::reset ( )
inline

Reset all metrics.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 559 of file pacs_monitor.h.

559 {
560 // Reset underlying metrics
562
563 // Clear custom metrics
564 {
565 std::lock_guard<std::mutex> lock(custom_metrics_mutex_);
566 custom_metrics_.clear();
567 }
568}
void reset() noexcept
Reset all metrics to zero.
static pacs_metrics & global_metrics() noexcept
Get the global singleton instance.

References custom_metrics_, custom_metrics_mutex_, kcenon::pacs::monitoring::pacs_metrics::global_metrics(), and kcenon::pacs::monitoring::pacs_metrics::reset().

Here is the call graph for this function:

◆ service_collector()

dicom_service_collector & kcenon::pacs::monitoring::pacs_monitor::service_collector ( )
inlinenodiscard

Get the service collector.

Returns
Reference to the service collector
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 626 of file pacs_monitor.h.

626 {
627 return *service_collector_;
628}

References service_collector_.

◆ storage_collector()

dicom_storage_collector & kcenon::pacs::monitoring::pacs_monitor::storage_collector ( )
inlinenodiscard

Get the storage collector.

Returns
Reference to the storage collector
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 630 of file pacs_monitor.h.

630 {
631 return *storage_collector_;
632}

References storage_collector_.

◆ to_json()

std::string kcenon::pacs::monitoring::pacs_monitor::to_json ( ) const
inlinenodiscard

Export all metrics as JSON.

Returns
JSON representation of all metrics
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 575 of file pacs_monitor.h.

575 {
576 // Use existing pacs_metrics JSON export
578}
std::string to_json() const
Export metrics as JSON string.

References kcenon::pacs::monitoring::pacs_metrics::global_metrics(), and kcenon::pacs::monitoring::pacs_metrics::to_json().

Here is the call graph for this function:

◆ to_prometheus()

std::string kcenon::pacs::monitoring::pacs_monitor::to_prometheus ( ) const
inlinenodiscard

Export all metrics in Prometheus text format.

Returns
Prometheus exposition format text
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 570 of file pacs_monitor.h.

570 {
571 // Use existing pacs_metrics Prometheus export
573}
std::string to_prometheus(std::string_view prefix="pacs") const
Export metrics in Prometheus text format.
std::string metric_prefix
Metric name prefix for Prometheus export.

References config_, kcenon::pacs::monitoring::pacs_metrics::global_metrics(), kcenon::pacs::monitoring::pacs_monitor_config::metric_prefix, and kcenon::pacs::monitoring::pacs_metrics::to_prometheus().

Here is the call graph for this function:

◆ unified_collector()

dicom_metrics_collector & kcenon::pacs::monitoring::pacs_monitor::unified_collector ( )
inlinenodiscard

Get the unified CRTP-based metrics collector.

Returns
Reference to the unified metrics collector
See also
Issue #490 - CRTP-based DICOM metrics collector
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 634 of file pacs_monitor.h.

634 {
635 return *unified_collector_;
636}

References unified_collector_.

◆ unregister_health_check()

void kcenon::pacs::monitoring::pacs_monitor::unregister_health_check ( std::string_view component)
inline

Unregister a health check.

Parameters
componentComponent name to unregister
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 587 of file pacs_monitor.h.

587 {
588 std::lock_guard<std::mutex> lock(health_checks_mutex_);
589 health_checks_.erase(std::string(component));
590}

References health_checks_, and health_checks_mutex_.

◆ update_config()

void kcenon::pacs::monitoring::pacs_monitor::update_config ( const pacs_monitor_config & config)
inline

Update configuration.

Parameters
configNew configuration
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/monitoring/pacs_monitor.h.

Definition at line 597 of file pacs_monitor.h.

597 {
598 std::unique_lock<std::shared_mutex> lock(config_mutex_);
599 config_ = config;
600
601 // Update collector configurations
604 }
605 if (service_collector_) {
606 service_collector_->set_ae_title(config_.ae_title);
607 }
608 if (storage_collector_) {
609 storage_collector_->set_ae_title(config_.ae_title);
610 storage_collector_->set_pool_metrics_enabled(config_.enable_pool_metrics);
611 }
612 if (unified_collector_) {
613 unified_collector_->set_ae_title(config_.ae_title);
614 unified_collector_->set_collect_associations(config_.enable_association_metrics);
615 unified_collector_->set_collect_transfers(config_.enable_storage_metrics);
619 }
620}

References kcenon::pacs::monitoring::pacs_monitor_config::ae_title, association_collector_, config_, config_mutex_, kcenon::pacs::monitoring::pacs_monitor_config::enable_association_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_pool_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_service_metrics, kcenon::pacs::monitoring::pacs_monitor_config::enable_storage_metrics, service_collector_, storage_collector_, and unified_collector_.

Member Data Documentation

◆ association_collector_

std::unique_ptr<dicom_association_collector> kcenon::pacs::monitoring::pacs_monitor::association_collector_
private

◆ config_

◆ config_mutex_

std::shared_mutex kcenon::pacs::monitoring::pacs_monitor::config_mutex_
mutableprivate

◆ custom_metrics_

std::vector<metric_value> kcenon::pacs::monitoring::pacs_monitor::custom_metrics_
private

◆ custom_metrics_mutex_

std::mutex kcenon::pacs::monitoring::pacs_monitor::custom_metrics_mutex_
mutableprivate

◆ health_checks_

std::unordered_map<std::string, std::function<bool()> > kcenon::pacs::monitoring::pacs_monitor::health_checks_
private

◆ health_checks_mutex_

std::mutex kcenon::pacs::monitoring::pacs_monitor::health_checks_mutex_
mutableprivate

◆ service_collector_

std::unique_ptr<dicom_service_collector> kcenon::pacs::monitoring::pacs_monitor::service_collector_
private

◆ storage_collector_

std::unique_ptr<dicom_storage_collector> kcenon::pacs::monitoring::pacs_monitor::storage_collector_
private

◆ unified_collector_

std::unique_ptr<dicom_metrics_collector> kcenon::pacs::monitoring::pacs_monitor::unified_collector_
private

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