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

Demonstrates time-series storage for metric history. More...

#include <iostream>
#include <memory>
#include <chrono>
#include <thread>
#include <random>
#include <iomanip>
#include "kcenon/monitoring/utils/time_series.h"
Include dependency graph for time_series_storage_example.cpp:

Go to the source code of this file.

Functions

std::string format_timestamp (std::chrono::system_clock::time_point tp)
 Format timestamp for display.
 
void demonstrate_basic_operations ()
 Demonstrate basic time-series operations.
 
void demonstrate_aggregations ()
 Demonstrate aggregation queries.
 
void demonstrate_retention_and_downsampling ()
 Demonstrate retention policy and downsampling.
 
void demonstrate_batch_operations ()
 Demonstrate batch point insertion.
 
int main ()
 

Detailed Description

Demonstrates time-series storage for metric history.

Definition in file time_series_storage_example.cpp.

Function Documentation

◆ demonstrate_aggregations()

void demonstrate_aggregations ( )

Demonstrate aggregation queries.

Examples
time_series_storage_example.cpp.

Definition at line 151 of file time_series_storage_example.cpp.

151 {
152 std::cout << "\n=== Aggregation Queries ===" << std::endl;
153
154 try {
155 // Create time-series
156 time_series_config config;
157 config.retention_period = 1h;
158 config.max_points = 3600;
159
160 auto ts_result = time_series::create("response_time_ms", config);
161 if (ts_result.is_err()) {
162 return;
163 }
164
165 auto ts = std::move(ts_result.value());
166
167 // Add sample data: simulated response times
168 std::cout << "\n1. Populating with response time data..." << std::endl;
169
170 auto now = std::chrono::system_clock::now();
171 std::random_device rd;
172 std::mt19937 gen(rd());
173 std::normal_distribution<> dis(100.0, 20.0); // Mean 100ms, stddev 20ms
174
175 for (int i = 0; i < 500; ++i) {
176 auto timestamp = now - std::chrono::seconds(500 - i);
177 double response_time = std::max(10.0, dis(gen)); // Min 10ms
178
179 ts->add_point(response_time, timestamp);
180 }
181
182 std::cout << " ✓ Added 500 response time measurements" << std::endl;
183
184 // Query last 5 minutes with 1-minute aggregation
185 std::cout << "\n2. Aggregation query (last 5 minutes)..." << std::endl;
186
187 time_series_query query;
188 query.start_time = now - 5min;
189 query.end_time = now;
190 query.step = 1min; // 1-minute buckets
191
192 auto query_result = ts->query(query);
193 if (query_result.is_ok()) {
194 const auto& result = query_result.value();
195 auto summary = result.get_summary();
196
197 std::cout << "\n Aggregation results:" << std::endl;
198 std::cout << " Count: " << summary.count << std::endl;
199 std::cout << " Average: "
200 << std::fixed << std::setprecision(2)
201 << summary.mean() << " ms" << std::endl;
202 std::cout << " Min: "
203 << std::fixed << std::setprecision(2)
204 << summary.min_value << " ms" << std::endl;
205 std::cout << " Max: "
206 << std::fixed << std::setprecision(2)
207 << summary.max_value << " ms" << std::endl;
208 std::cout << " Sum: "
209 << std::fixed << std::setprecision(2)
210 << summary.sum << " ms" << std::endl;
211 std::cout << " Rate of change: "
212 << std::fixed << std::setprecision(2)
213 << result.get_rate() << " ms/s" << std::endl;
214 }
215
216 } catch (const std::exception& e) {
217 std::cerr << "Exception: " << e.what() << std::endl;
218 }
219}
static common::Result< std::unique_ptr< time_series > > create(const std::string &name, const time_series_config &config={})
Factory method to create time_series with validation.
@ summary
Pre-calculated quantiles and count/sum.
Configuration for time series storage.
Definition time_series.h:34
std::chrono::seconds retention_period
Definition time_series.h:35
Query parameters for time series data.
std::chrono::milliseconds step
std::chrono::system_clock::time_point start_time
std::chrono::system_clock::time_point end_time

