Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
custom_metric_types_example.cpp File Reference

Example demonstrating custom metric types: histogram, summary, and timer. More...

#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include <random>
#include <vector>
#include "kcenon/monitoring/utils/metric_types.h"
Include dependency graph for custom_metric_types_example.cpp:

Go to the source code of this file.

Functions

double simulate_api_call (std::mt19937 &rng)
 
void demonstrate_histogram ()
 
void demonstrate_summary ()
 
void demonstrate_timer ()
 
void demonstrate_timer_scope ()
 
void demonstrate_metric_metadata ()
 
void demonstrate_metric_batch ()
 
int main ()
 

Detailed Description

Example demonstrating custom metric types: histogram, summary, and timer.

Definition in file custom_metric_types_example.cpp.

Function Documentation

◆ demonstrate_histogram()

void demonstrate_histogram ( )
Examples
custom_metric_types_example.cpp.

Definition at line 49 of file custom_metric_types_example.cpp.

49 {
50 std::cout << "\n=== Histogram Metric Example ===" << std::endl;
51 std::cout << "Tracking request size distribution\n" << std::endl;
52
53 histogram_data request_sizes;
54
55 // Initialize with custom buckets for request sizes (in KB)
56 request_sizes.buckets = {
57 {1.0, 0}, // <= 1KB
58 {10.0, 0}, // <= 10KB
59 {100.0, 0}, // <= 100KB
60 {1000.0, 0}, // <= 1MB
61 {10000.0, 0} // <= 10MB
62 };
63
64 // Simulate various request sizes
65 std::mt19937 rng(42);
66 std::exponential_distribution<> size_dist(0.1); // Most requests are small
67
68 std::cout << "Recording 1000 request sizes..." << std::endl;
69 for (int i = 0; i < 1000; ++i) {
70 double size_kb = size_dist(rng) * 10; // Scale to reasonable KB range
71 request_sizes.add_sample(size_kb);
72 }
73
74 // Display results
75 std::cout << "\nHistogram Results:" << std::endl;
76 std::cout << " Total requests: " << request_sizes.total_count << std::endl;
77 std::cout << " Total size: " << std::fixed << std::setprecision(2)
78 << request_sizes.sum << " KB" << std::endl;
79 std::cout << " Mean size: " << request_sizes.mean() << " KB" << std::endl;
80 std::cout << "\nBucket Distribution:" << std::endl;
81
82 uint64_t prev_count = 0;
83 for (const auto& bucket : request_sizes.buckets) {
84 uint64_t bucket_count = bucket.count - prev_count;
85 double percentage = (bucket_count * 100.0) / request_sizes.total_count;
86 std::cout << " <= " << std::setw(7) << bucket.upper_bound << " KB: "
87 << std::setw(5) << bucket_count << " requests ("
88 << std::setw(5) << std::fixed << std::setprecision(1)
89 << percentage << "%)" << std::endl;
90 prev_count = bucket.count;
91 }
92}
Histogram data with buckets.
double mean() const noexcept
Get mean value.
std::vector< histogram_bucket > buckets
void add_sample(double value)
Add value to histogram.

References kcenon::monitoring::histogram_data::add_sample(), kcenon::monitoring::histogram_data::buckets, kcenon::monitoring::histogram_data::mean(), kcenon::monitoring::histogram_data::sum, and kcenon::monitoring::histogram_data::total_count.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ demonstrate_metric_batch()

void demonstrate_metric_batch ( )
Examples
custom_metric_types_example.cpp.

Definition at line 222 of file custom_metric_types_example.cpp.

