mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-25 18:48:50 +02:00
Mismatching apply rules and parent objects: give time by rule and per object
This commit is contained in:
parent
2e38e24a31
commit
3ef0917dd9
@ -421,7 +421,7 @@ void ConfigObject::OnAllConfigLoaded()
|
|||||||
m_Zone = ctype->GetObject(zoneName);
|
m_Zone = ctype->GetObject(zoneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigObject::CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void ConfigObject::CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
/* Nothing to do here. */
|
/* Nothing to do here. */
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace icinga
|
|||||||
{
|
{
|
||||||
|
|
||||||
class ConfigType;
|
class ConfigType;
|
||||||
class TotalTimeSpentOnApplyMismatches;
|
class TimeSpentOnApplyMismatches;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dynamic object that can be instantiated from the configuration file.
|
* A dynamic object that can be instantiated from the configuration file.
|
||||||
@ -56,7 +56,7 @@ public:
|
|||||||
virtual void Resume();
|
virtual void Resume();
|
||||||
|
|
||||||
virtual void OnConfigLoaded();
|
virtual void OnConfigLoaded();
|
||||||
virtual void CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
virtual void CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
virtual void OnAllConfigLoaded();
|
virtual void OnAllConfigLoaded();
|
||||||
virtual void OnStateLoaded();
|
virtual void OnStateLoaded();
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "config/applyrule.hpp"
|
#include "config/applyrule.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
@ -198,9 +199,45 @@ void ApplyRule::CheckMatches(const ApplyRule::Ptr& rule, Type* sourceType, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double TotalTimeSpentOnApplyMismatches::AsSeconds() const
|
static double MonotonicTicksToSeconds(std::chrono::steady_clock::rep ticks)
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
return duration<double, seconds::period>(steady_clock::duration(m_MonotonicTicks.load())).count();
|
return duration<double, seconds::period>(steady_clock::duration(ticks)).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
double TimeSpentOnApplyMismatches::GetTotal()
|
||||||
|
{
|
||||||
|
std::chrono::steady_clock::rep total = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_lock<boost::shared_mutex> lock (m_Mutex);
|
||||||
|
|
||||||
|
for (auto& kv : m_ByRule) {
|
||||||
|
total += kv.second.MonotonicTicks.load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MonotonicTicksToSeconds(total);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TimeSpentOnApplyMismatches::BadRule> TimeSpentOnApplyMismatches::GetWorstRules()
|
||||||
|
{
|
||||||
|
std::vector<BadRule> worstRules;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_lock<boost::shared_mutex> lock (m_Mutex);
|
||||||
|
|
||||||
|
for (auto& kv : m_ByRule) {
|
||||||
|
worstRules.push_back({
|
||||||
|
kv.first, kv.second.ParentObjects.load(),MonotonicTicksToSeconds(kv.second.MonotonicTicks.load())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(worstRules.begin(), worstRules.end(), [](const BadRule& lhs, const BadRule& rhs) {
|
||||||
|
return lhs.SpentTime / lhs.ParentObjects > rhs.SpentTime / rhs.ParentObjects;
|
||||||
|
});
|
||||||
|
|
||||||
|
return worstRules;
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,18 @@
|
|||||||
|
|
||||||
#include "config/i2-config.hpp"
|
#include "config/i2-config.hpp"
|
||||||
#include "config/expression.hpp"
|
#include "config/expression.hpp"
|
||||||
#include "base/atomic.hpp"
|
|
||||||
#include "base/debuginfo.hpp"
|
#include "base/debuginfo.hpp"
|
||||||
#include "base/shared-object.hpp"
|
#include "base/shared-object.hpp"
|
||||||
#include "base/type.hpp"
|
#include "base/type.hpp"
|
||||||
|
#include <atomic>
|
||||||
|
#include <boost/thread/lock_types.hpp>
|
||||||
|
#include <boost/thread/shared_mutex.hpp>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
@ -114,29 +120,45 @@ private:
|
|||||||
|
|
||||||
class BenchmarkApplyRuleEvaluation;
|
class BenchmarkApplyRuleEvaluation;
|
||||||
|
|
||||||
class TotalTimeSpentOnApplyMismatches
|
class TimeSpentOnApplyMismatches
|
||||||
{
|
{
|
||||||
friend BenchmarkApplyRuleEvaluation;
|
friend BenchmarkApplyRuleEvaluation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TotalTimeSpentOnApplyMismatches() = default;
|
struct BadRule
|
||||||
TotalTimeSpentOnApplyMismatches(const TotalTimeSpentOnApplyMismatches&) = delete;
|
{
|
||||||
TotalTimeSpentOnApplyMismatches(TotalTimeSpentOnApplyMismatches&&) = delete;
|
ApplyRule::Ptr Rule;
|
||||||
TotalTimeSpentOnApplyMismatches& operator=(const TotalTimeSpentOnApplyMismatches&) = delete;
|
uint_fast32_t ParentObjects;
|
||||||
TotalTimeSpentOnApplyMismatches& operator=(TotalTimeSpentOnApplyMismatches&&) = delete;
|
double SpentTime;
|
||||||
|
};
|
||||||
|
|
||||||
double AsSeconds() const;
|
TimeSpentOnApplyMismatches() = default;
|
||||||
|
TimeSpentOnApplyMismatches(const TimeSpentOnApplyMismatches&) = delete;
|
||||||
|
TimeSpentOnApplyMismatches(TimeSpentOnApplyMismatches&&) = delete;
|
||||||
|
TimeSpentOnApplyMismatches& operator=(const TimeSpentOnApplyMismatches&) = delete;
|
||||||
|
TimeSpentOnApplyMismatches& operator=(TimeSpentOnApplyMismatches&&) = delete;
|
||||||
|
|
||||||
|
double GetTotal();
|
||||||
|
std::vector<BadRule> GetWorstRules();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Atomic<std::chrono::steady_clock::rep> m_MonotonicTicks {0};
|
struct PerRule
|
||||||
|
{
|
||||||
|
std::atomic<uint_fast32_t> ParentObjects;
|
||||||
|
std::atomic<std::chrono::steady_clock::rep> MonotonicTicks;
|
||||||
|
};
|
||||||
|
|
||||||
|
boost::shared_mutex m_Mutex;
|
||||||
|
std::map<ApplyRule::Ptr, PerRule> m_ByRule;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BenchmarkApplyRuleEvaluation
|
class BenchmarkApplyRuleEvaluation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline BenchmarkApplyRuleEvaluation(TotalTimeSpentOnApplyMismatches& totalTimeSpentOnMismatches, const bool& ruleMatched)
|
inline BenchmarkApplyRuleEvaluation(TimeSpentOnApplyMismatches& timeSpentOnMismatches,
|
||||||
: m_TotalTimeSpentOnMismatches(totalTimeSpentOnMismatches),
|
const ApplyRule::Ptr& rule, const bool& ruleMatched)
|
||||||
m_RuleMatched(ruleMatched), m_Start(std::chrono::steady_clock::now())
|
: m_TimeSpentOnMismatches(timeSpentOnMismatches), m_Rule(rule),
|
||||||
|
m_RuleMatched(ruleMatched), m_Start(std::chrono::steady_clock::now())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
BenchmarkApplyRuleEvaluation(const BenchmarkApplyRuleEvaluation&) = delete;
|
BenchmarkApplyRuleEvaluation(const BenchmarkApplyRuleEvaluation&) = delete;
|
||||||
@ -147,14 +169,32 @@ public:
|
|||||||
inline ~BenchmarkApplyRuleEvaluation()
|
inline ~BenchmarkApplyRuleEvaluation()
|
||||||
{
|
{
|
||||||
if (!m_RuleMatched) {
|
if (!m_RuleMatched) {
|
||||||
m_TotalTimeSpentOnMismatches.m_MonotonicTicks.fetch_add(
|
auto diff (std::chrono::steady_clock::now() - m_Start);
|
||||||
(std::chrono::steady_clock::now() - m_Start).count()
|
TimeSpentOnApplyMismatches::PerRule* total = nullptr;
|
||||||
);
|
auto& mtbr (m_TimeSpentOnMismatches.m_ByRule);
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_lock<boost::shared_mutex> lock (m_TimeSpentOnMismatches.m_Mutex);
|
||||||
|
auto perRule (mtbr.find(m_Rule));
|
||||||
|
|
||||||
|
if (perRule != mtbr.end()) {
|
||||||
|
total = &perRule->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!total) {
|
||||||
|
boost::unique_lock<boost::shared_mutex> lock (m_TimeSpentOnMismatches.m_Mutex);
|
||||||
|
total = &mtbr[m_Rule];
|
||||||
|
}
|
||||||
|
|
||||||
|
total->ParentObjects.fetch_add(1);
|
||||||
|
total->MonotonicTicks.fetch_add(diff.count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TotalTimeSpentOnApplyMismatches& m_TotalTimeSpentOnMismatches;
|
TimeSpentOnApplyMismatches& m_TimeSpentOnMismatches;
|
||||||
|
const ApplyRule::Ptr& m_Rule;
|
||||||
const bool& m_RuleMatched;
|
const bool& m_RuleMatched;
|
||||||
std::chrono::steady_clock::time_point m_Start;
|
std::chrono::steady_clock::time_point m_Start;
|
||||||
};
|
};
|
||||||
|
@ -387,7 +387,7 @@ ConfigItem::Ptr ConfigItem::GetByTypeAndName(const Type::Ptr& type, const String
|
|||||||
|
|
||||||
bool ConfigItem::CommitNewItems(
|
bool ConfigItem::CommitNewItems(
|
||||||
const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems,
|
const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
||||||
@ -598,14 +598,14 @@ bool ConfigItem::CommitNewItems(
|
|||||||
auto items (itemsByType.find(loadDep));
|
auto items (itemsByType.find(loadDep));
|
||||||
|
|
||||||
if (items != itemsByType.end()) {
|
if (items != itemsByType.end()) {
|
||||||
upq.ParallelFor(items->second, [&type, ¬ified_items, &totalTimeSpentOnApplyMismatches](const ItemPair& ip) {
|
upq.ParallelFor(items->second, [&type, ¬ified_items, &timeSpentOnApplyMismatches](const ItemPair& ip) {
|
||||||
const ConfigItem::Ptr& item = ip.first;
|
const ConfigItem::Ptr& item = ip.first;
|
||||||
|
|
||||||
if (!item->m_Object)
|
if (!item->m_Object)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ActivationScope ascope(item->m_ActivationContext);
|
ActivationScope ascope(item->m_ActivationContext);
|
||||||
item->m_Object->CreateChildObjects(type, totalTimeSpentOnApplyMismatches);
|
item->m_Object->CreateChildObjects(type, timeSpentOnApplyMismatches);
|
||||||
notified_items++;
|
notified_items++;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ bool ConfigItem::CommitNewItems(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure to activate any additionally generated items
|
// Make sure to activate any additionally generated items
|
||||||
if (!CommitNewItems(context, upq, newItems, totalTimeSpentOnApplyMismatches))
|
if (!CommitNewItems(context, upq, newItems, timeSpentOnApplyMismatches))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,9 +636,9 @@ bool ConfigItem::CommitItems(const ActivationContext::Ptr& context, WorkQueue& u
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
Log(LogInformation, "ConfigItem", "Committing config item(s).");
|
Log(LogInformation, "ConfigItem", "Committing config item(s).");
|
||||||
|
|
||||||
TotalTimeSpentOnApplyMismatches totalTimeSpentOnApplyMismatches;
|
TimeSpentOnApplyMismatches timeSpentOnApplyMismatches;
|
||||||
|
|
||||||
if (!CommitNewItems(context, upq, newItems, totalTimeSpentOnApplyMismatches)) {
|
if (!CommitNewItems(context, upq, newItems, timeSpentOnApplyMismatches)) {
|
||||||
upq.ReportExceptions("config");
|
upq.ReportExceptions("config");
|
||||||
|
|
||||||
for (const ConfigItem::Ptr& item : newItems) {
|
for (const ConfigItem::Ptr& item : newItems) {
|
||||||
@ -652,11 +652,23 @@ bool ConfigItem::CommitItems(const ActivationContext::Ptr& context, WorkQueue& u
|
|||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
Log(LogNotice, "ConfigItem")
|
Log(LogNotice, "ConfigItem")
|
||||||
<< "Spent " << totalTimeSpentOnApplyMismatches.AsSeconds()
|
<< "Spent " << timeSpentOnApplyMismatches.GetTotal()
|
||||||
<< " seconds on evaluating mismatching apply rules and parent objects."
|
<< " seconds on evaluating mismatching apply rules and parent objects."
|
||||||
<< " (This summary isn't aware of apply rules being evaluated in parallel."
|
<< " (This summary isn't aware of apply rules being evaluated in parallel."
|
||||||
<< " Therefore consider dividing the number by amount of CPU cores according to htop.)";
|
<< " Therefore consider dividing the number by amount of CPU cores according to htop.)";
|
||||||
|
|
||||||
|
if (LogDebug >= Logger::GetMinLogSeverity()) {
|
||||||
|
for (auto& perRule: timeSpentOnApplyMismatches.GetWorstRules()) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
ShowCodeLocation(oss, perRule.Rule->GetDebugInfo());
|
||||||
|
|
||||||
|
Log(LogDebug, "ConfigItem")
|
||||||
|
<< "Spent " << (perRule.SpentTime * 1000 / perRule.ParentObjects)
|
||||||
|
<< "ms on evaluating apply rule per mismatching parent object (total: "
|
||||||
|
<< (perRule.SpentTime * 1000) << "ms): " << oss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* log stats for external parsers */
|
/* log stats for external parsers */
|
||||||
typedef std::map<Type::Ptr, int> ItemCountMap;
|
typedef std::map<Type::Ptr, int> ItemCountMap;
|
||||||
ItemCountMap itemCounts;
|
ItemCountMap itemCounts;
|
||||||
|
@ -101,7 +101,7 @@ private:
|
|||||||
|
|
||||||
static bool CommitNewItems(
|
static bool CommitNewItems(
|
||||||
const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems,
|
const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ bool Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter)
|
bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule::Ptr& rule, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter)
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
BenchmarkApplyRuleEvaluation bare (totalTimeSpentOnApplyMismatches, match);
|
BenchmarkApplyRuleEvaluation bare (timeSpentOnApplyMismatches, rule, match);
|
||||||
|
|
||||||
auto& di (rule.GetDebugInfo());
|
auto& di (rule->GetDebugInfo());
|
||||||
|
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
||||||
@ -75,11 +75,11 @@ bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyR
|
|||||||
|
|
||||||
ScriptFrame frame (false);
|
ScriptFrame frame (false);
|
||||||
|
|
||||||
if (rule.GetScope() || rule.GetFTerm()) {
|
if (rule->GetScope() || rule->GetFTerm()) {
|
||||||
frame.Locals = new Dictionary();
|
frame.Locals = new Dictionary();
|
||||||
|
|
||||||
if (rule.GetScope()) {
|
if (rule->GetScope()) {
|
||||||
rule.GetScope()->CopyTo(frame.Locals);
|
rule->GetScope()->CopyTo(frame.Locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
||||||
@ -88,80 +88,80 @@ bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyR
|
|||||||
frame.Locals = checkable->GetFrozenLocalsForApply();
|
frame.Locals = checkable->GetFrozenLocalsForApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.GetFTerm()) {
|
if (rule->GetFTerm()) {
|
||||||
Value vinstances;
|
Value vinstances;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vinstances = rule.GetFTerm()->Evaluate(frame);
|
vinstances = rule->GetFTerm()->Evaluate(frame);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* Silently ignore errors here and assume there are no instances. */
|
/* Silently ignore errors here and assume there are no instances. */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinstances.IsObjectType<Array>()) {
|
if (vinstances.IsObjectType<Array>()) {
|
||||||
if (!rule.GetFVVar().IsEmpty())
|
if (!rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
||||||
|
|
||||||
Array::Ptr arr = vinstances;
|
Array::Ptr arr = vinstances;
|
||||||
|
|
||||||
ObjectLock olock(arr);
|
ObjectLock olock(arr);
|
||||||
for (const Value& instance : arr) {
|
for (const Value& instance : arr) {
|
||||||
String name = rule.GetName();
|
String name = rule->GetName();
|
||||||
|
|
||||||
frame.Locals->Set(rule.GetFKVar(), instance, true);
|
frame.Locals->Set(rule->GetFKVar(), instance, true);
|
||||||
name += instance;
|
name += instance;
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, name, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, name, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||||
if (rule.GetFVVar().IsEmpty())
|
if (rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
||||||
|
|
||||||
Dictionary::Ptr dict = vinstances;
|
Dictionary::Ptr dict = vinstances;
|
||||||
ObjectLock olock (dict);
|
ObjectLock olock (dict);
|
||||||
|
|
||||||
for (auto& kv : dict) {
|
for (auto& kv : dict) {
|
||||||
frame.Locals->Set(rule.GetFKVar(), kv.first, true);
|
frame.Locals->Set(rule->GetFKVar(), kv.first, true);
|
||||||
frame.Locals->Set(rule.GetFVVar(), kv.second, true);
|
frame.Locals->Set(rule->GetFVVar(), kv.second, true);
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, rule->GetName() + kv.first, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (EvaluateApplyRuleInstance(checkable, rule.GetName(), frame, rule, skipFilter)) {
|
} else if (EvaluateApplyRuleInstance(checkable, rule->GetName(), frame, *rule, skipFilter)) {
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dependency::EvaluateApplyRules(const Host::Ptr& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Dependency::EvaluateApplyRules(const Host::Ptr& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(Dependency::TypeInstance, Host::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(Dependency::TypeInstance, Host::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedHostRules(Dependency::TypeInstance, host->GetName())) {
|
for (auto& rule : ApplyRule::GetTargetedHostRules(Dependency::TypeInstance, host->GetName())) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dependency::EvaluateApplyRules(const Service::Ptr& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Dependency::EvaluateApplyRules(const Service::Ptr& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(Dependency::TypeInstance, Service::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(Dependency::TypeInstance, Service::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedServiceRules(Dependency::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
for (auto& rule : ApplyRule::GetTargetedServiceRules(Dependency::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#ifndef DEPENDENCY_H
|
#ifndef DEPENDENCY_H
|
||||||
#define DEPENDENCY_H
|
#define DEPENDENCY_H
|
||||||
|
|
||||||
|
#include "config/applyrule.hpp"
|
||||||
#include "icinga/i2-icinga.hpp"
|
#include "icinga/i2-icinga.hpp"
|
||||||
#include "icinga/dependency-ti.hpp"
|
#include "icinga/dependency-ti.hpp"
|
||||||
|
|
||||||
@ -34,8 +35,8 @@ public:
|
|||||||
|
|
||||||
void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
|
void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
|
||||||
|
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
/* Note: Only use them for unit test mocks. Prefer OnConfigLoaded(). */
|
/* Note: Only use them for unit test mocks. Prefer OnConfigLoaded(). */
|
||||||
void SetParent(intrusive_ptr<Checkable> parent);
|
void SetParent(intrusive_ptr<Checkable> parent);
|
||||||
@ -53,8 +54,8 @@ private:
|
|||||||
static bool EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
static bool EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
||||||
|
|
||||||
static bool EvaluateApplyRule(
|
static bool EvaluateApplyRule(
|
||||||
const Checkable::Ptr& checkable, const ApplyRule& rule,
|
const Checkable::Ptr& checkable, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter = false
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter = false
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,19 +47,19 @@ void Host::OnAllConfigLoaded()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Host::CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
if (childType == ScheduledDowntime::TypeInstance)
|
if (childType == ScheduledDowntime::TypeInstance)
|
||||||
ScheduledDowntime::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
ScheduledDowntime::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
if (childType == Notification::TypeInstance)
|
if (childType == Notification::TypeInstance)
|
||||||
Notification::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
Notification::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
if (childType == Dependency::TypeInstance)
|
if (childType == Dependency::TypeInstance)
|
||||||
Dependency::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
Dependency::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
if (childType == Service::TypeInstance)
|
if (childType == Service::TypeInstance)
|
||||||
Service::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
Service::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::Stop(bool runtimeRemoved)
|
void Host::Stop(bool runtimeRemoved)
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void Stop(bool runtimeRemoved) override;
|
void Stop(bool runtimeRemoved) override;
|
||||||
|
|
||||||
void CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches) override;
|
void CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches) override;
|
||||||
|
|
||||||
Dictionary::Ptr MakeLocalsForApply() override;
|
Dictionary::Ptr MakeLocalsForApply() override;
|
||||||
|
|
||||||
|
@ -62,14 +62,14 @@ bool Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Notification::EvaluateApplyRule(
|
bool Notification::EvaluateApplyRule(
|
||||||
const Checkable::Ptr& checkable, const ApplyRule& rule,
|
const Checkable::Ptr& checkable, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
BenchmarkApplyRuleEvaluation bare (totalTimeSpentOnApplyMismatches, match);
|
BenchmarkApplyRuleEvaluation bare (timeSpentOnApplyMismatches, rule, match);
|
||||||
|
|
||||||
auto& di (rule.GetDebugInfo());
|
auto& di (rule->GetDebugInfo());
|
||||||
|
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
||||||
@ -77,11 +77,11 @@ bool Notification::EvaluateApplyRule(
|
|||||||
|
|
||||||
ScriptFrame frame (false);
|
ScriptFrame frame (false);
|
||||||
|
|
||||||
if (rule.GetScope() || rule.GetFTerm()) {
|
if (rule->GetScope() || rule->GetFTerm()) {
|
||||||
frame.Locals = new Dictionary();
|
frame.Locals = new Dictionary();
|
||||||
|
|
||||||
if (rule.GetScope()) {
|
if (rule->GetScope()) {
|
||||||
rule.GetScope()->CopyTo(frame.Locals);
|
rule->GetScope()->CopyTo(frame.Locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
||||||
@ -90,81 +90,81 @@ bool Notification::EvaluateApplyRule(
|
|||||||
frame.Locals = checkable->GetFrozenLocalsForApply();
|
frame.Locals = checkable->GetFrozenLocalsForApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.GetFTerm()) {
|
if (rule->GetFTerm()) {
|
||||||
Value vinstances;
|
Value vinstances;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vinstances = rule.GetFTerm()->Evaluate(frame);
|
vinstances = rule->GetFTerm()->Evaluate(frame);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* Silently ignore errors here and assume there are no instances. */
|
/* Silently ignore errors here and assume there are no instances. */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinstances.IsObjectType<Array>()) {
|
if (vinstances.IsObjectType<Array>()) {
|
||||||
if (!rule.GetFVVar().IsEmpty())
|
if (!rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
||||||
|
|
||||||
Array::Ptr arr = vinstances;
|
Array::Ptr arr = vinstances;
|
||||||
|
|
||||||
ObjectLock olock(arr);
|
ObjectLock olock(arr);
|
||||||
for (const Value& instance : arr) {
|
for (const Value& instance : arr) {
|
||||||
String name = rule.GetName();
|
String name = rule->GetName();
|
||||||
|
|
||||||
frame.Locals->Set(rule.GetFKVar(), instance, true);
|
frame.Locals->Set(rule->GetFKVar(), instance, true);
|
||||||
name += instance;
|
name += instance;
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, name, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, name, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||||
if (rule.GetFVVar().IsEmpty())
|
if (rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
||||||
|
|
||||||
Dictionary::Ptr dict = vinstances;
|
Dictionary::Ptr dict = vinstances;
|
||||||
ObjectLock olock (dict);
|
ObjectLock olock (dict);
|
||||||
|
|
||||||
for (auto& kv : dict) {
|
for (auto& kv : dict) {
|
||||||
frame.Locals->Set(rule.GetFKVar(), kv.first, true);
|
frame.Locals->Set(rule->GetFKVar(), kv.first, true);
|
||||||
frame.Locals->Set(rule.GetFVVar(), kv.second, true);
|
frame.Locals->Set(rule->GetFVVar(), kv.second, true);
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, rule->GetName() + kv.first, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (EvaluateApplyRuleInstance(checkable, rule.GetName(), frame, rule, skipFilter)) {
|
} else if (EvaluateApplyRuleInstance(checkable, rule->GetName(), frame, *rule, skipFilter)) {
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notification::EvaluateApplyRules(const Host::Ptr& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Notification::EvaluateApplyRules(const Host::Ptr& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(Notification::TypeInstance, Host::TypeInstance))
|
for (auto& rule : ApplyRule::GetRules(Notification::TypeInstance, Host::TypeInstance))
|
||||||
{
|
{
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedHostRules(Notification::TypeInstance, host->GetName())) {
|
for (auto& rule : ApplyRule::GetTargetedHostRules(Notification::TypeInstance, host->GetName())) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notification::EvaluateApplyRules(const Service::Ptr& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Notification::EvaluateApplyRules(const Service::Ptr& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(Notification::TypeInstance, Service::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(Notification::TypeInstance, Service::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedServiceRules(Notification::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
for (auto& rule : ApplyRule::GetTargetedServiceRules(Notification::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#ifndef NOTIFICATION_H
|
#ifndef NOTIFICATION_H
|
||||||
#define NOTIFICATION_H
|
#define NOTIFICATION_H
|
||||||
|
|
||||||
|
#include "config/applyrule.hpp"
|
||||||
#include "icinga/i2-icinga.hpp"
|
#include "icinga/i2-icinga.hpp"
|
||||||
#include "icinga/notification-ti.hpp"
|
#include "icinga/notification-ti.hpp"
|
||||||
#include "icinga/checkable-ti.hpp"
|
#include "icinga/checkable-ti.hpp"
|
||||||
@ -99,8 +100,8 @@ public:
|
|||||||
void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
|
void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
|
||||||
void ValidateTimes(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
|
void ValidateTimes(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
|
||||||
|
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
static const std::map<String, int>& GetStateFilterMap();
|
static const std::map<String, int>& GetStateFilterMap();
|
||||||
static const std::map<String, int>& GetTypeFilterMap();
|
static const std::map<String, int>& GetTypeFilterMap();
|
||||||
@ -121,8 +122,8 @@ private:
|
|||||||
static bool EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
static bool EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
||||||
|
|
||||||
static bool EvaluateApplyRule(
|
static bool EvaluateApplyRule(
|
||||||
const intrusive_ptr<Checkable>& checkable, const ApplyRule& rule,
|
const intrusive_ptr<Checkable>& checkable, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter = false
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter = false
|
||||||
);
|
);
|
||||||
|
|
||||||
static std::map<String, int> m_StateFilterMap;
|
static std::map<String, int> m_StateFilterMap;
|
||||||
|
@ -61,14 +61,14 @@ bool ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ScheduledDowntime::EvaluateApplyRule(
|
bool ScheduledDowntime::EvaluateApplyRule(
|
||||||
const Checkable::Ptr& checkable, const ApplyRule& rule,
|
const Checkable::Ptr& checkable, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
BenchmarkApplyRuleEvaluation bare (totalTimeSpentOnApplyMismatches, match);
|
BenchmarkApplyRuleEvaluation bare (timeSpentOnApplyMismatches, rule, match);
|
||||||
|
|
||||||
auto& di (rule.GetDebugInfo());
|
auto& di (rule->GetDebugInfo());
|
||||||
|
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
||||||
@ -76,11 +76,11 @@ bool ScheduledDowntime::EvaluateApplyRule(
|
|||||||
|
|
||||||
ScriptFrame frame (false);
|
ScriptFrame frame (false);
|
||||||
|
|
||||||
if (rule.GetScope() || rule.GetFTerm()) {
|
if (rule->GetScope() || rule->GetFTerm()) {
|
||||||
frame.Locals = new Dictionary();
|
frame.Locals = new Dictionary();
|
||||||
|
|
||||||
if (rule.GetScope()) {
|
if (rule->GetScope()) {
|
||||||
rule.GetScope()->CopyTo(frame.Locals);
|
rule->GetScope()->CopyTo(frame.Locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
checkable->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
||||||
@ -89,80 +89,80 @@ bool ScheduledDowntime::EvaluateApplyRule(
|
|||||||
frame.Locals = checkable->GetFrozenLocalsForApply();
|
frame.Locals = checkable->GetFrozenLocalsForApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.GetFTerm()) {
|
if (rule->GetFTerm()) {
|
||||||
Value vinstances;
|
Value vinstances;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vinstances = rule.GetFTerm()->Evaluate(frame);
|
vinstances = rule->GetFTerm()->Evaluate(frame);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* Silently ignore errors here and assume there are no instances. */
|
/* Silently ignore errors here and assume there are no instances. */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinstances.IsObjectType<Array>()) {
|
if (vinstances.IsObjectType<Array>()) {
|
||||||
if (!rule.GetFVVar().IsEmpty())
|
if (!rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
||||||
|
|
||||||
Array::Ptr arr = vinstances;
|
Array::Ptr arr = vinstances;
|
||||||
|
|
||||||
ObjectLock olock(arr);
|
ObjectLock olock(arr);
|
||||||
for (const Value& instance : arr) {
|
for (const Value& instance : arr) {
|
||||||
String name = rule.GetName();
|
String name = rule->GetName();
|
||||||
|
|
||||||
frame.Locals->Set(rule.GetFKVar(), instance, true);
|
frame.Locals->Set(rule->GetFKVar(), instance, true);
|
||||||
name += instance;
|
name += instance;
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, name, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, name, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||||
if (rule.GetFVVar().IsEmpty())
|
if (rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
||||||
|
|
||||||
Dictionary::Ptr dict = vinstances;
|
Dictionary::Ptr dict = vinstances;
|
||||||
ObjectLock olock (dict);
|
ObjectLock olock (dict);
|
||||||
|
|
||||||
for (auto& kv : dict) {
|
for (auto& kv : dict) {
|
||||||
frame.Locals->Set(rule.GetFKVar(), kv.first, true);
|
frame.Locals->Set(rule->GetFKVar(), kv.first, true);
|
||||||
frame.Locals->Set(rule.GetFVVar(), kv.second, true);
|
frame.Locals->Set(rule->GetFVVar(), kv.second, true);
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(checkable, rule->GetName() + kv.first, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (EvaluateApplyRuleInstance(checkable, rule.GetName(), frame, rule, skipFilter)) {
|
} else if (EvaluateApplyRuleInstance(checkable, rule->GetName(), frame, *rule, skipFilter)) {
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(ScheduledDowntime::TypeInstance, Host::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(ScheduledDowntime::TypeInstance, Host::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedHostRules(ScheduledDowntime::TypeInstance, host->GetName())) {
|
for (auto& rule : ApplyRule::GetTargetedHostRules(ScheduledDowntime::TypeInstance, host->GetName())) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(ScheduledDowntime::TypeInstance, Service::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(ScheduledDowntime::TypeInstance, Service::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedServiceRules(ScheduledDowntime::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
for (auto& rule : ApplyRule::GetTargetedServiceRules(ScheduledDowntime::TypeInstance, service->GetHost()->GetName(), service->GetShortName())) {
|
||||||
if (EvaluateApplyRule(service, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(service, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#ifndef SCHEDULEDDOWNTIME_H
|
#ifndef SCHEDULEDDOWNTIME_H
|
||||||
#define SCHEDULEDDOWNTIME_H
|
#define SCHEDULEDDOWNTIME_H
|
||||||
|
|
||||||
|
#include "config/applyrule.hpp"
|
||||||
#include "icinga/i2-icinga.hpp"
|
#include "icinga/i2-icinga.hpp"
|
||||||
#include "icinga/scheduleddowntime-ti.hpp"
|
#include "icinga/scheduleddowntime-ti.hpp"
|
||||||
#include "icinga/checkable.hpp"
|
#include "icinga/checkable.hpp"
|
||||||
@ -29,8 +30,8 @@ public:
|
|||||||
|
|
||||||
Checkable::Ptr GetCheckable() const;
|
Checkable::Ptr GetCheckable() const;
|
||||||
|
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Host>& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const intrusive_ptr<Service>& service, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
static bool AllConfigIsLoaded();
|
static bool AllConfigIsLoaded();
|
||||||
|
|
||||||
void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
|
void ValidateRanges(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils) override;
|
||||||
@ -54,8 +55,8 @@ private:
|
|||||||
static bool EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
static bool EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
||||||
|
|
||||||
static bool EvaluateApplyRule(
|
static bool EvaluateApplyRule(
|
||||||
const Checkable::Ptr& checkable, const ApplyRule& rule,
|
const Checkable::Ptr& checkable, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter = false
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter = false
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,14 +56,14 @@ bool Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Service::EvaluateApplyRule(
|
bool Service::EvaluateApplyRule(
|
||||||
const Host::Ptr& host, const ApplyRule& rule,
|
const Host::Ptr& host, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
BenchmarkApplyRuleEvaluation bare (totalTimeSpentOnApplyMismatches, match);
|
BenchmarkApplyRuleEvaluation bare (timeSpentOnApplyMismatches, rule, match);
|
||||||
|
|
||||||
auto& di (rule.GetDebugInfo());
|
auto& di (rule->GetDebugInfo());
|
||||||
|
|
||||||
std::ostringstream msgbuf;
|
std::ostringstream msgbuf;
|
||||||
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
msgbuf << "Evaluating 'apply' rule (" << di << ")";
|
||||||
@ -71,11 +71,11 @@ bool Service::EvaluateApplyRule(
|
|||||||
|
|
||||||
ScriptFrame frame (false);
|
ScriptFrame frame (false);
|
||||||
|
|
||||||
if (rule.GetScope() || rule.GetFTerm()) {
|
if (rule->GetScope() || rule->GetFTerm()) {
|
||||||
frame.Locals = new Dictionary();
|
frame.Locals = new Dictionary();
|
||||||
|
|
||||||
if (rule.GetScope()) {
|
if (rule->GetScope()) {
|
||||||
rule.GetScope()->CopyTo(frame.Locals);
|
rule->GetScope()->CopyTo(frame.Locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
host->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
host->GetFrozenLocalsForApply()->CopyTo(frame.Locals);
|
||||||
@ -84,67 +84,67 @@ bool Service::EvaluateApplyRule(
|
|||||||
frame.Locals = host->GetFrozenLocalsForApply();
|
frame.Locals = host->GetFrozenLocalsForApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule.GetFTerm()) {
|
if (rule->GetFTerm()) {
|
||||||
Value vinstances;
|
Value vinstances;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vinstances = rule.GetFTerm()->Evaluate(frame);
|
vinstances = rule->GetFTerm()->Evaluate(frame);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
/* Silently ignore errors here and assume there are no instances. */
|
/* Silently ignore errors here and assume there are no instances. */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinstances.IsObjectType<Array>()) {
|
if (vinstances.IsObjectType<Array>()) {
|
||||||
if (!rule.GetFVVar().IsEmpty())
|
if (!rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
|
||||||
|
|
||||||
Array::Ptr arr = vinstances;
|
Array::Ptr arr = vinstances;
|
||||||
|
|
||||||
ObjectLock olock(arr);
|
ObjectLock olock(arr);
|
||||||
for (const Value& instance : arr) {
|
for (const Value& instance : arr) {
|
||||||
String name = rule.GetName();
|
String name = rule->GetName();
|
||||||
|
|
||||||
if (!rule.GetFKVar().IsEmpty()) {
|
if (!rule->GetFKVar().IsEmpty()) {
|
||||||
frame.Locals->Set(rule.GetFKVar(), instance, true);
|
frame.Locals->Set(rule->GetFKVar(), instance, true);
|
||||||
name += instance;
|
name += instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(host, name, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(host, name, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||||
if (rule.GetFVVar().IsEmpty())
|
if (rule->GetFVVar().IsEmpty())
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
|
||||||
|
|
||||||
Dictionary::Ptr dict = vinstances;
|
Dictionary::Ptr dict = vinstances;
|
||||||
ObjectLock olock (dict);
|
ObjectLock olock (dict);
|
||||||
|
|
||||||
for (auto& kv : dict) {
|
for (auto& kv : dict) {
|
||||||
frame.Locals->Set(rule.GetFKVar(), kv.first, true);
|
frame.Locals->Set(rule->GetFKVar(), kv.first, true);
|
||||||
frame.Locals->Set(rule.GetFVVar(), kv.second, true);
|
frame.Locals->Set(rule->GetFVVar(), kv.second, true);
|
||||||
|
|
||||||
if (EvaluateApplyRuleInstance(host, rule.GetName() + kv.first, frame, rule, skipFilter))
|
if (EvaluateApplyRuleInstance(host, rule->GetName() + kv.first, frame, *rule, skipFilter))
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (EvaluateApplyRuleInstance(host, rule.GetName(), frame, rule, skipFilter)) {
|
} else if (EvaluateApplyRuleInstance(host, rule->GetName(), frame, *rule, skipFilter)) {
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::EvaluateApplyRules(const Host::Ptr& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Service::EvaluateApplyRules(const Host::Ptr& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetRules(Service::TypeInstance, Host::TypeInstance)) {
|
for (auto& rule : ApplyRule::GetRules(Service::TypeInstance, Host::TypeInstance)) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rule : ApplyRule::GetTargetedHostRules(Service::TypeInstance, host->GetName())) {
|
for (auto& rule : ApplyRule::GetTargetedHostRules(Service::TypeInstance, host->GetName())) {
|
||||||
if (EvaluateApplyRule(host, *rule, totalTimeSpentOnApplyMismatches, true))
|
if (EvaluateApplyRule(host, rule, timeSpentOnApplyMismatches, true))
|
||||||
rule->AddMatch();
|
rule->AddMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,16 +74,16 @@ void Service::OnAllConfigLoaded()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches)
|
void Service::CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches)
|
||||||
{
|
{
|
||||||
if (childType == ScheduledDowntime::TypeInstance)
|
if (childType == ScheduledDowntime::TypeInstance)
|
||||||
ScheduledDowntime::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
ScheduledDowntime::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
if (childType == Notification::TypeInstance)
|
if (childType == Notification::TypeInstance)
|
||||||
Notification::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
Notification::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
if (childType == Dependency::TypeInstance)
|
if (childType == Dependency::TypeInstance)
|
||||||
Dependency::EvaluateApplyRules(this, totalTimeSpentOnApplyMismatches);
|
Dependency::EvaluateApplyRules(this, timeSpentOnApplyMismatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#ifndef SERVICE_H
|
#ifndef SERVICE_H
|
||||||
#define SERVICE_H
|
#define SERVICE_H
|
||||||
|
|
||||||
|
#include "config/applyrule.hpp"
|
||||||
#include "icinga/i2-icinga.hpp"
|
#include "icinga/i2-icinga.hpp"
|
||||||
#include "icinga/service-ti.hpp"
|
#include "icinga/service-ti.hpp"
|
||||||
#include "icinga/macroresolver.hpp"
|
#include "icinga/macroresolver.hpp"
|
||||||
@ -42,14 +43,14 @@ public:
|
|||||||
static StateType StateTypeFromString(const String& state);
|
static StateType StateTypeFromString(const String& state);
|
||||||
static String StateTypeToString(StateType state);
|
static String StateTypeToString(StateType state);
|
||||||
|
|
||||||
static void EvaluateApplyRules(const Host::Ptr& host, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches);
|
static void EvaluateApplyRules(const Host::Ptr& host, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches);
|
||||||
|
|
||||||
void OnAllConfigLoaded() override;
|
void OnAllConfigLoaded() override;
|
||||||
|
|
||||||
static boost::signals2::signal<void (const Service::Ptr&, const CheckResult::Ptr&, const MessageOrigin::Ptr&)> OnHostProblemChanged;
|
static boost::signals2::signal<void (const Service::Ptr&, const CheckResult::Ptr&, const MessageOrigin::Ptr&)> OnHostProblemChanged;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CreateChildObjects(const Type::Ptr& childType, TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches) override;
|
void CreateChildObjects(const Type::Ptr& childType, TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches) override;
|
||||||
|
|
||||||
Dictionary::Ptr MakeLocalsForApply() override;
|
Dictionary::Ptr MakeLocalsForApply() override;
|
||||||
|
|
||||||
@ -59,8 +60,8 @@ private:
|
|||||||
static bool EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
static bool EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, ScriptFrame& frame, const ApplyRule& rule, bool skipFilter);
|
||||||
|
|
||||||
static bool EvaluateApplyRule(
|
static bool EvaluateApplyRule(
|
||||||
const Host::Ptr& host, const ApplyRule& rule,
|
const Host::Ptr& host, const ApplyRule::Ptr& rule,
|
||||||
TotalTimeSpentOnApplyMismatches& totalTimeSpentOnApplyMismatches, bool skipFilter = false
|
TimeSpentOnApplyMismatches& timeSpentOnApplyMismatches, bool skipFilter = false
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user