diff --git a/doc/03-monitoring-basics.md b/doc/03-monitoring-basics.md
index 672c026ff..79ef8cc5d 100644
--- a/doc/03-monitoring-basics.md
+++ b/doc/03-monitoring-basics.md
@@ -664,6 +664,13 @@ The following macros provide global statistics:
icinga.num\_hosts\_in\_downtime | Current number of hosts in downtime.
icinga.num\_hosts\_acknowledged | Current number of acknowledged host problems.
+### Environment Variable Runtime Macros
+
+All environment variables of the Icinga process are available as runtime macros
+named `env.`. E.g. `$env.ProgramFiles$` for ProgramFiles which is
+especially useful on Windows. In contrast to the other runtime macros env vars
+require the `env.` prefix.
+
## Apply Rules
diff --git a/lib/db_ido/idochecktask.cpp b/lib/db_ido/idochecktask.cpp
index 6a7f0d363..3b5856a65 100644
--- a/lib/db_ido/idochecktask.cpp
+++ b/lib/db_ido/idochecktask.cpp
@@ -60,7 +60,6 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String idoType = MacroProcessor::ResolveMacros("$ido_type$", resolvers, checkable->GetLastCheckResult(),
nullptr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros);
diff --git a/lib/icinga/CMakeLists.txt b/lib/icinga/CMakeLists.txt
index 7079d84e5..62077bce7 100644
--- a/lib/icinga/CMakeLists.txt
+++ b/lib/icinga/CMakeLists.txt
@@ -41,6 +41,7 @@ set(icinga_SOURCES
customvarobject.cpp customvarobject.hpp customvarobject-ti.hpp
dependency.cpp dependency.hpp dependency-ti.hpp dependency-apply.cpp
downtime.cpp downtime.hpp downtime-ti.hpp
+ envresolver.cpp envresolver.hpp
eventcommand.cpp eventcommand.hpp eventcommand-ti.hpp
externalcommandprocessor.cpp externalcommandprocessor.hpp
host.cpp host.hpp host-ti.hpp
diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp
index ff3c6506d..1e3fe851f 100644
--- a/lib/icinga/apiactions.cpp
+++ b/lib/icinga/apiactions.cpp
@@ -667,7 +667,6 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, cons
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String resolved_endpoint = MacroProcessor::ResolveMacros(
endpoint, resolvers, checkable->GetLastCheckResult(),
diff --git a/lib/icinga/envresolver.cpp b/lib/icinga/envresolver.cpp
new file mode 100644
index 000000000..633255c86
--- /dev/null
+++ b/lib/icinga/envresolver.cpp
@@ -0,0 +1,20 @@
+/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
+
+#include "base/string.hpp"
+#include "base/value.hpp"
+#include "icinga/envresolver.hpp"
+#include "icinga/checkresult.hpp"
+#include
+
+using namespace icinga;
+
+bool EnvResolver::ResolveMacro(const String& macro, const CheckResult::Ptr&, Value *result) const
+{
+ auto value (getenv(macro.CStr()));
+
+ if (value) {
+ *result = value;
+ }
+
+ return value;
+}
diff --git a/lib/icinga/envresolver.hpp b/lib/icinga/envresolver.hpp
new file mode 100644
index 000000000..b3f0076fa
--- /dev/null
+++ b/lib/icinga/envresolver.hpp
@@ -0,0 +1,30 @@
+/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
+
+#ifndef ENVRESOLVER_H
+#define ENVRESOLVER_H
+
+#include "base/object.hpp"
+#include "base/string.hpp"
+#include "base/value.hpp"
+#include "icinga/macroresolver.hpp"
+#include "icinga/checkresult.hpp"
+
+namespace icinga
+{
+
+/**
+ * Resolves env var names.
+ *
+ * @ingroup icinga
+ */
+class EnvResolver final : public Object, public MacroResolver
+{
+public:
+ DECLARE_PTR_TYPEDEFS(EnvResolver);
+
+ bool ResolveMacro(const String& macro, const CheckResult::Ptr&, Value *result) const override;
+};
+
+}
+
+#endif /* ENVRESOLVER_H */
diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp
index 6fd30581c..97f0affe0 100644
--- a/lib/icinga/macroprocessor.cpp
+++ b/lib/icinga/macroprocessor.cpp
@@ -3,6 +3,8 @@
#include "icinga/macroprocessor.hpp"
#include "icinga/macroresolver.hpp"
#include "icinga/customvarobject.hpp"
+#include "icinga/envresolver.hpp"
+#include "icinga/icingaapplication.hpp"
#include "base/array.hpp"
#include "base/objectlock.hpp"
#include "base/logger.hpp"
@@ -73,6 +75,16 @@ Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolv
return result;
}
+static const EnvResolver::Ptr l_EnvResolver = new EnvResolver();
+
+static MacroProcessor::ResolverList GetDefaultResolvers()
+{
+ return {
+ { "icinga", IcingaApplication::GetInstance() },
+ { "env", l_EnvResolver, false }
+ };
+}
+
bool MacroProcessor::ResolveMacro(const String& macro, const ResolverList& resolvers,
const CheckResult::Ptr& cr, Value *result, bool *recursive_macro)
{
@@ -88,77 +100,84 @@ bool MacroProcessor::ResolveMacro(const String& macro, const ResolverList& resol
tokens.erase(tokens.begin());
}
- for (const ResolverSpec& resolver : resolvers) {
- if (!objName.IsEmpty() && objName != resolver.first)
- continue;
+ const auto defaultResolvers (GetDefaultResolvers());
- if (objName.IsEmpty()) {
- CustomVarObject::Ptr dobj = dynamic_pointer_cast(resolver.second);
+ for (auto resolverList : {&resolvers, &defaultResolvers}) {
+ for (auto& resolver : *resolverList) {
+ if (!objName.IsEmpty() && objName != resolver.Name)
+ continue;
- if (dobj) {
- Dictionary::Ptr vars = dobj->GetVars();
-
- if (vars && vars->Contains(macro)) {
- *result = vars->Get(macro);
- *recursive_macro = true;
- return true;
- }
- }
- }
-
- auto *mresolver = dynamic_cast(resolver.second.get());
-
- if (mresolver && mresolver->ResolveMacro(boost::algorithm::join(tokens, "."), cr, result))
- return true;
-
- Value ref = resolver.second;
- bool valid = true;
-
- for (const String& token : tokens) {
- if (ref.IsObjectType()) {
- Dictionary::Ptr dict = ref;
- if (dict->Contains(token)) {
- ref = dict->Get(token);
+ if (objName.IsEmpty()) {
+ if (!resolver.ResolveShortMacros)
continue;
- } else {
- valid = false;
- break;
+
+ CustomVarObject::Ptr dobj = dynamic_pointer_cast(resolver.Obj);
+
+ if (dobj) {
+ Dictionary::Ptr vars = dobj->GetVars();
+
+ if (vars && vars->Contains(macro)) {
+ *result = vars->Get(macro);
+ *recursive_macro = true;
+ return true;
+ }
}
- } else if (ref.IsObject()) {
- Object::Ptr object = ref;
-
- Type::Ptr type = object->GetReflectionType();
-
- if (!type) {
- valid = false;
- break;
- }
-
- int field = type->GetFieldId(token);
-
- if (field == -1) {
- valid = false;
- break;
- }
-
- ref = object->GetField(field);
-
- Field fieldInfo = type->GetFieldInfo(field);
-
- if (strcmp(fieldInfo.TypeName, "Timestamp") == 0)
- ref = static_cast(ref);
}
- }
- if (valid) {
- if (tokens[0] == "vars" ||
- tokens[0] == "action_url" ||
- tokens[0] == "notes_url" ||
- tokens[0] == "notes")
- *recursive_macro = true;
+ auto *mresolver = dynamic_cast(resolver.Obj.get());
- *result = ref;
- return true;
+ if (mresolver && mresolver->ResolveMacro(boost::algorithm::join(tokens, "."), cr, result))
+ return true;
+
+ Value ref = resolver.Obj;
+ bool valid = true;
+
+ for (const String& token : tokens) {
+ if (ref.IsObjectType()) {
+ Dictionary::Ptr dict = ref;
+ if (dict->Contains(token)) {
+ ref = dict->Get(token);
+ continue;
+ } else {
+ valid = false;
+ break;
+ }
+ } else if (ref.IsObject()) {
+ Object::Ptr object = ref;
+
+ Type::Ptr type = object->GetReflectionType();
+
+ if (!type) {
+ valid = false;
+ break;
+ }
+
+ int field = type->GetFieldId(token);
+
+ if (field == -1) {
+ valid = false;
+ break;
+ }
+
+ ref = object->GetField(field);
+
+ Field fieldInfo = type->GetFieldInfo(field);
+
+ if (strcmp(fieldInfo.TypeName, "Timestamp") == 0)
+ ref = static_cast(ref);
+ }
+ }
+
+ if (valid) {
+ if (tokens[0] == "vars" ||
+ tokens[0] == "action_url" ||
+ tokens[0] == "notes_url" ||
+ tokens[0] == "notes")
+ *recursive_macro = true;
+
+ *result = ref;
+ return true;
+ }
}
}
@@ -170,9 +189,12 @@ Value MacroProcessor::EvaluateFunction(const Function::Ptr& func, const Resolver
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros, int recursionLevel)
{
Dictionary::Ptr resolvers_this = new Dictionary();
+ const auto defaultResolvers (GetDefaultResolvers());
- for (const ResolverSpec& resolver : resolvers) {
- resolvers_this->Set(resolver.first, resolver.second);
+ for (auto resolverList : {&resolvers, &defaultResolvers}) {
+ for (auto& resolver: *resolverList) {
+ resolvers_this->Set(resolver.Name, resolver.Obj);
+ }
}
auto internalResolveMacrosShim = [resolvers, cr, resolvedMacros, useResolvedMacros, recursionLevel](const std::vector& args) {
diff --git a/lib/icinga/macroprocessor.hpp b/lib/icinga/macroprocessor.hpp
index d6c16107a..7e7482153 100644
--- a/lib/icinga/macroprocessor.hpp
+++ b/lib/icinga/macroprocessor.hpp
@@ -7,6 +7,7 @@
#include "icinga/checkable.hpp"
#include "base/value.hpp"
#include
+#include
namespace icinga
{
@@ -19,8 +20,21 @@ namespace icinga
class MacroProcessor
{
public:
+ struct ResolverSpec
+ {
+ String Name;
+ Object::Ptr Obj;
+
+ // Whether to resolve not only e.g. $host.address$, but also just $address$
+ bool ResolveShortMacros;
+
+ inline ResolverSpec(String name, Object::Ptr obj, bool resolveShortMacros = true)
+ : Name(std::move(name)), Obj(std::move(obj)), ResolveShortMacros(resolveShortMacros)
+ {
+ }
+ };
+
typedef std::function EscapeCallback;
- typedef std::pair ResolverSpec;
typedef std::vector ResolverList;
static Value ResolveMacros(const Value& str, const ResolverList& resolvers,
diff --git a/lib/icingadb/icingadbchecktask.cpp b/lib/icingadb/icingadbchecktask.cpp
index c2f1a3699..f7c596457 100644
--- a/lib/icingadb/icingadbchecktask.cpp
+++ b/lib/icingadb/icingadbchecktask.cpp
@@ -61,7 +61,6 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
auto resolve ([&](const String& macro) {
return MacroProcessor::ResolveMacros(macro, resolvers, checkable->GetLastCheckResult(),
diff --git a/lib/livestatus/hoststable.cpp b/lib/livestatus/hoststable.cpp
index ad049edbe..d90f4a56e 100644
--- a/lib/livestatus/hoststable.cpp
+++ b/lib/livestatus/hoststable.cpp
@@ -10,7 +10,6 @@
#include "icinga/eventcommand.hpp"
#include "icinga/timeperiod.hpp"
#include "icinga/macroprocessor.hpp"
-#include "icinga/icingaapplication.hpp"
#include "icinga/compatutility.hpp"
#include "icinga/pluginutility.hpp"
#include "base/configtype.hpp"
@@ -315,7 +314,6 @@ Value HostsTable::NotesExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "host", host },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(host->GetNotes(), resolvers);
@@ -340,7 +338,6 @@ Value HostsTable::NotesUrlExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "host", host },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(host->GetNotesUrl(), resolvers);
@@ -365,7 +362,6 @@ Value HostsTable::ActionUrlExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "host", host },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(host->GetActionUrl(), resolvers);
@@ -422,7 +418,6 @@ Value HostsTable::IconImageExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "host", host },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(host->GetIconImage(), resolvers);
diff --git a/lib/livestatus/servicestable.cpp b/lib/livestatus/servicestable.cpp
index bb5d4fb81..681445aaf 100644
--- a/lib/livestatus/servicestable.cpp
+++ b/lib/livestatus/servicestable.cpp
@@ -12,7 +12,6 @@
#include "icinga/eventcommand.hpp"
#include "icinga/timeperiod.hpp"
#include "icinga/macroprocessor.hpp"
-#include "icinga/icingaapplication.hpp"
#include "icinga/compatutility.hpp"
#include "icinga/pluginutility.hpp"
#include "base/configtype.hpp"
@@ -372,7 +371,6 @@ Value ServicesTable::NotesExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "service", service },
{ "host", service->GetHost() },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(service->GetNotes(), resolvers);
@@ -398,7 +396,6 @@ Value ServicesTable::NotesUrlExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "service", service },
{ "host", service->GetHost() },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(service->GetNotesUrl(), resolvers);
@@ -424,7 +421,6 @@ Value ServicesTable::ActionUrlExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "service", service },
{ "host", service->GetHost() },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(service->GetActionUrl(), resolvers);
@@ -450,7 +446,6 @@ Value ServicesTable::IconImageExpandedAccessor(const Value& row)
MacroProcessor::ResolverList resolvers {
{ "service", service },
{ "host", service->GetHost() },
- { "icinga", IcingaApplication::GetInstance() }
};
return MacroProcessor::ResolveMacros(service->GetIconImage(), resolvers);
diff --git a/lib/methods/clusterzonechecktask.cpp b/lib/methods/clusterzonechecktask.cpp
index 983719795..fd52534c3 100644
--- a/lib/methods/clusterzonechecktask.cpp
+++ b/lib/methods/clusterzonechecktask.cpp
@@ -63,7 +63,6 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", command);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String zoneName = MacroProcessor::ResolveMacros("$cluster_zone$", resolvers, checkable->GetLastCheckResult(),
nullptr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros);
diff --git a/lib/methods/dummychecktask.cpp b/lib/methods/dummychecktask.cpp
index 561415c64..905a022c3 100644
--- a/lib/methods/dummychecktask.cpp
+++ b/lib/methods/dummychecktask.cpp
@@ -4,7 +4,6 @@
# include
#endif /* _WIN32 */
#include "methods/dummychecktask.hpp"
-#include "icinga/icingaapplication.hpp"
#include "icinga/pluginutility.hpp"
#include "base/utility.hpp"
#include "base/perfdatavalue.hpp"
@@ -37,7 +36,6 @@ void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", command);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
int dummyState = MacroProcessor::ResolveMacros("$dummy_state$", resolvers, checkable->GetLastCheckResult(),
nullptr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros);
diff --git a/lib/methods/icingachecktask.cpp b/lib/methods/icingachecktask.cpp
index 40795495d..d3eae1f33 100644
--- a/lib/methods/icingachecktask.cpp
+++ b/lib/methods/icingachecktask.cpp
@@ -5,7 +5,6 @@
#include "icinga/service.hpp"
#include "icinga/checkcommand.hpp"
#include "icinga/macroprocessor.hpp"
-#include "icinga/icingaapplication.hpp"
#include "icinga/clusterevents.hpp"
#include "icinga/checkable.hpp"
#include "remote/apilistener.hpp"
@@ -41,7 +40,6 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", command);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String missingIcingaMinVersion;
diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp
index 9bfa72203..b4749fbfd 100644
--- a/lib/methods/pluginchecktask.cpp
+++ b/lib/methods/pluginchecktask.cpp
@@ -4,7 +4,6 @@
#include "icinga/pluginutility.hpp"
#include "icinga/checkcommand.hpp"
#include "icinga/macroprocessor.hpp"
-#include "icinga/icingaapplication.hpp"
#include "base/configtype.hpp"
#include "base/logger.hpp"
#include "base/function.hpp"
@@ -37,7 +36,6 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
int timeout = commandObj->GetTimeout();
diff --git a/lib/methods/plugineventtask.cpp b/lib/methods/plugineventtask.cpp
index 8b2fc44ac..00efb6ce4 100644
--- a/lib/methods/plugineventtask.cpp
+++ b/lib/methods/plugineventtask.cpp
@@ -4,7 +4,6 @@
#include "icinga/eventcommand.hpp"
#include "icinga/macroprocessor.hpp"
#include "icinga/pluginutility.hpp"
-#include "icinga/icingaapplication.hpp"
#include "base/configtype.hpp"
#include "base/logger.hpp"
#include "base/function.hpp"
@@ -36,7 +35,6 @@ void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable,
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
int timeout = commandObj->GetTimeout();
std::function callback;
diff --git a/lib/methods/pluginnotificationtask.cpp b/lib/methods/pluginnotificationtask.cpp
index 17f34cda8..a20c971a1 100644
--- a/lib/methods/pluginnotificationtask.cpp
+++ b/lib/methods/pluginnotificationtask.cpp
@@ -6,7 +6,6 @@
#include "icinga/pluginutility.hpp"
#include "icinga/service.hpp"
#include "icinga/macroprocessor.hpp"
-#include "icinga/icingaapplication.hpp"
#include "base/function.hpp"
#include "base/logger.hpp"
#include "base/utility.hpp"
@@ -53,7 +52,6 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
int timeout = commandObj->GetTimeout();
std::function callback;
diff --git a/lib/methods/sleepchecktask.cpp b/lib/methods/sleepchecktask.cpp
index a018de46b..af6b0638e 100644
--- a/lib/methods/sleepchecktask.cpp
+++ b/lib/methods/sleepchecktask.cpp
@@ -1,7 +1,6 @@
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "methods/sleepchecktask.hpp"
-#include "icinga/icingaapplication.hpp"
#include "icinga/pluginutility.hpp"
#include "base/utility.hpp"
#include "base/convert.hpp"
@@ -33,7 +32,6 @@ void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
resolvers.emplace_back("command", commandObj);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
double sleepTime = MacroProcessor::ResolveMacros("$sleep_time$", resolvers, checkable->GetLastCheckResult(),
nullptr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros);
diff --git a/lib/perfdata/graphitewriter.cpp b/lib/perfdata/graphitewriter.cpp
index 4b9424e80..19e1209bd 100644
--- a/lib/perfdata/graphitewriter.cpp
+++ b/lib/perfdata/graphitewriter.cpp
@@ -293,7 +293,6 @@ void GraphiteWriter::CheckResultHandlerInternal(const Checkable::Ptr& checkable,
if (service)
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String prefix;
diff --git a/lib/perfdata/influxdbcommonwriter.cpp b/lib/perfdata/influxdbcommonwriter.cpp
index 42b7f02b7..0303af09f 100644
--- a/lib/perfdata/influxdbcommonwriter.cpp
+++ b/lib/perfdata/influxdbcommonwriter.cpp
@@ -224,7 +224,6 @@ void InfluxdbCommonWriter::CheckResultHandlerWQ(const Checkable::Ptr& checkable,
if (service)
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
String prefix;
diff --git a/lib/perfdata/opentsdbwriter.cpp b/lib/perfdata/opentsdbwriter.cpp
index e83cb59cb..c7d825fef 100644
--- a/lib/perfdata/opentsdbwriter.cpp
+++ b/lib/perfdata/opentsdbwriter.cpp
@@ -195,8 +195,7 @@ void OpenTsdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C
if (service)
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
-
+
// Resolve macros for the service and host template config line
if (config_tmpl_tags) {
ObjectLock olock(config_tmpl_tags);
diff --git a/lib/perfdata/perfdatawriter.cpp b/lib/perfdata/perfdatawriter.cpp
index 77652b1da..0e99c2728 100644
--- a/lib/perfdata/perfdatawriter.cpp
+++ b/lib/perfdata/perfdatawriter.cpp
@@ -116,7 +116,6 @@ void PerfdataWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C
if (service)
resolvers.emplace_back("service", service);
resolvers.emplace_back("host", host);
- resolvers.emplace_back("icinga", IcingaApplication::GetInstance());
if (service) {
String line = MacroProcessor::ResolveMacros(GetServiceFormatTemplate(), resolvers, cr, nullptr, &PerfdataWriter::EscapeMacroMetric);