222 {
223 std::cout << "\n=== Metric Batch Example ===" << std::endl;
224 std::cout << "Batching metrics for efficient processing\n" << std::endl;
225
226 metric_batch batch(1);
227 batch.reserve(100);
228
229 // Add various metrics to the batch
230 auto counter_meta = create_metric_metadata("requests", metric_type::counter);
231 auto gauge_meta = create_metric_metadata("connections", metric_type::gauge);
232
233 std::cout << "Adding 100 metrics to batch..." << std::endl;
234 for (int i = 0; i < 50; ++i) {
235 batch.add_metric(compact_metric_value(counter_meta, int64_t(i * 10)));
236 batch.add_metric(compact_metric_value(gauge_meta, double(100 + i)));
237 }
238
239 std::cout << "\nBatch Statistics:" << std::endl;
240 std::cout << " Batch ID: " << batch.batch_id << std::endl;
241 std::cout << " Metrics count: " << batch.size() << std::endl;
242 std::cout << " Memory footprint: " << batch.memory_footprint() << " bytes" << std::endl;
243 std::cout << " Is empty: " << (batch.empty() ? "yes" : "no") << std::endl;
244
245 // Clear and verify
246 batch.clear();
247 std::cout << "\nAfter clear:" << std::endl;
248 std::cout << " Metrics count: " << batch.size() << std::endl;
249 std::cout << " Is empty: " << (batch.empty() ? "yes" : "no") << std::endl;
250}
metric_metadata create_metric_metadata(const std::string &name, metric_type type, size_t tag_count=0)
Create metric metadata from name and type.
Memory-efficient metric value storage.
Batch of metrics for efficient processing.

References kcenon::monitoring::metric_batch::add_metric(), kcenon::monitoring::metric_batch::batch_id, kcenon::monitoring::metric_batch::clear(), kcenon::monitoring::create_metric_metadata(), kcenon::monitoring::metric_batch::empty(), kcenon::monitoring::metric_batch::memory_footprint(), kcenon::monitoring::metric_batch::reserve(), and kcenon::monitoring::metric_batch::size().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ demonstrate_metric_metadata()

void demonstrate_metric_metadata ( )
Examples
custom_metric_types_example.cpp.

Definition at line 186 of file custom_metric_types_example.cpp.

186 {
187 std::cout << "\n=== Metric Metadata Example ===" << std::endl;
188 std::cout << "Creating and using metric metadata\n" << std::endl;
189
190 // Create metadata for different metric types
191 auto counter_meta = create_metric_metadata("http_requests_total", metric_type::counter, 2);
192 auto gauge_meta = create_metric_metadata("memory_usage_bytes", metric_type::gauge, 1);
193 auto histogram_meta = create_metric_metadata("request_duration_seconds", metric_type::histogram, 3);
194
195 std::cout << "Metric Metadata Examples:" << std::endl;
196 std::cout << " Counter: http_requests_total" << std::endl;
197 std::cout << " - Hash: " << counter_meta.name_hash << std::endl;
198 std::cout << " - Type: " << metric_type_to_string(counter_meta.type) << std::endl;
199 std::cout << " - Tags: " << static_cast<int>(counter_meta.tag_count) << std::endl;
200
201 std::cout << "\n Gauge: memory_usage_bytes" << std::endl;
202 std::cout << " - Hash: " << gauge_meta.name_hash << std::endl;
203 std::cout << " - Type: " << metric_type_to_string(gauge_meta.type) << std::endl;
204 std::cout << " - Tags: " << static_cast<int>(gauge_meta.tag_count) << std::endl;
205
206 std::cout << "\n Histogram: request_duration_seconds" << std::endl;
207 std::cout << " - Hash: " << histogram_meta.name_hash << std::endl;
208 std::cout << " - Type: " << metric_type_to_string(histogram_meta.type) << std::endl;
209 std::cout << " - Tags: " << static_cast<int>(histogram_meta.tag_count) << std::endl;
210
211 // Create compact metric values
212 compact_metric_value counter_value(counter_meta, int64_t(12345));
213 compact_metric_value gauge_value(gauge_meta, 1024.5);
214
215 std::cout << "\nCompact Metric Values:" << std::endl;
216 std::cout << " Counter value: " << counter_value.as_int64() << std::endl;
217 std::cout << " Gauge value: " << gauge_value.as_double() << std::endl;
218 std::cout << " Memory footprint (counter): " << counter_value.memory_footprint() << " bytes" << std::endl;
219 std::cout << " Memory footprint (gauge): " << gauge_value.memory_footprint() << " bytes" << std::endl;
220}
constexpr const char * metric_type_to_string(metric_type type) noexcept
Convert metric type to string.

