26#include <shared_mutex>
120 const auto duration_us =
static_cast<std::uint64_t
>(duration.count());
125 while (duration_us < current_min &&
127 std::memory_order_relaxed)) {
132 while (duration_us > current_max &&
134 std::memory_order_relaxed)) {
142 const auto duration_us =
static_cast<std::uint64_t
>(duration.count());
147 while (duration_us < current_min &&
149 std::memory_order_relaxed)) {
153 while (duration_us > current_max &&
155 std::memory_order_relaxed)) {
183 bytes_sent.fetch_add(bytes, std::memory_order_relaxed);
203 bytes_sent.store(0, std::memory_order_relaxed);
227 const auto active =
current_active.fetch_add(1, std::memory_order_relaxed) + 1;
230 auto current_peak =
peak_active.load(std::memory_order_relaxed);
231 while (active > current_peak &&
232 !
peak_active.compare_exchange_weak(current_peak, active,
233 std::memory_order_relaxed)) {
291 return static_cast<double>(
pool_hits.load(std::memory_order_relaxed))
292 /
static_cast<double>(total);
299 pool_hits.fetch_add(1, std::memory_order_relaxed);
301 pool_misses.fetch_add(1, std::memory_order_relaxed);
318 pool_hits.store(0, std::memory_order_relaxed);
395 std::chrono::microseconds duration,
396 std::uint64_t bytes_stored = 0) noexcept {
399 if (bytes_stored > 0) {
415 std::chrono::microseconds duration,
416 [[maybe_unused]] std::uint32_t matches = 0) noexcept {
429 void record_echo(
bool success, std::chrono::microseconds duration)
noexcept {
444 std::chrono::microseconds duration,
445 std::uint32_t images_moved = 0) noexcept {
448 for (std::uint32_t i = 0; i < images_moved; ++i) {
464 std::chrono::microseconds duration,
465 std::uint32_t images_retrieved = 0,
466 std::uint64_t bytes_retrieved = 0) noexcept {
469 for (std::uint32_t i = 0; i < images_retrieved; ++i) {
472 if (bytes_retrieved > 0) {
488 std::chrono::microseconds duration)
noexcept {
491 counter.record_success(duration);
493 counter.record_failure(duration);
676 [[nodiscard]] std::string
to_json()
const;
686 [[nodiscard]] std::string
to_prometheus(std::string_view prefix =
"pacs")
const;
Central metrics collection for PACS DICOM operations.
operation_counter n_event_
void record_get(bool success, std::chrono::microseconds duration, std::uint32_t images_retrieved=0, std::uint64_t bytes_retrieved=0) noexcept
Record a C-GET operation.
void record_association_aborted() noexcept
Record an association being aborted.
const pool_counters & dataset_pool() const noexcept
Get dataset pool counters.
operation_counter c_move_
const data_transfer_metrics & transfer() const noexcept
Get data transfer metrics.
pool_counters dataset_pool_
std::string to_prometheus(std::string_view prefix="pacs") const
Export metrics in Prometheus text format.
const pool_counters & element_pool() const noexcept
Get element pool counters.
pool_counters & pdu_buffer_pool() noexcept
Get mutable PDU buffer pool counters.
pool_counters & dataset_pool() noexcept
Get mutable dataset pool counters.
void reset() noexcept
Reset all metrics to zero.
pacs_metrics & operator=(pacs_metrics &&)=delete
const operation_counter & get_counter(dimse_operation op) const noexcept
Get operation counter for a specific DIMSE operation.
void record_association_established() noexcept
Record an association being established.
void record_association_rejected() noexcept
Record an association being rejected.
operation_counter & get_counter(dimse_operation op) noexcept
Get mutable operation counter for a specific DIMSE operation.
operation_counter c_store_
void record_bytes_received(std::uint64_t bytes) noexcept
Record bytes received from the network.
static pacs_metrics & global_metrics() noexcept
Get the global singleton instance.
operation_counter n_action_
operation_counter n_create_
pacs_metrics(pacs_metrics &&)=delete
Non-movable (singleton)
pool_counters & element_pool() noexcept
Get mutable element pool counters.
void record_operation(dimse_operation op, bool success, std::chrono::microseconds duration) noexcept
Record a generic DIMSE operation.
pool_counters pdu_buffer_pool_
const pool_counters & pdu_buffer_pool() const noexcept
Get PDU buffer pool counters.
void record_bytes_sent(std::uint64_t bytes) noexcept
Record bytes sent over the network.
std::string to_json() const
Export metrics as JSON string.
pacs_metrics(const pacs_metrics &)=delete
Non-copyable.
void record_echo(bool success, std::chrono::microseconds duration) noexcept
Record a C-ECHO (verification) operation.
void record_query(bool success, std::chrono::microseconds duration, std::uint32_t matches=0) noexcept
Record a C-FIND (query) operation.
pacs_metrics & operator=(const pacs_metrics &)=delete
const association_counters & associations() const noexcept
Get association counters.
void record_association_released() noexcept
Record an association being released.
association_counters associations_
pacs_metrics()=default
Default constructor.
operation_counter c_find_
void record_move(bool success, std::chrono::microseconds duration, std::uint32_t images_moved=0) noexcept
Record a C-MOVE operation.
operation_counter c_echo_
void record_store(bool success, std::chrono::microseconds duration, std::uint64_t bytes_stored=0) noexcept
Record a C-STORE operation.
data_transfer_metrics transfer_
pool_counters element_pool_
operation_counter n_delete_
dimse_operation
DICOM Message Service Element (DIMSE) operation types.
@ c_store
C-STORE (Storage Service)
@ c_find
C-FIND (Query Service)
@ c_get
C-GET (Retrieve Service)
@ n_create
N-CREATE (MPPS)
@ c_move
C-MOVE (Retrieve Service)
@ c_echo
C-ECHO (Verification Service)
@ counter
Monotonic increasing value.
constexpr std::string_view to_string(health_level level) noexcept
Convert health level to string representation.
Metrics for tracking DICOM association lifecycle.
void reset() noexcept
Reset all counters to zero.
std::atomic< std::uint32_t > peak_active
std::atomic< std::uint64_t > total_rejected
void record_aborted() noexcept
Record an association being aborted.
std::atomic< std::uint64_t > total_aborted
void record_released() noexcept
Record an association being released normally.
std::atomic< std::uint32_t > current_active
void record_rejected() noexcept
Record an association being rejected.
std::atomic< std::uint64_t > total_established
void record_established() noexcept
Record an association being established.
Metrics for tracking data transfer volumes.
void add_bytes_received(std::uint64_t bytes) noexcept
Record bytes received.
std::atomic< std::uint64_t > images_retrieved
void reset() noexcept
Reset all counters to zero.
void increment_images_retrieved() noexcept
Record an image retrieved.
void add_bytes_sent(std::uint64_t bytes) noexcept
Record bytes sent.
void increment_images_stored() noexcept
Record an image stored.
std::atomic< std::uint64_t > bytes_sent
std::atomic< std::uint64_t > images_stored
std::atomic< std::uint64_t > bytes_received
Atomic counter for tracking operation success/failure counts.
std::atomic< std::uint64_t > max_duration_us
void reset() noexcept
Reset all counters to zero.
void record_failure(std::chrono::microseconds duration) noexcept
Record a failed operation with duration.
std::atomic< std::uint64_t > success_count
std::uint64_t average_duration_us() const noexcept
Get average duration in microseconds (0 if no operations)
std::atomic< std::uint64_t > total_duration_us
Total duration in microseconds.
std::atomic< std::uint64_t > failure_count
std::atomic< std::uint64_t > min_duration_us
void record_success(std::chrono::microseconds duration) noexcept
Record a successful operation with duration.
std::uint64_t total_count() const noexcept
Get total operation count (success + failure)
Metrics for tracking object pool usage.
void reset() noexcept
Reset all counters to zero.
std::atomic< std::uint64_t > pool_misses
std::atomic< std::uint64_t > total_acquisitions
double hit_ratio() const noexcept
Calculate hit ratio (0.0 to 1.0)
void set_pool_size(std::uint32_t size) noexcept
Update current pool size.
std::atomic< std::uint64_t > total_releases
std::atomic< std::uint64_t > pool_hits
std::atomic< std::uint32_t > current_pool_size
void record_release() noexcept
Record a pool release.
void record_acquisition(bool was_pool_hit) noexcept
Record a pool acquisition (hit or miss)