diff --git a/lib/perfdata/opentsdbwriter.cpp b/lib/perfdata/opentsdbwriter.cpp index 38405a2a3..527acf4c9 100644 --- a/lib/perfdata/opentsdbwriter.cpp +++ b/lib/perfdata/opentsdbwriter.cpp @@ -151,15 +151,54 @@ void OpenTsdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C Service::Ptr service = dynamic_pointer_cast(checkable); Host::Ptr host; + Dictionary::Ptr config_tmpl_clean; - if (service) + if (service) { host = service->GetHost(); - else + config_tmpl_clean = GetServiceTemplate(); + } + else { host = static_pointer_cast(checkable); + config_tmpl_clean = GetHostTemplate(); + } + + // Clone the config template and perform an in-place macro expansion of measurement and tag values + Dictionary::Ptr config_tmpl = static_pointer_cast(config_tmpl_clean->Clone()); + Dictionary::Ptr config_tmpl_tags = config_tmpl->Get("tags"); + + // Configure config template macro resolver + MacroProcessor::ResolverList resolvers; + if (service) + resolvers.emplace_back("service", service); + resolvers.emplace_back("host", host); + resolvers.emplace_back("icinga", IcingaApplication::GetInstance()); String metric; std::map tags; + // Resolve macros in configuration template + if (config_tmpl_tags) { + + ObjectLock olock(config_tmpl_tags); + + for (const Dictionary::Pair& pair : config_tmpl_tags) { + + String missing_macro; + Value value = MacroProcessor::ResolveMacros(pair.second, resolvers, cr, &missing_macro); + + if (!missing_macro.IsEmpty()) { + Log(LogDebug, "OpenTsdbWriter") + << "Macro in config template does not exist:'" << missing_macro << "'."; + + continue; + } + + String tagname = pair.first; + tags[tagname] = EscapeTag(value); + + } + } + String escaped_hostName = EscapeTag(host->GetName()); tags["host"] = escaped_hostName; @@ -338,3 +377,31 @@ String OpenTsdbWriter::EscapeMetric(const String& str) return result; } + +void OpenTsdbWriter::ValidateHostTemplate(const Lazy& lvalue, const ValidationUtils& utils) +{ + ObjectImpl::ValidateHostTemplate(lvalue, utils); + + Dictionary::Ptr tags = lvalue()->Get("tags"); + if (tags) { + ObjectLock olock(tags); + for (const Dictionary::Pair& pair : tags) { + if (!MacroProcessor::ValidateMacroString(pair.second)) + BOOST_THROW_EXCEPTION(ValidationError(this, { "host_template", "tags", pair.first }, "Closing $ not found in macro format string '" + pair.second)); + } + } +} + +void OpenTsdbWriter::ValidateServiceTemplate(const Lazy& lvalue, const ValidationUtils& utils) +{ + ObjectImpl::ValidateServiceTemplate(lvalue, utils); + + Dictionary::Ptr tags = lvalue()->Get("tags"); + if (tags) { + ObjectLock olock(tags); + for (const Dictionary::Pair& pair : tags) { + if (!MacroProcessor::ValidateMacroString(pair.second)) + BOOST_THROW_EXCEPTION(ValidationError(this, { "service_template", "tags", pair.first }, "Closing $ not found in macro format string '" + pair.second)); + } + } +} \ No newline at end of file diff --git a/lib/perfdata/opentsdbwriter.hpp b/lib/perfdata/opentsdbwriter.hpp index 5aff981cd..4dd98811e 100644 --- a/lib/perfdata/opentsdbwriter.hpp +++ b/lib/perfdata/opentsdbwriter.hpp @@ -26,6 +26,9 @@ public: static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); + void ValidateHostTemplate(const Lazy& lvalue, const ValidationUtils& utils) override; + void ValidateServiceTemplate(const Lazy& lvalue, const ValidationUtils& utils) override; + protected: void OnConfigLoaded() override; void Resume() override; diff --git a/lib/perfdata/opentsdbwriter.ti b/lib/perfdata/opentsdbwriter.ti index de19a1eac..7a0219f01 100644 --- a/lib/perfdata/opentsdbwriter.ti +++ b/lib/perfdata/opentsdbwriter.ti @@ -20,6 +20,13 @@ class OpenTsdbWriter : ConfigObject [config] bool enable_ha { default {{{ return false; }}} }; + [config] Dictionary::Ptr host_template { + default {{{ return new Dictionary(); }}} + + }; + [config] Dictionary::Ptr service_template { + default {{{ return new Dictionary(); }}} + }; [no_user_modify] bool connected; [no_user_modify] bool should_connect { @@ -27,4 +34,17 @@ class OpenTsdbWriter : ConfigObject }; }; +validator OpenTsdbWriter { + Dictionary host_template { + Dictionary "tags" { + String "*"; + }; + }; + Dictionary service_template { + Dictionary "tags" { + String "*"; + }; + }; +}; + }