21#include <kcenon/common/interfaces/logger_interface.h>
22#include <kcenon/common/interfaces/monitoring_interface.h>
29using namespace common::interfaces;
44 common::VoidResult
log(log_level level,
const std::string& message)
override {
46 return std::monostate{};
51 auto now = std::chrono::system_clock::now();
52 auto time_t = std::chrono::system_clock::to_time_t(now);
55 localtime_s(&tm, &time_t);
57 localtime_r(&time_t, &tm);
60 std::cout <<
"[" << std::put_time(&tm,
"%Y-%m-%d %H:%M:%S") <<
"] "
62 << message << std::endl;
69 return std::monostate{};
72 common::VoidResult
log(log_level level,
const std::string& message,
73 const std::string& file,
int line,
74 const std::string& function)
override {
75 std::string detailed_message = message +
" [" + file +
":" +
76 std::to_string(line) +
" in " + function +
"]";
77 return log(level, detailed_message);
80 common::VoidResult
log(
const log_entry& entry)
override {
81 return log(entry.level, entry.message, entry.file, entry.line, entry.function);
88 common::VoidResult
set_level(log_level level)
override {
90 return std::monostate{};
97 common::VoidResult
flush()
override {
99 return std::monostate{};
113 result.
status = health_status::healthy;
114 result.
message =
"Console logger operational";
120 return "console_logger";
137 std::cout <<
"\n=== Scenario 1: Standalone Systems ===" << std::endl;
138 std::cout <<
"Both systems work independently without each other.\n" << std::endl;
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;
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;
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;
160 auto monitor = std::make_shared<performance_monitor>();
161 auto logger = std::make_shared<console_logger>();
164 logger->set_monitor(monitor);
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");
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;
178 for (
const auto&
metric : snapshot.metrics) {
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;
191 auto logger = std::make_shared<console_logger>();
192 auto monitor = std::make_shared<performance_monitor>();
195 monitor->record_metric(
"cpu_usage", 45.5);
196 monitor->record_metric(
"memory_usage", 512.0);
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);
206 std::cout <<
"\nā Monitor can report status to logger" << std::endl;
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;
217 auto logger = std::make_shared<console_logger>();
218 auto monitor = std::make_shared<performance_monitor>();
221 logger->set_monitor(monitor);
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;
229 std::cout <<
"\nSimulating application workload..." << std::endl;
230 for (
int i = 0; i < 10; ++i) {
232 logger->log(log_level::info,
"Processing request " + std::to_string(i));
235 monitor->record_metric(
"requests_processed", i + 1);
236 monitor->record_metric(
"response_time_ms", 50.0 + (i * 5));
238 std::this_thread::sleep_for(std::chrono::milliseconds(10));
242 std::cout <<
"\n=== System Health Check ===" << std::endl;
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;
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;
260 std::cout <<
"\n=== Collected Metrics ===" << std::endl;
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) {
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) {
280 std::cout <<
"\nā Both systems fully operational and integrated!" << std::endl;
287 std::cout <<
"\n\n=== Scenario 5: Runtime Flexibility ===" << std::endl;
288 std::cout <<
"Dependencies can be changed at runtime.\n" << std::endl;
290 auto logger = std::make_shared<console_logger>();
291 auto monitor1 = std::make_shared<performance_monitor>();
292 auto monitor2 = std::make_shared<performance_monitor>();
295 logger->set_monitor(monitor1);
296 logger->log(log_level::info,
"Using monitor 1");
299 logger->set_monitor(monitor2);
300 logger->log(log_level::info,
"Switched to monitor 2");
303 logger->set_monitor(
nullptr);
304 logger->log(log_level::info,
"Operating without monitor");
306 std::cout <<
"\nā Runtime dependency changes work seamlessly" << std::endl;
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;
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;
333 }
catch (
const std::exception& e) {
334 std::cerr <<
"Error: " << e.what() << std::endl;
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)
Simple console logger implementing ILogger interface.
common::VoidResult log(log_level level, const std::string &message, const std::string &file, int line, const std::string &function) override
common::VoidResult log(const log_entry &entry) override
common::Result< health_check_result > health_check() override
bool is_enabled(log_level level) const override
std::atomic< int > message_count_
common::VoidResult log(log_level level, const std::string &message) override
common::Result< metrics_snapshot > get_monitoring_data() override
std::string get_component_name() const override
common::VoidResult set_level(log_level level) override
common::VoidResult flush() override
std::shared_ptr< IMonitor > monitor_
log_level get_level() const override
void set_monitor(std::shared_ptr< IMonitor > monitor)
int get_message_count() const
auto to_string(plugin_load_error error) -> std::string
Convert plugin_load_error to string.
Result of a health check operation.
std::unordered_map< std::string, std::string > metadata
Basic metric structure for interface compatibility.
std::variant< double, int64_t, std::string > value
Complete snapshot of metrics at a point in time.
void add_metric(const std::string &name, double value)
Add a metric to the snapshot.