Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
thread_to_monitoring_adapter.h
Go to the documentation of this file.
1
8#pragma once
9
10// Define guard so compatibility shim does not try to include a non‑existent path
11#ifndef KCENON_MONITORING_ADAPTERS_THREAD_TO_MONITORING_ADAPTER_H
12#define KCENON_MONITORING_ADAPTERS_THREAD_TO_MONITORING_ADAPTER_H
13
14// BSD 3-Clause License
15// Copyright (c) 2025, 🍀☀🌕🌥 🌊
16// See the LICENSE file in the project root for full license information.
17
18
19// Module description:
20// Thread system adapter for monitoring_system. Provides a thin integration
21// layer that can (optionally) pull metrics from thread_system and/or publish
22// them to the monitoring event bus. When thread_system is not available, the
23// adapter degrades gracefully and returns empty metric sets.
24
25#include <atomic>
26#include <chrono>
27#include <memory>
28#include <optional>
29#include <string>
30#include <thread>
31#include <vector>
32
33#include "../core/event_bus.h"
34#include "../core/event_types.h"
37
38// Optional thread_system integration
39// Note: thread_system v3.0+ uses common_system interfaces instead of
40// thread-specific monitorable_interface.h. Detection now uses umbrella headers.
41#if !defined(MONITORING_THREAD_SYSTEM_AVAILABLE)
42# if defined(MONITORING_HAS_THREAD_SYSTEM)
43# define MONITORING_THREAD_SYSTEM_AVAILABLE 1
44# elif __has_include(<kcenon/thread/thread_pool.h>)
45# define MONITORING_THREAD_SYSTEM_AVAILABLE 1
46# else
47# define MONITORING_THREAD_SYSTEM_AVAILABLE 0
48# endif
49#endif
50
51// thread_system v3.0+ uses common_system interfaces
52#if MONITORING_THREAD_SYSTEM_AVAILABLE
53# include <kcenon/thread/interfaces/service_container.h>
54# if __has_include(<kcenon/common/interfaces/monitoring_interface.h>)
55# include <kcenon/common/interfaces/monitoring_interface.h>
56# define MONITORING_HAS_COMMON_INTERFACES 1
57# endif
58#endif
59
60namespace kcenon { namespace monitoring {
61
63public:
65 std::chrono::milliseconds interval{std::chrono::milliseconds{1000}};
66 bool publish_events{true};
67 };
68
69 explicit thread_to_monitoring_adapter(std::shared_ptr<event_bus> bus)
70 : bus_(std::move(bus)) {}
71
72 // Returns true when thread_system headers are available and a monitorable
73 // provider can be discovered at runtime (best‑effort).
75#if MONITORING_THREAD_SYSTEM_AVAILABLE
76 // thread_system v3.0+ uses common_system interfaces
77# if defined(MONITORING_HAS_COMMON_INTERFACES)
78 // Dynamic discovery via service_container if present
79 try {
80 auto& container = kcenon::thread::service_container::global();
81 auto monitorable = container.resolve<kcenon::common::interfaces::IMonitorable>();
82 return static_cast<bool>(monitorable);
83 } catch (...) {
84 return true; // Headers present; treat as available even if not registered
85 }
86# else
87 return true; // thread_system available but no common interfaces
88# endif
89#else
90 return false;
91#endif
92 }
93
94 // One‑shot collection. When thread_system is not available, returns empty.
95 common::Result<std::vector<metric>> collect_metrics() {
96 std::vector<metric> out;
97
98#if MONITORING_THREAD_SYSTEM_AVAILABLE && defined(MONITORING_HAS_COMMON_INTERFACES)
99 try {
100 auto& container = kcenon::thread::service_container::global();
101 auto monitorable = container.resolve<kcenon::common::interfaces::IMonitorable>();
102 if (monitorable) {
103 // Convert minimal subset of thread_system metrics into adapter metrics
104 // thread_system v3.0 uses common::interfaces::IMonitorable
105 auto monitoring_result = monitorable->get_monitoring_data();
106 if (!monitoring_result.is_err()) {
107 const auto& snap = monitoring_result.value();
108 // Map metrics from common_system snapshot
109 for (const auto& m : snap.metrics) {
110 metric adapted{m.name, m.value, {}};
111 out.emplace_back(std::move(adapted));
112 }
113 }
114 }
115 } catch (...) {
116 // Fall back to empty on any failure
117 }
118#endif
119
120 return common::ok(std::move(out));
121 }
122
123 // Supported metric names. Empty in fallback mode to satisfy tests.
124 std::vector<std::string> get_metric_types() const {
125#if MONITORING_THREAD_SYSTEM_AVAILABLE
126 return {
127 "thread.pool.jobs_pending",
128 "thread.pool.jobs_completed",
129 "thread.pool.worker_threads"
130 };
131#else
132 return {};
133#endif
134 }
135
136 // Start periodic collection (best‑effort). When publish_events is true,
137 // collected metrics are emitted via metric_collection_event.
138 common::VoidResult start_collection(const collection_config& cfg) {
139 if (running_.exchange(true)) {
140 return common::ok(); // already running
141 }
142
143 if (!bus_) {
144 running_ = false;
145 return common::VoidResult::err(static_cast<int>(monitoring_error_code::operation_failed), "event_bus not set");
146 }
147
148 worker_ = std::thread([this, cfg]() {
149 while (running_.load()) {
150 auto res = collect_metrics();
151 if (res.is_ok() && cfg.publish_events && !res.value().empty()) {
152 bus_->publish_event(metric_collection_event("thread_system_adapter", res.value()));
153 }
154 std::this_thread::sleep_for(cfg.interval);
155 }
156 });
157
158 return common::ok();
159 }
160
161 common::VoidResult stop_collection() {
162 if (!running_.exchange(false)) {
163 return common::ok();
164 }
165 if (worker_.joinable()) {
166 worker_.join();
167 }
168 return common::ok();
169 }
170
172
173private:
174 std::shared_ptr<event_bus> bus_;
175 std::atomic<bool> running_{false};
176 std::thread worker_;
177};
178
179} } // namespace kcenon::monitoring
180
181#endif // KCENON_MONITORING_ADAPTERS_THREAD_TO_MONITORING_ADAPTER_H
Event containing collected metrics batch.
common::Result< std::vector< metric > > collect_metrics()
common::VoidResult start_collection(const collection_config &cfg)
Lightweight event bus implementation for monitoring system.
Common event type definitions for monitoring system.
Adapter for metric types to support interface definitions.
Result pattern type definitions for monitoring system.
Basic metric structure for interface compatibility.