References kcenon::monitoring::time_series::create(), kcenon::monitoring::time_series_query::end_time, kcenon::monitoring::time_series_config::max_points, kcenon::monitoring::time_series_config::retention_period, kcenon::monitoring::time_series_query::start_time, kcenon::monitoring::time_series_query::step, and kcenon::monitoring::summary.

Referenced by main().

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

◆ demonstrate_basic_operations()

void demonstrate_basic_operations ( )

Demonstrate basic time-series operations.

Examples
time_series_storage_example.cpp.

Definition at line 55 of file time_series_storage_example.cpp.

55 {
56 std::cout << "=== Basic Time-Series Operations ===" << std::endl;
57
58 try {
59 // Step 1: Create time-series with configuration
60 std::cout << "\n1. Creating time-series storage..." << std::endl;
61
62 time_series_config config;
63 config.retention_period = 1h; // Keep data for 1 hour
64 config.resolution = 1s; // 1-second resolution
65 config.max_points = 3600; // Max 3600 points (1 hour of data)
66 config.enable_compression = true;
67 config.compression_threshold = 0.1;
68
69 auto ts_result = time_series::create("cpu_usage", config);
70 if (ts_result.is_err()) {
71 std::cerr << " Failed to create time-series: "
72 << ts_result.error().message << std::endl;
73 return;
74 }
75
76 auto ts = std::move(ts_result.value());
77 std::cout << " ✓ Created time-series: " << ts->name() << std::endl;
78 std::cout << " Retention: " << config.retention_period.count() << "s" << std::endl;
79 std::cout << " Max points: " << config.max_points << std::endl;
80
81 // Step 2: Write metrics with timestamps
82 std::cout << "\n2. Writing metric data points..." << std::endl;
83
84 auto now = std::chrono::system_clock::now();
85 std::random_device rd;
86 std::mt19937 gen(rd());
87 std::uniform_real_distribution<> dis(30.0, 90.0);
88
89 // Add 100 data points over the last 100 seconds
90 for (int i = 0; i < 100; ++i) {
91 auto timestamp = now - std::chrono::seconds(100 - i);
92 double cpu_value = dis(gen); // Random CPU usage 30-90%
93
94 auto add_result = ts->add_point(cpu_value, timestamp);
95 if (add_result.is_err()) {
96 std::cerr << " Failed to add point: "
97 << add_result.error().message << std::endl;
98 }
99 }
100
101 std::cout << " ✓ Added 100 data points" << std::endl;
102 std::cout << " Current size: " << ts->size() << " points" << std::endl;
103 std::cout << " Memory footprint: " << ts->memory_footprint() << " bytes" << std::endl;
104
105 // Step 3: Get latest value
106 std::cout << "\n3. Retrieving latest value..." << std::endl;
107
108 auto latest_result = ts->get_latest_value();
109 if (latest_result.is_ok()) {
110 std::cout << " Latest CPU usage: "
111 << std::fixed << std::setprecision(2)
112 << latest_result.value() << "%" << std::endl;
113 }
114
115 // Step 4: Time-range query (last 30 seconds)
116 std::cout << "\n4. Querying last 30 seconds..." << std::endl;
117
118 time_series_query query;
119 query.start_time = now - 30s;
120 query.end_time = now;
121 query.step = 5s; // 5-second aggregation steps
122
123 auto query_result = ts->query(query);
124 if (query_result.is_ok()) {
125 const auto& result = query_result.value();
126 std::cout << " ✓ Query returned " << result.points.size()
127 << " aggregated points" << std::endl;
128 std::cout << " Total samples: " << result.total_samples << std::endl;
129 std::cout << " Average value: "
130 << std::fixed << std::setprecision(2)
131 << result.get_average() << "%" << std::endl;
132
133 // Show first 3 points
134 std::cout << "\n Sample points:" << std::endl;
135 for (size_t i = 0; i < std::min(size_t(3), result.points.size()); ++i) {
136 const auto& point = result.points[i];
137 std::cout << " [" << format_timestamp(point.timestamp) << "] "
138 << std::fixed << std::setprecision(2) << point.value << "%"
139 << " (samples: " << point.sample_count << ")" << std::endl;
140 }
141 }
142
143 } catch (const std::exception& e) {
144 std::cerr << "Exception: " << e.what() << std::endl;
145 }
146}
std::chrono::milliseconds resolution
Definition time_series.h:36
std::string format_timestamp(std::chrono::system_clock::time_point tp)
Format timestamp for display.

