Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
system_resource_collector.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
12#pragma once
13
14#include <array>
15#include <atomic>
16#include <chrono>
17#include <cstdint>
18#include <fstream>
19#include <iomanip>
20#include <iostream>
21#include <memory>
22#include <mutex>
23#include <numeric>
24#include <sstream>
25#include <string>
26#include <thread>
27#include <unordered_map>
28#include <vector>
29
30#ifdef __APPLE__
31 #include <mach/mach.h>
32 #include <mach/mach_host.h>
33 #include <mach/processor_info.h>
34 #include <mach/vm_map.h>
35 #include <sys/sysctl.h>
36 #include <sys/types.h>
37#elif __linux__
38 #include <sys/sysinfo.h>
39 #include <unistd.h>
40#elif _WIN32
41 #ifndef WIN32_LEAN_AND_MEAN
42 #define WIN32_LEAN_AND_MEAN
43 #endif
44 #ifndef NOMINMAX
45 #define NOMINMAX
46 #endif
47 // winsock2.h must be included before windows.h to avoid redefinition errors
48 #include <winsock2.h>
49 #include <ws2tcpip.h>
50 #include <windows.h>
51 #include <iphlpapi.h>
52 #include <psapi.h>
53 #pragma comment(lib, "ws2_32.lib")
54 #pragma comment(lib, "iphlpapi.lib")
55#endif
56
59
60namespace kcenon { namespace monitoring {
61
69 bool collect_cpu = true;
70 bool collect_memory = true;
71 bool collect_disk = true;
72 bool collect_network = true;
73 bool collect_process = true;
74 bool enable_load_history = false;
76 std::chrono::milliseconds interval = std::chrono::seconds(10);
77};
78
91 struct cpu_metrics {
92 double usage_percent{0.0};
93 double user_percent{0.0};
94 double system_percent{0.0};
95 double idle_percent{0.0};
96 size_t count{0};
97
102 double one_min{0.0};
103 double five_min{0.0};
104 double fifteen_min{0.0};
107
112 size_t total_bytes{0};
114 size_t used_bytes{0};
115 double usage_percent{0.0};
116
120 struct swap_info {
121 size_t total_bytes{0};
122 size_t used_bytes{0};
123 double usage_percent{0.0};
126
146
160
170
175 uint64_t total{0};
176 uint64_t per_sec{0};
177 uint64_t voluntary{0};
178 uint64_t nonvoluntary{0};
180};
181
186 public:
189
195
200 std::chrono::seconds get_uptime() const;
201
206 std::string get_hostname() const;
207
212 std::string get_os_info() const;
213
214 private:
215 // CPU tracking for usage calculation
216 struct cpu_stats {
217 uint64_t user{0};
218 uint64_t nice{0};
219 uint64_t system{0};
220 uint64_t idle{0};
221 uint64_t iowait{0};
222 uint64_t irq{0};
223 uint64_t softirq{0};
224 uint64_t steal{0};
225 };
226
227 mutable std::mutex stats_mutex_;
229 std::chrono::steady_clock::time_point last_collection_time_;
230
231 // Network tracking
233 uint64_t rx_bytes{0};
234 uint64_t tx_bytes{0};
235 uint64_t rx_packets{0};
236 uint64_t tx_packets{0};
237 uint64_t rx_errors{0};
238 uint64_t tx_errors{0};
239 uint64_t rx_dropped{0};
240 uint64_t tx_dropped{0};
241 };
243
244 // Disk I/O tracking
245 struct disk_stats {
246 uint64_t read_bytes{0};
247 uint64_t write_bytes{0};
248 uint64_t read_ops{0};
249 uint64_t write_ops{0};
250 };
252
253 // Context switch tracking
255
256 // Platform-specific collection methods
262
263#ifdef __APPLE__
264 void collect_macos_cpu_stats(system_resources& resources);
265 void collect_macos_memory_stats(system_resources& resources);
266#elif __linux__
267 void collect_linux_cpu_stats(system_resources& resources);
268 void collect_linux_memory_stats(system_resources& resources);
269 cpu_stats parse_proc_stat();
270#elif _WIN32
271 void collect_windows_cpu_stats(system_resources& resources);
272 void collect_windows_memory_stats(system_resources& resources);
273#endif
274};
275
288 public:
290
296
297 ~system_resource_collector() override = default;
298
299 // metric_collector_plugin implementation
300 bool initialize(const std::unordered_map<std::string, std::string>& config) override;
301 std::vector<metric> collect() override;
302 std::string get_name() const override { return "system_resource_collector"; }
303 std::vector<std::string> get_metric_types() const override;
304 bool is_healthy() const override;
305 std::unordered_map<std::string, double> get_statistics() const override;
306
312
318
324
330 template <typename Duration>
331 std::vector<load_average_sample> get_load_history(Duration duration) const {
332 if (load_history_) {
333 return load_history_->get_samples(duration);
334 }
335 return {};
336 }
337
343 template <typename Duration>
345 if (load_history_) {
346 return load_history_->get_statistics(duration);
347 }
348 return {};
349 }
350
355 std::vector<load_average_sample> get_all_load_history() const;
356
362
367 void configure_load_history(size_t max_samples);
368
374
375 private:
376 // Collector implementation
377 std::unique_ptr<system_info_collector> collector_;
378
379 // Configuration
385
386 // Statistics
387 mutable std::mutex stats_mutex_;
388 std::atomic<size_t> collection_count_{0};
389 std::atomic<size_t> collection_errors_{0};
390 std::atomic<int64_t> init_time_ns_{0}; // Store as nanoseconds for atomic access
391 std::shared_ptr<system_resources> last_resources_; // Use shared_ptr to avoid large struct copy
392
393 // Load average history tracking
394 std::unique_ptr<load_average_history> load_history_;
396
397 // Helper methods
398 metric create_metric(const std::string& name, double value, const std::string& unit = "",
399 const std::unordered_map<std::string, std::string>& labels = {}) const;
400 void add_cpu_metrics(std::vector<metric>& metrics, const system_resources& resources);
401 void add_memory_metrics(std::vector<metric>& metrics, const system_resources& resources);
402 void add_disk_metrics(std::vector<metric>& metrics, const system_resources& resources);
403 void add_network_metrics(std::vector<metric>& metrics, const system_resources& resources);
404 void add_process_metrics(std::vector<metric>& metrics, const system_resources& resources);
405};
406
412 public:
413 struct thresholds {
414 double cpu_usage_warn{75.0};
415 double cpu_usage_critical{90.0};
416 double memory_usage_warn{80.0};
418 double disk_usage_warn{85.0};
420 double swap_usage_warn{50.0};
422 };
423
424 struct alert {
425 enum class severity { info, warning, critical };
426
427 std::string resource;
430 double threshold;
431 std::string message;
432 std::chrono::steady_clock::time_point timestamp;
433 };
434
435 explicit resource_threshold_monitor(const thresholds& config);
436
442 std::vector<alert> check_thresholds(const system_resources& resources);
443
448 void update_thresholds(const thresholds& config);
449
455
461 std::vector<alert> get_alert_history(size_t max_count = 100) const;
462
467
468 private:
469 mutable std::mutex config_mutex_;
471
472 mutable std::mutex history_mutex_;
473 std::vector<alert> alert_history_;
474 const size_t max_history_size_{1000};
475
476 void check_cpu_usage(std::vector<alert>& alerts, const system_resources& resources);
477 void check_memory_usage(std::vector<alert>& alerts, const system_resources& resources);
478 void check_disk_usage(std::vector<alert>& alerts, const system_resources& resources);
479 void check_swap_usage(std::vector<alert>& alerts, const system_resources& resources);
480 void add_alert(std::vector<alert>& alerts, const std::string& resource,
481 alert::severity level, double value, double threshold, const std::string& message);
482};
483
484} } // namespace kcenon::monitoring
void check_swap_usage(std::vector< alert > &alerts, const system_resources &resources)
resource_threshold_monitor(const thresholds &config)
std::vector< alert > get_alert_history(size_t max_count=100) const
std::vector< alert > check_thresholds(const system_resources &resources)
void check_memory_usage(std::vector< alert > &alerts, const system_resources &resources)
void update_thresholds(const thresholds &config)
void check_disk_usage(std::vector< alert > &alerts, const system_resources &resources)
void check_cpu_usage(std::vector< alert > &alerts, const system_resources &resources)
void add_alert(std::vector< alert > &alerts, const std::string &resource, alert::severity level, double value, double threshold, const std::string &message)
std::chrono::steady_clock::time_point last_collection_time_
void collect_disk_stats(system_resources &resources)
void collect_cpu_stats(system_resources &resources)
void collect_network_stats(system_resources &resources)
void collect_memory_stats(system_resources &resources)
void collect_process_stats(system_resources &resources)
std::chrono::seconds get_uptime() const
void add_disk_metrics(std::vector< metric > &metrics, const system_resources &resources)
void configure_load_history(size_t max_samples)
void add_network_metrics(std::vector< metric > &metrics, const system_resources &resources)
system_resource_collector(const system_metrics_config &config)
bool initialize(const std::unordered_map< std::string, std::string > &config) override
system_metrics_config get_config() const
std::unordered_map< std::string, double > get_statistics() const override
void add_memory_metrics(std::vector< metric > &metrics, const system_resources &resources)
load_average_statistics get_all_load_statistics() const
std::unique_ptr< system_info_collector > collector_
void add_cpu_metrics(std::vector< metric > &metrics, const system_resources &resources)
std::shared_ptr< system_resources > last_resources_
std::vector< load_average_sample > get_load_history(Duration duration) const
void set_config(const system_metrics_config &config)
std::vector< std::string > get_metric_types() const override
load_average_statistics get_load_statistics(Duration duration) const
void add_process_metrics(std::vector< metric > &metrics, const system_resources &resources)
metric create_metric(const std::string &name, double value, const std::string &unit="", const std::unordered_map< std::string, std::string > &labels={}) const
std::vector< load_average_sample > get_all_load_history() const
std::unique_ptr< load_average_history > load_history_
std::vector< metric > collect() override
Plugin-based metric collector with dynamic discovery and registration.
Statistics for load average history.
Basic metric structure for interface compatibility.
struct kcenon::monitoring::system_resources::cpu_metrics::load_average load
struct kcenon::monitoring::system_resources::disk_metrics::io_throughput io
struct kcenon::monitoring::system_resources::memory_metrics::swap_info swap
struct kcenon::monitoring::system_resources::memory_metrics memory
struct kcenon::monitoring::system_resources::cpu_metrics cpu
struct kcenon::monitoring::system_resources::process_metrics process
struct kcenon::monitoring::system_resources::disk_metrics disk
struct kcenon::monitoring::system_resources::network_metrics network
struct kcenon::monitoring::system_resources::context_switch_metrics context_switches
Generic time-series buffer for metric history tracking.