class FileLogger : StreamLogger
{
+ activation_priority -100;
+
[config, required] String path;
};
class SyslogLogger : Logger
{
+ activation_priority -100;
+
[config] String facility {
default {{{ return "LOG_USER"; }}}
};
return std::vector<String>();
}
+int Type::GetActivationPriority() const
+{
+ return 0;
+}
+
void Type::RegisterAttributeHandler(int fieldId, const AttributeHandler& callback)
{
throw std::runtime_error("Invalid field ID.");
Value GetField(int id) const override;
virtual std::vector<String> GetLoadDependencies() const;
+ virtual int GetActivationPriority() const;
typedef std::function<void (const Object::Ptr&, const Value&)> AttributeHandler;
virtual void RegisterAttributeHandler(int fieldId, const AttributeHandler& callback);
class CheckerComponent : ConfigObject
{
+ activation_priority 100;
+
[config] int concurrent_checks {
get {{{
return Application::GetMaxConcurrentChecks();
class CheckResultReader : ConfigObject
{
+ activation_priority 100;
+
[config] String spool_dir {
default {{{ return Application::GetLocalStateDir() + "/lib/icinga2/spool/checkresults/"; }}}
};
class CompatLogger : ConfigObject
{
+ activation_priority 100;
+
[config] String log_dir {
default {{{ return Application::GetLocalStateDir() + "/log/icinga2/compat"; }}}
};
class ExternalCommandListener : ConfigObject
{
+ activation_priority 100;
+
[config] String command_path {
default {{{ return Application::GetRunDir() + "/icinga2/cmd/icinga2.cmd"; }}}
};
class StatusDataWriter : ConfigObject
{
+ activation_priority 100;
+
[config] String status_path {
default {{{ return Application::GetLocalStateDir() + "/cache/icinga2/status.dat"; }}}
};
if (!silent)
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
- for (const ConfigItem::Ptr& item : newItems) {
- if (!item->m_Object)
- continue;
+ /* Activate objects in priority order. */
+ std::vector<Type::Ptr> types = Type::GetAllTypes();
- ConfigObject::Ptr object = item->m_Object;
+ std::sort(types.begin(), types.end(), [](const Type::Ptr& a, const Type::Ptr& b) {
+ if (a->GetActivationPriority() < b->GetActivationPriority())
+ return true;
+ return false;
+ });
+
+ for (const Type::Ptr& type : types) {
+ for (const ConfigItem::Ptr& item : newItems) {
+ if (!item->m_Object)
+ continue;
+
+ ConfigObject::Ptr object = item->m_Object;
+ Type::Ptr objectType = object->GetReflectionType();
+
+ if (objectType != type)
+ continue;
#ifdef I2_DEBUG
- Log(LogDebug, "ConfigItem")
- << "Activating object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'";
+ Log(LogDebug, "ConfigItem")
+ << "Activating object '" << object->GetName() << "' of type '"
+ << objectType->GetName() << "' with priority '"
+ << objectType->GetActivationPriority();
#endif /* I2_DEBUG */
- object->Activate(runtimeCreated);
+ object->Activate(runtimeCreated);
+ }
}
upq.Join();
class IdoMysqlConnection : DbConnection
{
+ activation_priority 100;
+
[config] String host {
default {{{ return "localhost"; }}}
};
class IdoPgsqlConnection : DbConnection
{
+ activation_priority 100;
+
[config] String host {
default {{{ return "localhost"; }}}
};
{
class LivestatusListener : ConfigObject {
+ activation_priority 100;
+
[config] String socket_type {
default {{{ return "unix"; }}}
};
class NotificationComponent : ConfigObject
{
+ activation_priority 100;
+
[config] bool enable_ha (EnableHA) {
default {{{ return true; }}}
};
class ElasticsearchWriter : ConfigObject
{
+ activation_priority 100;
+
[config, required] String host {
default {{{ return "127.0.0.1"; }}}
};
class GelfWriter : ConfigObject
{
+ activation_priority 100;
+
[config] String host {
default {{{ return "127.0.0.1"; }}}
};
class GraphiteWriter : ConfigObject
{
+ activation_priority 100;
+
[config] String host {
default {{{ return "127.0.0.1"; }}}
};
class InfluxdbWriter : ConfigObject
{
+ activation_priority 100;
+
[config, required] String host {
default {{{ return "127.0.0.1"; }}}
};
class OpenTsdbWriter : ConfigObject
{
+ activation_priority 100;
+
[config] String host {
default {{{ return "127.0.0.1"; }}}
};
class PerfdataWriter : ConfigObject
{
+ activation_priority 100;
+
[config] String host_perfdata_path {
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/host-perfdata"; }}}
};
class ApiListener : ConfigObject
{
+ activation_priority 50;
+
[config, deprecated] String cert_path;
[config, deprecated] String key_path;
[config, deprecated] String ca_path;
namespace { return T_NAMESPACE; }
code { return T_CODE; }
load_after { return T_LOAD_AFTER; }
+activation_priority { return T_ACTIVATION_PRIORITY; }
library { return T_LIBRARY; }
abstract { yylval->num = TAAbstract; return T_CLASS_ATTRIBUTE; }
vararg_constructor { yylval->num = TAVarArgConstructor; return T_CLASS_ATTRIBUTE; }
\"[^\"]+\" { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_STRING; }
\<[^ \>]*\> { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_ANGLE_STRING; }
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
+-?[0-9]+(\.[0-9]+)? { yylval->num = strtod(yytext, NULL); return T_NUMBER; }
. return yytext[0];
%token T_CLASS "class (T_CLASS)"
%token T_CODE "code (T_CODE)"
%token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
+%token T_ACTIVATION_PRIORITY "activation_priority (T_ACTIVATION_PRIORITY)"
%token T_LIBRARY "library (T_LIBRARY)"
%token T_NAMESPACE "namespace (T_NAMESPACE)"
%token T_VALIDATOR "validator (T_VALIDATOR)"
%token T_SET "set (T_SET)"
%token T_DEFAULT "default (T_DEFAULT)"
%token T_FIELD_ACCESSOR_TYPE "field_accessor_type (T_FIELD_ACCESSOR_TYPE)"
+%token T_NUMBER "number (T_NUMBER)"
%type <text> T_IDENTIFIER
%type <text> T_STRING
%type <text> T_ANGLE_STRING
%type <rule> validator_rule
%type <rules> validator_rules
%type <validator> validator
+%type <num> T_NUMBER
%{
for (const Field& field : *$7) {
if (field.Attributes & FALoadDependency) {
$$->LoadDependencies.push_back(field.Name);
+ } else if (field.Attributes & FAActivationPriority) {
+ $$->ActivationPriority = field.Priority;
} else
$$->Fields.push_back(field);
}
std::free($2);
$$ = field;
}
+ | T_ACTIVATION_PRIORITY T_NUMBER ';'
+ {
+ auto *field = new Field();
+ field->Attributes = FAActivationPriority;
+ field->Priority = $2;
+ $$ = field;
+ }
;
alternative_name_specifier: /* empty */
m_Impl << "\t" << "return deps;" << std::endl
<< "}" << std::endl << std::endl;
+ /* GetActivationPriority */
+ m_Header << "\t" << "int GetActivationPriority() const override;" << std::endl;
+
+ m_Impl << "int TypeImpl<" << klass.Name << ">::GetActivationPriority() const" << std::endl
+ << "{" << std::endl
+ << "\t" << "return " << klass.ActivationPriority << ";" << std::endl
+ << "}" << std::endl << std::endl;
+
/* RegisterAttributeHandler */
m_Header << "public:" << std::endl
<< "\t" << "void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;" << std::endl;
FANoUserView = 2048,
FADeprecated = 4096,
FAGetVirtual = 8192,
- FASetVirtual = 16384
+ FASetVirtual = 16384,
+ FAActivationPriority = 32768
};
struct FieldType
std::string NavigationName;
std::string NavigateAccessor;
bool PureNavigateAccessor{false};
+ int Priority{0};
inline std::string GetFriendlyName() const
{
int Attributes;
std::vector<Field> Fields;
std::vector<std::string> LoadDependencies;
+ int ActivationPriority{0};
};
enum RuleAttribute