References kcenon::monitoring::time_series_config::compression_threshold, kcenon::monitoring::time_series::create(), kcenon::monitoring::time_series_config::enable_compression, kcenon::monitoring::time_series_query::end_time, format_timestamp(), kcenon::monitoring::time_series_config::max_points, kcenon::monitoring::time_series_config::resolution, kcenon::monitoring::time_series_config::retention_period, kcenon::monitoring::time_series_query::start_time, and kcenon::monitoring::time_series_query::step.

Referenced by main().

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

◆ demonstrate_batch_operations()

void demonstrate_batch_operations ( )

Demonstrate batch point insertion.

Examples
time_series_storage_example.cpp.

Definition at line 292 of file time_series_storage_example.cpp.

292 {
293 std::cout << "\n=== Batch Point Operations ===" << std::endl;
294
295 try {
296 std::cout << "\n1. Creating time-series..." << std::endl;
297
298 auto ts_result = time_series::create("network_throughput_mbps");
299 if (ts_result.is_err()) {
300 return;
301 }
302
303 auto ts = std::move(ts_result.value());
304
305 // Create batch of points
306 std::cout << "\n2. Preparing batch of data points..." << std::endl;
307
308 std::vector<time_point_data> batch;
309 auto now = std::chrono::system_clock::now();
310
311 std::random_device rd;
312 std::mt19937 gen(rd());
313 std::uniform_real_distribution<> dis(50.0, 200.0);
314
315 for (int i = 0; i < 200; ++i) {
316 auto timestamp = now - std::chrono::seconds(200 - i);
317 double throughput = dis(gen);
318 batch.emplace_back(timestamp, throughput);
319 }
320
321 std::cout << " ✓ Prepared " << batch.size() << " points" << std::endl;
322
323 // Add batch
324 std::cout << "\n3. Adding batch..." << std::endl;
325
326 auto add_result = ts->add_points(batch);
327 if (add_result.is_ok()) {
328 std::cout << " ✓ Batch insert successful" << std::endl;
329 std::cout << " Total points in series: " << ts->size() << std::endl;
330 std::cout << " Memory footprint: " << ts->memory_footprint() << " bytes" << std::endl;
331 }
332
333 } catch (const std::exception& e) {
334 std::cerr << "Exception: " << e.what() << std::endl;
335 }
336}

References kcenon::monitoring::time_series::create().

Referenced by main().

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

◆ demonstrate_retention_and_downsampling()

void demonstrate_retention_and_downsampling ( )

Demonstrate retention policy and downsampling.

Examples
time_series_storage_example.cpp.

Definition at line 224 of file time_series_storage_example.cpp.

