PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
logger_adapter.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
18#pragma once
19
20#include <chrono>
21#include <cstdint>
22#include <filesystem>
24#include <functional>
25#include <map>
26#include <memory>
27#include <optional>
28#include <string>
29#include <string_view>
30
32
33// ─────────────────────────────────────────────────────
34// Forward Declarations
35// ─────────────────────────────────────────────────────
36
41enum class log_level {
42 trace = 0,
43 debug = 1,
44 info = 2,
45 warn = 3,
46 error = 4,
47 fatal = 5,
48 off = 6
49};
50
65
80
81// Note: query_level may also be defined in monitoring_adapter.hpp
82#ifndef PACS_INTEGRATION_QUERY_LEVEL_DEFINED
83#define PACS_INTEGRATION_QUERY_LEVEL_DEFINED
89#endif
90
104
105// ─────────────────────────────────────────────────────
106// Configuration
107// ─────────────────────────────────────────────────────
108
115 std::filesystem::path log_directory{"logs"};
116
119
121 bool enable_console{true};
122
124 bool enable_file{true};
125
128
130 std::size_t max_file_size_mb{100};
131
133 std::size_t max_files{10};
134
136 std::string audit_log_format{"json"};
137
139 bool async_mode{true};
140
142 std::size_t buffer_size{8192};
143};
144
145// ─────────────────────────────────────────────────────
146// Logger Adapter Class
147// ─────────────────────────────────────────────────────
148
185public:
186 // ─────────────────────────────────────────────────────
187 // Initialization
188 // ─────────────────────────────────────────────────────
189
199 static void initialize(const logger_config& config);
200
207 static void shutdown();
208
213 [[nodiscard]] static auto is_initialized() noexcept -> bool;
214
215 // ─────────────────────────────────────────────────────
216 // Standard Logging
217 // ─────────────────────────────────────────────────────
218
225 template <typename... Args>
226 static void trace(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
227 log(log_level::trace, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
228 }
229
236 template <typename... Args>
237 static void debug(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
238 log(log_level::debug, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
239 }
240
247 template <typename... Args>
248 static void info(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
249 log(log_level::info, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
250 }
251
258 template <typename... Args>
259 static void warn(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
260 log(log_level::warn, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
261 }
262
269 template <typename... Args>
270 static void error(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
271 log(log_level::error, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
272 }
273
280 template <typename... Args>
281 static void fatal(kcenon::pacs::compat::format_string<Args...> fmt, Args&&... args) {
282 log(log_level::fatal, kcenon::pacs::compat::format(fmt, std::forward<Args>(args)...));
283 }
284
290 static void log(log_level level, const std::string& message);
291
297 [[nodiscard]] static auto is_level_enabled(log_level level) noexcept -> bool;
298
302 static void flush();
303
304 // ─────────────────────────────────────────────────────
305 // DICOM Audit Logging (for HIPAA/compliance)
306 // ─────────────────────────────────────────────────────
307
318 static void log_association_established(const std::string& calling_ae,
319 const std::string& called_ae,
320 const std::string& remote_ip);
321
330 static void log_association_released(const std::string& calling_ae,
331 const std::string& called_ae);
332
345 static void log_c_store_received(const std::string& calling_ae,
346 const std::string& patient_id,
347 const std::string& study_uid,
348 const std::string& sop_instance_uid,
349 storage_status status);
350
360 static void log_c_find_executed(const std::string& calling_ae,
361 query_level level,
362 std::size_t matches_returned);
363
375 static void log_c_move_executed(const std::string& calling_ae,
376 const std::string& destination_ae,
377 const std::string& study_uid,
378 std::size_t instances_moved,
379 move_status status);
380
391 const std::string& description,
392 const std::string& user_id = "");
393
394 // ─────────────────────────────────────────────────────
395 // Configuration
396 // ─────────────────────────────────────────────────────
397
402 static void set_min_level(log_level level);
403
408 [[nodiscard]] static auto get_min_level() noexcept -> log_level;
409
414 [[nodiscard]] static auto get_config() -> const logger_config&;
415
416private:
417 // Private implementation helpers
418 static void write_audit_log(const std::string& event_type,
419 const std::string& outcome,
420 const std::map<std::string, std::string>& fields);
421
422 [[nodiscard]] static auto storage_status_to_string(storage_status status) -> std::string;
423 [[nodiscard]] static auto move_status_to_string(move_status status) -> std::string;
424 [[nodiscard]] static auto query_level_to_string(query_level level) -> std::string;
425 [[nodiscard]] static auto security_event_to_string(security_event_type type) -> std::string;
426 [[nodiscard]] static auto log_level_to_string(log_level level) -> std::string;
427
428 // Internal state (managed through pimpl or static members)
429 class impl;
430 static std::unique_ptr<impl> pimpl_;
431};
432
433} // namespace kcenon::pacs::integration
Adapter for DICOM audit logging using logger_system.
static std::unique_ptr< impl > pimpl_
static void flush()
Flush all pending log messages.
static void trace(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log a trace-level message.
static void log_c_find_executed(const std::string &calling_ae, query_level level, std::size_t matches_returned)
Log C-FIND operation.
static void log_security_event(security_event_type type, const std::string &description, const std::string &user_id="")
Log a security-related event.
static void write_audit_log(const std::string &event_type, const std::string &outcome, const std::map< std::string, std::string > &fields)
static void log_c_store_received(const std::string &calling_ae, const std::string &patient_id, const std::string &study_uid, const std::string &sop_instance_uid, storage_status status)
Log C-STORE operation.
static void log_association_released(const std::string &calling_ae, const std::string &called_ae)
Log DICOM association release.
static void log_c_move_executed(const std::string &calling_ae, const std::string &destination_ae, const std::string &study_uid, std::size_t instances_moved, move_status status)
Log C-MOVE operation.
static void shutdown()
Shutdown the logger.
static auto security_event_to_string(security_event_type type) -> std::string
static void log(log_level level, const std::string &message)
Log a message at the specified level.
static auto get_config() -> const logger_config &
Get the current configuration.
static void debug(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log a debug-level message.
static auto log_level_to_string(log_level level) -> std::string
static auto storage_status_to_string(storage_status status) -> std::string
static void info(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log an info-level message.
static void warn(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log a warning-level message.
static auto is_level_enabled(log_level level) noexcept -> bool
Check if a log level is enabled.
static void set_min_level(log_level level)
Set the minimum log level.
static void error(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log an error-level message.
static void fatal(kcenon::pacs::compat::format_string< Args... > fmt, Args &&... args)
Log a fatal-level message.
static auto move_status_to_string(move_status status) -> std::string
static auto is_initialized() noexcept -> bool
Check if the logger is initialized.
static void initialize(const logger_config &config)
Initialize the logger with configuration.
static auto get_min_level() noexcept -> log_level
Get the current minimum log level.
static void log_association_established(const std::string &calling_ae, const std::string &called_ae, const std::string &remote_ip)
Log DICOM association establishment.
static auto query_level_to_string(query_level level) -> std::string
Compatibility header providing kcenon::pacs::compat::format as an alias for std::format.
std::format_string< Args... > format_string
Definition format.h:31
storage_status
Status of DICOM C-STORE operations.
security_event_type
Types of security events for audit logging.
log_level
Log severity levels.
query_level
DICOM query retrieve level.
move_status
Status of DICOM C-MOVE operations.
Configuration options for the logger adapter.
bool async_mode
Use asynchronous logging for better performance.
std::string audit_log_format
Audit log format: "json" or "syslog".
std::size_t max_files
Maximum number of rotated log files to keep.
bool enable_audit_log
Enable separate audit trail file for HIPAA compliance.
std::size_t max_file_size_mb
Maximum log file size in megabytes before rotation.
bool enable_console
Enable console output.
log_level min_level
Minimum log level to output.
std::size_t buffer_size
Buffer size for async logging.
std::filesystem::path log_directory
Directory for log files.