References kcenon::monitoring::compact_metric_value::as_double(), kcenon::monitoring::create_metric_metadata(), kcenon::monitoring::compact_metric_value::memory_footprint(), and kcenon::monitoring::metric_type_to_string().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ demonstrate_summary()

void demonstrate_summary ( )
Examples
custom_metric_types_example.cpp.

Definition at line 94 of file custom_metric_types_example.cpp.

94 {
95 std::cout << "\n=== Summary Metric Example ===" << std::endl;
96 std::cout << "Tracking CPU usage over time\n" << std::endl;
97
98 summary_data cpu_usage;
99
100 // Simulate CPU usage readings
101 std::mt19937 rng(123);
102 std::normal_distribution<> usage_dist(45.0, 15.0); // Mean 45%, stddev 15%
103
104 std::cout << "Recording 100 CPU usage samples..." << std::endl;
105 for (int i = 0; i < 100; ++i) {
106 double usage = std::clamp(usage_dist(rng), 0.0, 100.0);
107 cpu_usage.add_sample(usage);
108 }
109
110 // Display results
111 std::cout << "\nSummary Results:" << std::endl;
112 std::cout << " Sample count: " << cpu_usage.count << std::endl;
113 std::cout << " Min CPU: " << std::fixed << std::setprecision(2)
114 << cpu_usage.min_value << "%" << std::endl;
115 std::cout << " Max CPU: " << cpu_usage.max_value << "%" << std::endl;
116 std::cout << " Mean CPU: " << cpu_usage.mean() << "%" << std::endl;
117 std::cout << " Total sum: " << cpu_usage.sum << std::endl;
118
119 // Demonstrate reset functionality
120 std::cout << "\nResetting summary..." << std::endl;
121 cpu_usage.reset();
122 std::cout << " After reset - count: " << cpu_usage.count << std::endl;
123}
Summary statistics for metrics.
void add_sample(double value)
Add sample to summary.
double mean() const noexcept
Get mean value.

References kcenon::monitoring::summary_data::add_sample(), kcenon::monitoring::summary_data::count, kcenon::monitoring::summary_data::max_value, kcenon::monitoring::summary_data::mean(), kcenon::monitoring::summary_data::min_value, kcenon::monitoring::summary_data::reset(), and kcenon::monitoring::summary_data::sum.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ demonstrate_timer()

void demonstrate_timer ( )
Examples
custom_metric_types_example.cpp.

Definition at line 125 of file custom_metric_types_example.cpp.

125 {
126 std::cout << "\n=== Timer Metric Example ===" << std::endl;
127 std::cout << "Measuring API response times with percentiles\n" << std::endl;
128
129 // Create timer with custom reservoir size
130 timer_data api_latency(512);
131
132 std::mt19937 rng(456);
133
134 std::cout << "Simulating 500 API calls..." << std::endl;
135 for (int i = 0; i < 500; ++i) {
136 double latency = simulate_api_call(rng);
137 api_latency.record(latency);
138 }
139
140 // Get and display snapshot
141 auto snapshot = api_latency.get_snapshot();
142
143 std::cout << "\nTimer Results:" << std::endl;
144 std::cout << " Total calls: " << snapshot.count << std::endl;
145 std::cout << " Min latency: " << std::fixed << std::setprecision(2)
146 << snapshot.min << " ms" << std::endl;
147 std::cout << " Max latency: " << snapshot.max << " ms" << std::endl;
148 std::cout << " Mean latency: " << snapshot.mean << " ms" << std::endl;
149 std::cout << " Std deviation: " << snapshot.stddev << " ms" << std::endl;
150
151 std::cout << "\nPercentiles:" << std::endl;
152 std::cout << " p50 (median): " << snapshot.p50 << " ms" << std::endl;
153 std::cout << " p90: " << snapshot.p90 << " ms" << std::endl;
154 std::cout << " p95: " << snapshot.p95 << " ms" << std::endl;
155 std::cout << " p99: " << snapshot.p99 << " ms" << std::endl;
156 std::cout << " p99.9: " << snapshot.p999 << " ms" << std::endl;
157}
double simulate_api_call(std::mt19937 &rng)
Timer data with percentile calculations.

