Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
registry_audit_log.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
22#pragma once
23
25
26#include <atomic>
27#include <chrono>
28#include <mutex>
29#include <string>
30#include <vector>
31
32namespace kcenon::common {
33namespace interfaces {
34
35// Use project's source_location for C++17 compatibility
37
55
61inline const char* to_string(registry_action action) {
62 switch (action) {
63 case registry_action::register_logger: return "register_logger";
64 case registry_action::unregister_logger: return "unregister_logger";
65 case registry_action::set_default_logger: return "set_default_logger";
66 case registry_action::register_factory: return "register_factory";
67 case registry_action::set_default_factory: return "set_default_factory";
68 case registry_action::clear_loggers: return "clear_loggers";
69 case registry_action::freeze_logger_registry: return "freeze_logger_registry";
70 case registry_action::register_service: return "register_service";
71 case registry_action::unregister_service: return "unregister_service";
72 case registry_action::clear_services: return "clear_services";
73 case registry_action::freeze_service_container: return "freeze_service_container";
74 default: return "unknown";
75 }
76}
77
88
90 std::string target_name;
91
93 std::string file;
94
96 int line;
97
99 std::string function;
100
102 std::chrono::system_clock::time_point timestamp;
103
106
108 std::string error_message;
109
120 registry_action act,
121 std::string target,
123 bool succeeded = true,
124 std::string error = "")
125 : action(act)
126 , target_name(std::move(target))
127 , file(loc.file_name())
128 , line(static_cast<int>(loc.line()))
129 , function(loc.function_name())
130 , timestamp(std::chrono::system_clock::now())
131 , success(succeeded)
132 , error_message(std::move(error)) {}
133};
134
162public:
170 static void log_event(const registry_event& event);
171
177 static void log_event(registry_event&& event);
178
187 static std::vector<registry_event> get_events();
188
195 static std::vector<registry_event> get_events_by_action(registry_action action);
196
204 static std::vector<registry_event> get_events_in_range(
205 std::chrono::system_clock::time_point start,
206 std::chrono::system_clock::time_point end);
207
213 static size_t event_count();
214
220 static bool is_enabled();
221
230 static void set_enabled(bool enabled);
231
241 static void clear();
242
243private:
245
246 static std::mutex& get_mutex();
247 static std::vector<registry_event>& get_events_internal();
248 static std::atomic<bool>& get_enabled_flag();
249};
250
251// ============================================================================
252// RegistryAuditLog Implementation
253// ============================================================================
254
255inline std::mutex& RegistryAuditLog::get_mutex() {
256 static std::mutex mutex;
257 return mutex;
258}
259
260inline std::vector<registry_event>& RegistryAuditLog::get_events_internal() {
261 static std::vector<registry_event> events;
262 return events;
263}
264
265inline std::atomic<bool>& RegistryAuditLog::get_enabled_flag() {
266 static std::atomic<bool> enabled{true};
267 return enabled;
268}
269
271 if (!is_enabled()) {
272 return;
273 }
274
275 std::lock_guard<std::mutex> lock(get_mutex());
276 get_events_internal().push_back(event);
277}
278
280 if (!is_enabled()) {
281 return;
282 }
283
284 std::lock_guard<std::mutex> lock(get_mutex());
285 get_events_internal().push_back(std::move(event));
286}
287
288inline std::vector<registry_event> RegistryAuditLog::get_events() {
289 std::lock_guard<std::mutex> lock(get_mutex());
290 return get_events_internal();
291}
292
293inline std::vector<registry_event> RegistryAuditLog::get_events_by_action(
294 registry_action action) {
295 std::lock_guard<std::mutex> lock(get_mutex());
296
297 std::vector<registry_event> result;
298 for (const auto& event : get_events_internal()) {
299 if (event.action == action) {
300 result.push_back(event);
301 }
302 }
303 return result;
304}
305
306inline std::vector<registry_event> RegistryAuditLog::get_events_in_range(
307 std::chrono::system_clock::time_point start,
308 std::chrono::system_clock::time_point end) {
309 std::lock_guard<std::mutex> lock(get_mutex());
310
311 std::vector<registry_event> result;
312 for (const auto& event : get_events_internal()) {
313 if (event.timestamp >= start && event.timestamp <= end) {
314 result.push_back(event);
315 }
316 }
317 return result;
318}
319
321 std::lock_guard<std::mutex> lock(get_mutex());
322 return get_events_internal().size();
323}
324
326 return get_enabled_flag().load(std::memory_order_acquire);
327}
328
329inline void RegistryAuditLog::set_enabled(bool enabled) {
330 get_enabled_flag().store(enabled, std::memory_order_release);
331}
332
334 std::lock_guard<std::mutex> lock(get_mutex());
335 get_events_internal().clear();
336}
337
338} // namespace interfaces
339} // namespace kcenon::common
Thread-safe audit log for registry operations.
static std::vector< registry_event > get_events_in_range(std::chrono::system_clock::time_point start, std::chrono::system_clock::time_point end)
Get events within a time range.
static std::vector< registry_event > get_events_by_action(registry_action action)
Get events filtered by action type.
static std::vector< registry_event > get_events()
Get all logged events.
static void log_event(const registry_event &event)
Log a registry event.
static void clear()
Clear all audit events.
static void set_enabled(bool enabled)
Enable or disable audit logging.
static size_t event_count()
Get the number of logged events.
static bool is_enabled()
Check if audit logging is enabled.
static std::vector< registry_event > & get_events_internal()
static std::atomic< bool > & get_enabled_flag()
registry_action
Types of registry mutation actions.
@ freeze_logger_registry
Freeze logger registry.
@ unregister_service
Service unregistration.
@ freeze_service_container
Freeze service container.
@ set_default_factory
Default factory set (logger)
@ register_factory
Factory registration (logger)
std::string to_string(log_level level)
Convert log level to string.
Core interfaces.
Definition adapter.h:21
C++17-compatible source_location implementation.
Generic event structure for the event bus.
Definition event_bus.h:111
Represents a single audit event for registry mutations.
int line
Line number where the operation was initiated.
std::chrono::system_clock::time_point timestamp
Timestamp when the event occurred.
registry_event(registry_action act, std::string target, const source_location &loc=source_location::current(), bool succeeded=true, std::string error="")
Construct a registry event.
bool success
Whether the operation was successful.
std::string function
Function where the operation was initiated.
std::string file
File where the operation was initiated.
std::string target_name
Name of the service or logger (empty for clear/freeze operations)
registry_action action
The type of action performed.
std::string error_message
Error message if the operation failed (empty on success)
C++17-compatible source_location implementation using compiler builtins.
Definition utils.cppm:54
static constexpr source_location current(const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE()) noexcept