15#include <kcenon/common/interfaces/logger_interface.h>
16#include <kcenon/common/interfaces/monitoring_interface.h>
22#include <unordered_map>
26namespace ci = kcenon::common::interfaces;
34class logger_interface_adapter :
public ci::ILogger {
36 explicit logger_interface_adapter(std::shared_ptr<logger>
logger)
37 : logger_(std::move(
logger)) {}
41 return make_adapter_error(
"Logger not initialized");
43 return logger_->log(level, message);
47 std::string_view message,
48 const kcenon::common::source_location& loc)
override {
50 return make_adapter_error(
"Logger not initialized");
52 return logger_->log(level, message, loc);
57 return make_adapter_error(
"Logger not initialized");
59 return logger_->log(entry);
62 bool is_enabled(ci::log_level level)
const override {
63 return logger_ && logger_->is_enabled(level);
68 return make_adapter_error(
"Logger not initialized");
70 return logger_->set_level(level);
73 ci::log_level get_level()
const override {
75 return ci::log_level::off;
77 return logger_->get_level();
82 return make_adapter_error(
"Logger not initialized");
89 std::shared_ptr<logger> logger_;
108 const std::string& name,
109 double value)
override
115 std::cout <<
"[Monitor] Recorded metric: " << name
116 <<
" = " << value << std::endl;
122 const std::string& name,
124 const std::unordered_map<std::string, std::string>& tags)
override
129 std::string tagged_name = name;
130 for (
const auto& [key, val] : tags) {
131 tagged_name +=
"." + key +
":" + val;
137 std::cout <<
"[Monitor] Recorded tagged metric: " << tagged_name
138 <<
" = " << value << std::endl;
146 ci::metrics_snapshot snapshot;
147 snapshot.source_id =
"example_monitor";
148 snapshot.capture_time = std::chrono::system_clock::now();
150 for (
const auto& [name, value] :
metrics_) {
151 snapshot.add_metric(name, value);
158 ci::health_check_result
result;
159 result.timestamp = std::chrono::system_clock::now();
160 result.status = ci::health_status::healthy;
161 result.message =
"Example monitor operational";
172 std::cout <<
"[Monitor] Metrics reset" << std::endl;
186 std::cout <<
"\n=== Example 1: Basic Dependency Injection ===" << std::endl;
189 auto monitor = std::make_shared<example_monitor>();
198 if (!logger_result) {
199 std::cerr <<
"Failed to create logger: "
200 << logger_result.error_message() << std::endl;
204 auto logger_instance = std::shared_ptr<logger>(std::move(logger_result.value()));
207 logger_instance->log(ci::log_level::info,
"Application started");
208 logger_instance->log(ci::log_level::debug,
"Debug message");
209 logger_instance->log(ci::log_level::warning,
"Warning message");
212 std::cout <<
"\nMonitor collected " << monitor->get_metric_count()
213 <<
" metrics" << std::endl;
222 std::cout <<
"Logger health: [health_check() not yet implemented]" << std::endl;
229 std::cout <<
"\n=== Example 2: Optional Monitor (No Monitor) ===" << std::endl;
237 if (!logger_result) {
238 std::cerr <<
"Failed to create logger" << std::endl;
242 auto logger_instance = std::shared_ptr<logger>(std::move(logger_result.value()));
245 logger_instance->log(ci::log_level::info,
"Operating without monitor");
246 logger_instance->log(ci::log_level::warning,
"Warning without monitoring");
248 std::cout <<
"Logger operates successfully without monitor (DI optional)" << std::endl;
255 std::cout <<
"\n=== Example 3: Runtime Monitor Injection ===" << std::endl;
262 if (!logger_result) {
263 std::cerr <<
"Failed to create logger" << std::endl;
267 auto logger_instance = std::shared_ptr<logger>(std::move(logger_result.value()));
269 std::cout <<
"Phase 1: Operating without monitor" << std::endl;
270 logger_instance->log(ci::log_level::info,
"Message 1 - no monitoring");
274 auto monitor = std::make_unique<example_monitor>();
275 auto* monitor_ref = monitor.get();
278 std::cout <<
"\nPhase 2: Monitor injected at runtime [set_monitor() not yet implemented]" << std::endl;
279 logger_instance->log(ci::log_level::info,
"Message 2 - with monitoring");
280 logger_instance->log(ci::log_level::info,
"Message 3 - with monitoring");
282 std::cout <<
"\nMonitor recorded " << monitor_ref->get_metric_count()
283 <<
" metrics (only from Phase 2)" << std::endl;
290 std::cout <<
"\n=== Example 4: Monitor Swapping ===" << std::endl;
296 if (!logger_result)
return;
297 auto logger_instance = std::shared_ptr<logger>(std::move(logger_result.value()));
300 auto monitor1 = std::make_unique<example_monitor>();
301 auto* monitor1_ref = monitor1.get();
304 std::cout <<
"Using Monitor 1 [set_monitor() not yet implemented]" << std::endl;
305 logger_instance->log(ci::log_level::info,
"Message to Monitor 1");
306 logger_instance->log(ci::log_level::info,
"Another message to Monitor 1");
308 size_t monitor1_metrics = monitor1_ref->get_metric_count();
311 auto monitor2 = std::make_unique<example_monitor>();
312 auto* monitor2_ref = monitor2.get();
315 std::cout <<
"\nSwapped to Monitor 2 [set_monitor() not yet implemented]" << std::endl;
316 logger_instance->log(ci::log_level::info,
"Message to Monitor 2");
318 size_t monitor2_metrics = monitor2_ref->get_metric_count();
320 std::cout <<
"\nMonitor 1 metrics before swap: " << monitor1_metrics << std::endl;
321 std::cout <<
"Monitor 2 metrics after swap: " << monitor2_metrics << std::endl;
332 logger->log(ci::log_level::info, std::string(
"Used via interface - loose coupling!"));
335 if (
auto monitorable = std::dynamic_pointer_cast<ci::IMonitorable>(
logger)) {
336 auto data = monitorable->get_monitoring_data();
338 std::cout <<
"Logger provides monitoring data from "
345 std::cout <<
"\n=== Example 5: Interface-Based Usage ===" << std::endl;
347 auto monitor = std::make_shared<example_monitor>();
353 if (!logger_result)
return;
356 auto logger_instance = std::shared_ptr<logger>(std::move(logger_result.value()));
357 auto logger_adapter = std::make_shared<logger_interface_adapter>(logger_instance);
362 std::cout <<
"Successfully used logger through interface abstraction" << std::endl;
366 std::cout <<
"==================================================" << std::endl;
367 std::cout <<
"Logger System - Dependency Injection Pattern Demo" << std::endl;
368 std::cout <<
"Phase 4: DI Pattern Implementation Examples" << std::endl;
369 std::cout <<
"==================================================" << std::endl;
378 std::cout <<
"\n==================================================" << std::endl;
379 std::cout <<
"All DI pattern examples completed successfully!" << std::endl;
380 std::cout <<
"==================================================" << std::endl;
382 }
catch (
const std::exception& e) {
383 std::cerr <<
"Error: " << e.what() << std::endl;
Example monitor implementation demonstrating IMonitor interface.
std::mutex metrics_mutex_
kcenon::common::Result< ci::health_check_result > check_health() override
kcenon::common::VoidResult reset() override
kcenon::common::VoidResult record_metric(const std::string &name, double value, const std::unordered_map< std::string, std::string > &tags) override
std::unordered_map< std::string, double > metrics_
kcenon::common::Result< ci::metrics_snapshot > get_metrics() override
size_t get_metric_count() const
kcenon::common::VoidResult record_metric(const std::string &name, double value) override
Builder pattern for logger construction with validation.
logger_builder & with_monitoring(std::shared_ptr< common::interfaces::IMonitor > monitor)
Set monitoring interface (Phase 2.2.4)
logger_builder & with_min_level(log_level level)
logger_builder & with_async(bool async=true)
result< std::unique_ptr< logger > > build()
void example_2_optional_monitor()
Example demonstrating monitor-less operation.
void example_4_monitor_swapping()
Example demonstrating monitor swapping.
void example_5_interface_based_usage()
void example_1_basic_di_pattern()
Example demonstrating DI pattern with logger and monitor.
void example_3_runtime_monitor_injection()
Example demonstrating runtime monitor injection.
void use_logger_via_interface(std::shared_ptr< ci::ILogger > logger)
Example demonstrating ILogger interface usage.
Builder pattern implementation for flexible logger configuration kcenon.
bool is_ok(const Result< T > &result)
T & get_value(Result< T > &result)