224 {
225 std::cout << "\n=== Retention Policy & Downsampling ===" << std::endl;
226
227 try {
228 std::cout << "\n1. Creating time-series with short retention..." << std::endl;
229
230 time_series_config config;
231 config.retention_period = 60s; // Only keep last 60 seconds
232 config.max_points = 120; // Limit to 120 points
233 config.enable_compression = true; // Enable downsampling
234
235 auto ts_result = time_series::create("memory_usage_mb", config);
236 if (ts_result.is_err()) {
237 return;
238 }
239
240 auto ts = std::move(ts_result.value());
241 std::cout << " ✓ Created time-series with 60-second retention" << std::endl;
242
243 // Add old data (beyond retention)
244 std::cout << "\n2. Adding old data (beyond retention period)..." << std::endl;
245
246 auto now = std::chrono::system_clock::now();
247
248 // Add data from 2 minutes ago (should be cleaned up)
249 for (int i = 0; i < 60; ++i) {
250 auto old_timestamp = now - 120s + std::chrono::seconds(i);
251 ts->add_point(500.0 + i, old_timestamp);
252 }
253
254 // Add recent data (within retention)
255 for (int i = 0; i < 60; ++i) {
256 auto recent_timestamp = now - 60s + std::chrono::seconds(i);
257 ts->add_point(800.0 + i, recent_timestamp);
258 }
259
260 std::cout << " Added 120 points total" << std::endl;
261 std::cout << " Current size after cleanup: " << ts->size() << " points" << std::endl;
262 std::cout << " (Old data beyond retention was automatically removed)" << std::endl;
263
264 // Query all data
265 std::cout << "\n3. Querying all retained data..." << std::endl;
266
267 time_series_query query;
268 query.start_time = now - 60s;
269 query.end_time = now;
270 query.step = 10s;
271
272 auto query_result = ts->query(query);
273 if (query_result.is_ok()) {
274 const auto& result = query_result.value();
275 std::cout << " ✓ Retrieved " << result.points.size()
276 << " downsampled points (from " << result.total_samples
277 << " original samples)" << std::endl;
278 std::cout << " Downsampling ratio: "
279 << std::fixed << std::setprecision(1)
280 << (double)result.total_samples / result.points.size()
281 << "x compression" << std::endl;
282 }
283
284 } catch (const std::exception& e) {
285 std::cerr << "Exception: " << e.what() << std::endl;
286 }
287}

References kcenon::monitoring::time_series::create(), kcenon::monitoring::time_series_config::enable_compression, kcenon::monitoring::time_series_query::end_time, kcenon::monitoring::time_series_config::max_points, kcenon::monitoring::time_series_config::retention_period, kcenon::monitoring::time_series_query::start_time, and kcenon::monitoring::time_series_query::step.

Referenced by main().

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

◆ format_timestamp()

std::string format_timestamp ( std::chrono::system_clock::time_point tp)

Format timestamp for display.

Examples
time_series_storage_example.cpp.

Definition at line 34 of file time_series_storage_example.cpp.

34 {
35 auto time_t = std::chrono::system_clock::to_time_t(tp);
36 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
37 tp.time_since_epoch()) % 1000;
38
39 std::tm tm;
40#ifdef _WIN32
41 localtime_s(&tm, &time_t);
42#else
43 localtime_r(&time_t, &tm);
44#endif
45
46 std::ostringstream oss;
47 oss << std::put_time(&tm, "%H:%M:%S")
48 << '.' << std::setfill('0') << std::setw(3) << ms.count();
49 return oss.str();
50}

Referenced by demonstrate_basic_operations().

Here is the caller graph for this function:

◆ main()

int main ( )

Definition at line 338 of file time_series_storage_example.cpp.

338 {
339 std::cout << "Time-Series Storage Example\n" << std::endl;
340
341 // Demonstrate basic operations
343
344 std::cout << "\n" << std::string(60, '=') << "\n" << std::endl;
345
346 // Demonstrate aggregation queries
348
349 std::cout << "\n" << std::string(60, '=') << "\n" << std::endl;
350
351 // Demonstrate retention and downsampling
353
354 std::cout << "\n" << std::string(60, '=') << "\n" << std::endl;
355
356 // Demonstrate batch operations
358
359 std::cout << "\n=== Example completed successfully ===" << std::endl;
360
361 return 0;
362}
void demonstrate_aggregations()
Demonstrate aggregation queries.
void demonstrate_retention_and_downsampling()
Demonstrate retention policy and downsampling.
void demonstrate_basic_operations()
Demonstrate basic time-series operations.
void demonstrate_batch_operations()
Demonstrate batch point insertion.

References demonstrate_aggregations(), demonstrate_basic_operations(), demonstrate_batch_operations(), and demonstrate_retention_and_downsampling().

Here is the call graph for this function: