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