Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
platform_metrics_example.cpp
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#include <iostream>
19#include <thread>
20#include <chrono>
21#include <iomanip>
22
24
25using namespace kcenon::monitoring;
26using namespace std::chrono_literals;
27
32 std::cout << "\n=== Platform Information ===" << std::endl;
33
34 if (info.available) {
35 std::cout << "Platform: " << info.name << std::endl;
36 std::cout << "Version: " << info.version << std::endl;
37 std::cout << "Architecture: " << info.architecture << std::endl;
38 } else {
39 std::cout << "Platform information not available" << std::endl;
40 }
41}
42
47 std::cout << "\n=== Uptime Metrics ===" << std::endl;
48
49 if (uptime.available) {
50 // Convert seconds to days, hours, minutes
51 int64_t seconds = uptime.uptime_seconds;
52 int64_t days = seconds / (24 * 3600);
53 seconds %= (24 * 3600);
54 int64_t hours = seconds / 3600;
55 seconds %= 3600;
56 int64_t minutes = seconds / 60;
57 seconds %= 60;
58
59 std::cout << "System Uptime: " << days << "d " << hours << "h "
60 << minutes << "m " << seconds << "s" << std::endl;
61 std::cout << "Total Uptime: " << uptime.uptime_seconds << " seconds" << std::endl;
62 std::cout << "Idle Time: " << uptime.idle_seconds << " seconds" << std::endl;
63
64 // Display boot timestamp as ISO 8601 format if available
65 if (uptime.boot_timestamp > 0) {
66 auto boot_time = std::chrono::system_clock::from_time_t(uptime.boot_timestamp);
67 auto boot_tt = std::chrono::system_clock::to_time_t(boot_time);
68 std::tm boot_tm{};
69#ifdef _MSC_VER
70 localtime_s(&boot_tm, &boot_tt);
71#else
72 localtime_r(&boot_tt, &boot_tm);
73#endif
74 std::cout << "Boot Time: " << std::put_time(&boot_tm, "%Y-%m-%d %H:%M:%S") << std::endl;
75 }
76 } else {
77 std::cout << "Uptime metrics not available on this platform" << std::endl;
78 }
79}
80
85 std::cout << "\n=== Context Switch Statistics ===" << std::endl;
86
87 if (switches.available) {
88 std::cout << "Total Switches: " << switches.total_switches << std::endl;
89 std::cout << "Voluntary Switches: " << switches.voluntary_switches << std::endl;
90 std::cout << "Involuntary Switches: " << switches.involuntary_switches << std::endl;
91 std::cout << "Switches Per Second: " << std::fixed << std::setprecision(2)
92 << switches.switches_per_second << std::endl;
93 } else {
94 std::cout << "Context switch statistics not available on this platform" << std::endl;
95 }
96}
97
102 std::cout << "\n=== TCP Connection States ===" << std::endl;
103
104 if (tcp.available) {
105 std::cout << "ESTABLISHED: " << tcp.established << std::endl;
106 std::cout << "SYN_SENT: " << tcp.syn_sent << std::endl;
107 std::cout << "SYN_RECV: " << tcp.syn_recv << std::endl;
108 std::cout << "FIN_WAIT1: " << tcp.fin_wait1 << std::endl;
109 std::cout << "FIN_WAIT2: " << tcp.fin_wait2 << std::endl;
110 std::cout << "TIME_WAIT: " << tcp.time_wait << std::endl;
111 std::cout << "CLOSE_WAIT: " << tcp.close_wait << std::endl;
112 std::cout << "LISTEN: " << tcp.listen << std::endl;
113 std::cout << "Total Connections: " << tcp.total << std::endl;
114 } else {
115 std::cout << "TCP state information not available on this platform" << std::endl;
116 }
117}
118
123 std::cout << "\n=== Socket Buffer Information ===" << std::endl;
124
125 if (socket.available) {
126 std::cout << "RX Buffer Size: " << (socket.rx_buffer_size / 1024.0) << " KB" << std::endl;
127 std::cout << "TX Buffer Size: " << (socket.tx_buffer_size / 1024.0) << " KB" << std::endl;
128 std::cout << "RX Buffer Used: " << (socket.rx_buffer_used / 1024.0) << " KB ("
129 << std::fixed << std::setprecision(1)
130 << (socket.rx_buffer_size > 0 ? (socket.rx_buffer_used * 100.0 / socket.rx_buffer_size) : 0.0)
131 << "%)" << std::endl;
132 std::cout << "TX Buffer Used: " << (socket.tx_buffer_used / 1024.0) << " KB ("
133 << (socket.tx_buffer_size > 0 ? (socket.tx_buffer_used * 100.0 / socket.tx_buffer_size) : 0.0)
134 << "%)" << std::endl;
135 } else {
136 std::cout << "Socket buffer information not available on this platform" << std::endl;
137 }
138}
139
144 std::cout << "\n=== Interrupt Statistics ===" << std::endl;
145
146 if (interrupts.available) {
147 std::cout << "Total Interrupts: " << interrupts.total_interrupts << std::endl;
148 } else {
149 std::cout << "Interrupt statistics not available on this platform" << std::endl;
150 }
151}
152
157 std::cout << "\n=== Platform-Specific Feature Detection ===" << std::endl;
158
159 // Collect platform info first
160 auto info = collector.get_platform_info();
161
162 std::cout << "\nDetected Platform: " << info.name << std::endl;
163
164 // Demonstrate feature availability checks before collection
165 std::cout << "\nFeature Availability:" << std::endl;
166
167 // Display feature availability
168 std::cout << " Platform Available: " << (collector.is_platform_available() ? "Yes" : "No") << std::endl;
169 std::cout << " Collector Health: " << (collector.is_available() ? "Healthy" : "Unhealthy") << std::endl;
170
171 std::cout << "\nNote: The Strategy pattern abstracts platform-specific implementations." << std::endl;
172 std::cout << " Features not supported on a platform return empty/unavailable values." << std::endl;
173
174#if defined(__linux__)
175 std::cout << "\nLinux-specific features:" << std::endl;
176 std::cout << " - Reading /proc/stat for context switches" << std::endl;
177 std::cout << " - Reading /proc/net/tcp for TCP state info" << std::endl;
178 std::cout << " - Reading /proc/uptime for system uptime" << std::endl;
179#elif defined(__APPLE__)
180 std::cout << "\nmacOS-specific features:" << std::endl;
181 std::cout << " - Using sysctl for system metrics" << std::endl;
182 std::cout << " - Limited TCP state information" << std::endl;
183 std::cout << " - Using kern.boottime for uptime" << std::endl;
184#elif defined(_WIN32)
185 std::cout << "\nWindows-specific features:" << std::endl;
186 std::cout << " - Using GetTickCount64 for uptime" << std::endl;
187 std::cout << " - Using Performance Counters for metrics" << std::endl;
188 std::cout << " - Limited context switch information" << std::endl;
189#else
190 std::cout << "\nUnknown platform - limited feature support" << std::endl;
191#endif
192}
193
197void demonstrate_metric_normalization(const std::vector<metric>& metrics) {
198 std::cout << "\n=== Cross-Platform Metric Normalization ===" << std::endl;
199
200 std::cout << "\nAll metrics use standardized naming conventions:" << std::endl;
201 std::cout << " platform.uptime.* - Uptime metrics" << std::endl;
202 std::cout << " platform.context_switches.* - Context switch metrics" << std::endl;
203 std::cout << " platform.tcp.* - TCP state metrics" << std::endl;
204 std::cout << " platform.socket.* - Socket buffer metrics" << std::endl;
205 std::cout << " platform.interrupts.* - Interrupt metrics" << std::endl;
206
207 std::cout << "\nCollected Metrics (" << metrics.size() << " total):" << std::endl;
208
209 // Display metrics directly without grouping to avoid compilation issues
210 for (const auto& m : metrics) {
211 std::cout << " " << m.name << ": ";
212 std::visit([](const auto& val) { std::cout << val; }, m.value);
213 auto unit_it = m.tags.find("unit");
214 if (unit_it != m.tags.end() && !unit_it->second.empty()) {
215 std::cout << " " << unit_it->second;
216 }
217 std::cout << std::endl;
218 }
219}
220
221int main() {
222 std::cout << "=== Platform Metrics Example ===" << std::endl;
223
224 try {
225 // Step 1: Create platform_metrics_collector with configuration
226 std::cout << "\n1. Creating platform_metrics_collector..." << std::endl;
227
229 config.collect_uptime = true;
230 config.collect_context_switches = true;
231 config.collect_tcp_states = true;
232 config.collect_socket_buffers = true;
233 config.collect_interrupts = true;
234
235 platform_metrics_collector collector(config);
236
237 // Initialize the collector
238 std::unordered_map<std::string, std::string> init_config;
239 if (!collector.initialize(init_config)) {
240 std::cerr << "Failed to initialize platform_metrics_collector" << std::endl;
241 return 1;
242 }
243
244 std::cout << " Initialized: " << collector.name() << std::endl;
245 std::cout << " Health: " << (collector.is_available() ? "OK" : "UNHEALTHY") << std::endl;
246
247 // Step 2: Display platform information
248 std::cout << "\n2. Retrieving platform information..." << std::endl;
249 auto platform_info = collector.get_platform_info();
251
252 // Step 3: Demonstrate platform-specific feature detection
253 std::cout << "\n3. Demonstrating platform-specific features..." << std::endl;
255
256 // Step 4: Collect and display metrics (3 iterations)
257 std::cout << "\n4. Collecting platform metrics (3 iterations)..." << std::endl;
258
259 for (int i = 0; i < 3; ++i) {
260 std::cout << "\n--- Iteration " << (i + 1) << "/3 ---" << std::endl;
261
262 // Collect all platform metrics
263 auto metrics = collector.collect();
264 std::cout << "Metrics collected: " << metrics.size() << std::endl;
265
266 // Get last collected metrics for detailed display
267 auto last_metrics = collector.get_last_metrics();
268
269 // Display each metric category
270 display_uptime_metrics(last_metrics.uptime);
271 display_context_switch_stats(last_metrics.context_switches);
272 display_tcp_info(last_metrics.tcp);
273 display_socket_info(last_metrics.socket);
274 display_interrupt_info(last_metrics.interrupts);
275
276 // Wait before next collection
277 if (i < 2) {
278 std::cout << "\nWaiting 2 seconds before next collection..." << std::endl;
279 std::this_thread::sleep_for(2s);
280 }
281 }
282
283 // Step 5: Demonstrate metric normalization
284 std::cout << "\n5. Demonstrating cross-platform metric normalization..." << std::endl;
285 auto final_metrics = collector.collect();
287
288 // Step 6: Display collector statistics
289 std::cout << "\n6. Collector Statistics:" << std::endl;
290
291 auto stats = collector.get_statistics();
292 for (const auto& [key, value] : stats) {
293 std::cout << " " << key << ": " << value << std::endl;
294 }
295
296 // Step 7: Demonstrate dynamic configuration updates
297 std::cout << "\n7. Configuration note:" << std::endl;
298 std::cout << " Platform metrics collector configuration is set at initialization." << std::endl;
299 std::cout << " To change configuration, recreate the collector with new config." << std::endl;
300
301 std::cout << "\n=== Example completed successfully ===" << std::endl;
302
303 } catch (const std::exception& e) {
304 std::cerr << "Exception: " << e.what() << std::endl;
305 return 1;
306 }
307
308 return 0;
309}
Unified platform-agnostic metrics collector.
auto is_available() const -> bool override
bool initialize(const config_map &config) override
auto name() const -> std::string_view override
auto get_statistics() const -> stats_map override
auto collect() -> std::vector< metric > override
@ info
Informational, no action required.
Unified platform-agnostic metrics collector.
void display_platform_info(const platform_info &info)
void display_interrupt_info(const platform_interrupt_info &interrupts)
void demonstrate_metric_normalization(const std::vector< metric > &metrics)
void display_uptime_metrics(const platform_uptime &uptime)
void display_tcp_info(const platform_tcp_info &tcp)
void display_context_switch_stats(const platform_context_switches &switches)
void demonstrate_platform_features(platform_metrics_collector &collector)
void display_socket_info(const platform_socket_info &socket)
double switches_per_second
Context switches per second.
uint64_t voluntary_switches
Voluntary context switches.
uint64_t involuntary_switches
Involuntary context switches.
Platform identification information.
std::string name
Platform name (linux, macos, windows, unknown)
Configuration for platform metrics collection.
bool collect_context_switches
Collect context switch metrics.
bool collect_socket_buffers
Collect socket buffer metrics.
Platform TCP connection state information.
uint64_t established
ESTABLISHED connections.
int64_t boot_timestamp
Unix timestamp of last boot.
int64_t idle_seconds
Total idle time in seconds.
int64_t uptime_seconds
System uptime in seconds.
bool available
Whether uptime info is available.