References kcenon::monitoring::timer_data::snapshot::count, kcenon::monitoring::timer_data::get_snapshot(), kcenon::monitoring::timer_data::record(), and simulate_api_call().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ demonstrate_timer_scope()

void demonstrate_timer_scope ( )
Examples
custom_metric_types_example.cpp.

Definition at line 159 of file custom_metric_types_example.cpp.

159 {
160 std::cout << "\n=== Timer Scope (RAII) Example ===" << std::endl;
161 std::cout << "Automatic duration recording with RAII pattern\n" << std::endl;
162
163 timer_data operation_timer;
164
165 // Simulate different operations with automatic timing
166 std::cout << "Running 10 operations with automatic timing..." << std::endl;
167
168 for (int i = 0; i < 10; ++i) {
169 // timer_scope automatically records duration when it goes out of scope
170 timer_scope scope(operation_timer);
171
172 // Simulate varying work
173 std::this_thread::sleep_for(std::chrono::milliseconds(20 + (i * 5)));
174 }
175
176 // Display results
177 std::cout << "\nTimer Scope Results:" << std::endl;
178 std::cout << " Operations recorded: " << operation_timer.count() << std::endl;
179 std::cout << " Mean duration: " << std::fixed << std::setprecision(2)
180 << operation_timer.mean() << " ms" << std::endl;
181 std::cout << " Min duration: " << operation_timer.min() << " ms" << std::endl;
182 std::cout << " Max duration: " << operation_timer.max() << " ms" << std::endl;
183 std::cout << " p95 duration: " << operation_timer.p95() << " ms" << std::endl;
184}
RAII timer scope for automatic duration recording with timer_data.
uint64_t count() const noexcept
Get sample count.
double mean() const noexcept
Get mean value.
double p95() const
Get p95 value.
double max() const noexcept
Get maximum recorded value.
double min() const noexcept
Get minimum recorded value.

References kcenon::monitoring::timer_data::count(), kcenon::monitoring::timer_data::max(), kcenon::monitoring::timer_data::mean(), kcenon::monitoring::timer_data::min(), and kcenon::monitoring::timer_data::p95().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( )

Definition at line 252 of file custom_metric_types_example.cpp.

252 {
253 std::cout << "========================================" << std::endl;
254 std::cout << " Custom Metric Types Example" << std::endl;
255 std::cout << " monitoring_system v2.0" << std::endl;
256 std::cout << "========================================" << std::endl;
257
258 try {
259 // Demonstrate each metric type
266
267 std::cout << "\n========================================" << std::endl;
268 std::cout << " Example completed successfully!" << std::endl;
269 std::cout << "========================================" << std::endl;
270
271 } catch (const std::exception& e) {
272 std::cerr << "Error: " << e.what() << std::endl;
273 return 1;
274 }
275
276 return 0;
277}
void demonstrate_metric_metadata()
void demonstrate_timer()
void demonstrate_summary()
void demonstrate_timer_scope()
void demonstrate_metric_batch()
void demonstrate_histogram()

References demonstrate_histogram(), demonstrate_metric_batch(), demonstrate_metric_metadata(), demonstrate_summary(), demonstrate_timer(), and demonstrate_timer_scope().

Here is the call graph for this function:

◆ simulate_api_call()

double simulate_api_call ( std::mt19937 & rng)
Examples
custom_metric_types_example.cpp.

Definition at line 30 of file custom_metric_types_example.cpp.

30 {
31 // Most calls are fast (10-50ms), some are slow (100-500ms)
32 std::uniform_real_distribution<> fast_dist(10.0, 50.0);
33 std::uniform_real_distribution<> slow_dist(100.0, 500.0);
34 std::uniform_int_distribution<> is_slow(1, 10);
35
36 double latency;
37 if (is_slow(rng) == 1) {
38 // 10% of calls are slow
39 latency = slow_dist(rng);
40 } else {
41 latency = fast_dist(rng);
42 }
43
44 // Simulate the actual delay
45 std::this_thread::sleep_for(std::chrono::microseconds(static_cast<int>(latency * 100)));
46 return latency;
47}

Referenced by demonstrate_timer().

Here is the caller graph for this function: