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

Phase 4 - Bidirectional Dependency Injection Example. More...

#include <kcenon/monitoring/core/performance_monitor.h>
#include <kcenon/common/interfaces/logger_interface.h>
#include <kcenon/common/interfaces/monitoring_interface.h>
#include <iostream>
#include <memory>
#include <chrono>
#include <thread>
Include dependency graph for bidirectional_di_example.cpp:

Go to the source code of this file.

Classes

class  console_logger
 Simple console logger implementing ILogger interface. More...
 

Functions

void demo_standalone_systems ()
 Scenario 1: Standalone Systems.
 
void demo_logger_with_monitor ()
 Scenario 2: Logger with Monitor Injection.
 
void demo_monitor_with_logger ()
 Scenario 3: Monitor with Logger Injection (via adapter)
 
void demo_bidirectional_integration ()
 Scenario 4: Bidirectional DI (THE KEY DEMO!)
 
void demo_runtime_flexibility ()
 Scenario 5: Runtime Flexibility.
 
int main ()
 

Detailed Description

Phase 4 - Bidirectional Dependency Injection Example.

Definition in file bidirectional_di_example.cpp.

Function Documentation

◆ demo_bidirectional_integration()

void demo_bidirectional_integration ( )

Scenario 4: Bidirectional DI (THE KEY DEMO!)

Examples
bidirectional_di_example.cpp.

Definition at line 212 of file bidirectional_di_example.cpp.

212 {
213 std::cout << "\n\n=== Scenario 4: Bidirectional DI (No Circular Dependency!) ===" << std::endl;
214 std::cout << "Both systems integrated at RUNTIME without compile-time circular dependency.\n" << std::endl;
215
216 // Create both systems
217 auto logger = std::make_shared<console_logger>();
218 auto monitor = std::make_shared<performance_monitor>();
219
220 // Bidirectional injection
221 logger->set_monitor(monitor);
222 // Note: In real logger_system, logger would also be injected into adapter
223
224 std::cout << "\n✓ Bidirectional dependency injection complete" << std::endl;
225 std::cout << " Logger -> uses Monitor for metrics" << std::endl;
226 std::cout << " Monitor <- logs status via Logger\n" << std::endl;
227
228 // Simulate application workload
229 std::cout << "\nSimulating application workload..." << std::endl;
230 for (int i = 0; i < 10; ++i) {
231 // Log activity
232 logger->log(log_level::info, "Processing request " + std::to_string(i));
233
234 // Record performance metrics
235 monitor->record_metric("requests_processed", i + 1);
236 monitor->record_metric("response_time_ms", 50.0 + (i * 5));
237
238 std::this_thread::sleep_for(std::chrono::milliseconds(10));
239 }
240
241 // Check both systems' health
242 std::cout << "\n=== System Health Check ===" << std::endl;
243
244 auto logger_health = logger->health_check();
245 if (std::holds_alternative<health_check_result>(logger_health)) {
246 auto& health = std::get<health_check_result>(logger_health);
247 std::cout << "Logger Status: " << to_string(health.status)
248 << " - " << health.message << std::endl;
249 std::cout << " Messages logged: " << logger->get_message_count() << std::endl;
250 }
251
252 auto monitor_health = monitor->check_health();
253 if (std::holds_alternative<health_check_result>(monitor_health)) {
254 auto& health = std::get<health_check_result>(monitor_health);
255 std::cout << "Monitor Status: " << to_string(health.status)
256 << " - " << health.message << std::endl;
257 }
258
259 // Get comprehensive metrics
260 std::cout << "\n=== Collected Metrics ===" << std::endl;
261
262 auto logger_metrics = logger->get_monitoring_data();
263 if (std::holds_alternative<metrics_snapshot>(logger_metrics)) {
264 auto& snapshot = std::get<metrics_snapshot>(logger_metrics);
265 std::cout << "Logger Metrics:" << std::endl;
266 for (const auto& metric : snapshot.metrics) {
267 std::cout << " " << metric.name << ": " << metric.value << std::endl;
268 }
269 }
270
271 auto monitor_metrics = monitor->get_metrics();
272 if (std::holds_alternative<metrics_snapshot>(monitor_metrics)) {
273 auto& snapshot = std::get<metrics_snapshot>(monitor_metrics);
274 std::cout << "\nMonitor Metrics:" << std::endl;
275 for (const auto& metric : snapshot.metrics) {
276 std::cout << " " << metric.name << ": " << metric.value << std::endl;
277 }
278 }
279
280 std::cout << "\n✓ Both systems fully operational and integrated!" << std::endl;
281}
auto to_string(plugin_load_error error) -> std::string
Convert plugin_load_error to string.
Basic metric structure for interface compatibility.
std::variant< double, int64_t, std::string > value

References kcenon::monitoring::metric::name, kcenon::monitoring::to_string(), and kcenon::monitoring::metric::value.

Referenced by main().

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

◆ demo_logger_with_monitor()

void demo_logger_with_monitor ( )

Scenario 2: Logger with Monitor Injection.

Examples
bidirectional_di_example.cpp.

Definition at line 156 of file bidirectional_di_example.cpp.

156 {
157 std::cout << "\n=== Scenario 2: Logger with Monitor ===" << std::endl;
158 std::cout << "Logger receives monitor via DI for metrics collection.\n" << std::endl;
159
160 auto monitor = std::make_shared<performance_monitor>();
161 auto logger = std::make_shared<console_logger>();
162
163 // Inject monitor into logger
164 logger->set_monitor(monitor);
165
166 // Log some messages
167 logger->log(log_level::info, "First message with monitoring");
168 logger->log(log_level::warning, "Second message with monitoring");
169 logger->log(log_level::error, "Third message with monitoring");
170
171 // Check monitor collected metrics
172 auto metrics_result = monitor->get_metrics();
173 if (std::holds_alternative<metrics_snapshot>(metrics_result)) {
174 auto& snapshot = std::get<metrics_snapshot>(metrics_result);
175 std::cout << "\n✓ Monitor collected " << snapshot.metrics.size()
176 << " metrics from logger" << std::endl;
177
178 for (const auto& metric : snapshot.metrics) {
179 std::cout << " - " << metric.name << ": " << metric.value << std::endl;
180 }
181 }
182}

References kcenon::monitoring::metric::name, and kcenon::monitoring::metric::value.

Referenced by main().

Here is the caller graph for this function:

◆ demo_monitor_with_logger()

void demo_monitor_with_logger ( )

Scenario 3: Monitor with Logger Injection (via adapter)

Examples
bidirectional_di_example.cpp.

Definition at line 187 of file bidirectional_di_example.cpp.

187 {
188 std::cout << "\n\n=== Scenario 3: Monitor with Logger ===" << std::endl;
189 std::cout << "Monitor can report to logger (via adapter pattern).\n" << std::endl;
190
191 auto logger = std::make_shared<console_logger>();
192 auto monitor = std::make_shared<performance_monitor>();
193
194 // Monitor records metrics
195 monitor->record_metric("cpu_usage", 45.5);
196 monitor->record_metric("memory_usage", 512.0);
197
198 // Check health and log result
199 auto health_result = monitor->check_health();
200 if (std::holds_alternative<health_check_result>(health_result)) {
201 auto& health = std::get<health_check_result>(health_result);
202 std::string health_msg = "Monitor health: " + to_string(health.status);
203 logger->log(log_level::info, health_msg);
204 }
205
206 std::cout << "\n✓ Monitor can report status to logger" << std::endl;
207}

References kcenon::monitoring::to_string().

Referenced by main().

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

◆ demo_runtime_flexibility()

void demo_runtime_flexibility ( )

Scenario 5: Runtime Flexibility.

Examples
bidirectional_di_example.cpp.

Definition at line 286 of file bidirectional_di_example.cpp.

286 {
287 std::cout << "\n\n=== Scenario 5: Runtime Flexibility ===" << std::endl;
288 std::cout << "Dependencies can be changed at runtime.\n" << std::endl;
289
290 auto logger = std::make_shared<console_logger>();
291 auto monitor1 = std::make_shared<performance_monitor>();
292 auto monitor2 = std::make_shared<performance_monitor>();
293
294 // Start with first monitor
295 logger->set_monitor(monitor1);
296 logger->log(log_level::info, "Using monitor 1");
297
298 // Switch to second monitor
299 logger->set_monitor(monitor2);
300 logger->log(log_level::info, "Switched to monitor 2");
301
302 // Remove monitor completely
303 logger->set_monitor(nullptr);
304 logger->log(log_level::info, "Operating without monitor");
305
306 std::cout << "\n✓ Runtime dependency changes work seamlessly" << std::endl;
307}

Referenced by main().

Here is the caller graph for this function:

◆ demo_standalone_systems()

void demo_standalone_systems ( )

Scenario 1: Standalone Systems.

Examples
bidirectional_di_example.cpp.

Definition at line 136 of file bidirectional_di_example.cpp.

136 {
137 std::cout << "\n=== Scenario 1: Standalone Systems ===" << std::endl;
138 std::cout << "Both systems work independently without each other.\n" << std::endl;
139
140 // Logger works alone
141 auto logger = std::make_shared<console_logger>();
142 logger->log(log_level::info, "Logger operating standalone");
143 std::cout << "✓ Logger works without monitor\n" << std::endl;
144
145 // Monitor works alone
146 auto monitor = std::make_shared<performance_monitor>();
147 auto result = monitor->record_metric("standalone_metric", 42.0);
148 if (std::holds_alternative<std::monostate>(result)) {
149 std::cout << "✓ Monitor works without logger\n" << std::endl;
150 }
151}

Referenced by main().

Here is the caller graph for this function:

◆ main()

int main ( )

Definition at line 309 of file bidirectional_di_example.cpp.

309 {
310 std::cout << "╔═══════════════════════════════════════════════════════════╗" << std::endl;
311 std::cout << "║ Phase 4: Bidirectional DI Example ║" << std::endl;
312 std::cout << "║ Demonstrating Circular Dependency Resolution ║" << std::endl;
313 std::cout << "╚═══════════════════════════════════════════════════════════╝" << std::endl;
314
315 try {
321
322 std::cout << "\n\n╔═══════════════════════════════════════════════════════════╗" << std::endl;
323 std::cout << "║ ✓ ALL SCENARIOS PASSED ║" << std::endl;
324 std::cout << "║ ║" << std::endl;
325 std::cout << "║ Key Achievement: ║" << std::endl;
326 std::cout << "║ • NO compile-time circular dependency ║" << std::endl;
327 std::cout << "║ • Runtime bidirectional integration works ║" << std::endl;
328 std::cout << "║ • Both systems can operate standalone ║" << std::endl;
329 std::cout << "║ • Pure interface-based design ║" << std::endl;
330 std::cout << "╚═══════════════════════════════════════════════════════════╝" << std::endl;
331
332 return 0;
333 } catch (const std::exception& e) {
334 std::cerr << "Error: " << e.what() << std::endl;
335 return 1;
336 }
337}
void demo_standalone_systems()
Scenario 1: Standalone Systems.
void demo_runtime_flexibility()
Scenario 5: Runtime Flexibility.
void demo_bidirectional_integration()
Scenario 4: Bidirectional DI (THE KEY DEMO!)
void demo_logger_with_monitor()
Scenario 2: Logger with Monitor Injection.
void demo_monitor_with_logger()
Scenario 3: Monitor with Logger Injection (via adapter)

References demo_bidirectional_integration(), demo_logger_with_monitor(), demo_monitor_with_logger(), demo_runtime_flexibility(), and demo_standalone_systems().

Here is the call graph for this function: