#include "Observ.hpp" #include #include "Caps.hpp" namespace molo::example::fw { void EventBus::on(const std::string& type, std::function listener) { std::lock_guard lock(mu_); if (!kEnabled) return; listeners_[type].push_back(std::move(listener)); } void EventBus::emit(const Event& event) { std::lock_guard lock(mu_); if (!kEnabled) return; delivered_.push_back(event); auto it = listeners_.find(event.type); if (it == listeners_.end()) return; for (auto& l : it->second) l(event); } std::vector EventBus::delivered() const { std::lock_guard lock(mu_); return delivered_; } void Metrics::inc(const std::string& name, double value) { std::lock_guard lock(mu_); if (!kEnabled) return; if (!values_.count(name) && values_.size() >= caps::kMaxMetrics) return; values_[name] += value; } void Metrics::gauge(const std::string& name, double value) { std::lock_guard lock(mu_); if (!kEnabled) return; if (!values_.count(name) && values_.size() >= caps::kMaxMetrics) return; values_[name] = value; } double Metrics::get(const std::string& name) const { std::lock_guard lock(mu_); auto it = values_.find(name); return it == values_.end() ? 0.0 : it->second; } std::string Metrics::render_prometheus() const { std::lock_guard lock(mu_); std::string out; for (const auto& [k, v] : values_) { char buf[64]; std::snprintf(buf, sizeof(buf), "%g", v); out += k + " " + buf + "\n"; } return out; } Span Telemetry::start_span(const std::string& name, const std::string& correlation_id) { std::lock_guard lock(mu_); Span s; if (!kEnabled) return s; s.trace_id = "trace-" + std::to_string(next_id_); s.span_id = "span-" + std::to_string(next_id_); ++next_id_; s.name = name; s.correlation_id = correlation_id; return s; } void Telemetry::finish_span(const Span& span) { std::lock_guard lock(mu_); if (!kEnabled) return; if (spans_.size() >= caps::kMaxSpans) return; spans_.push_back(span); } std::vector Telemetry::spans() const { std::lock_guard lock(mu_); return spans_; } } // namespace molo::example::fw