mirror of https://github.com/Icinga/icinga2.git
Icinga DB: make icinga:history:stream:notification#id deterministic
... i.e. UUID -> SHA1(x..., send time) given that SHA1(x...) = notification id. Rationale: allow both masters to write the same notification history concurrently (while not in split-brain), so that REPLACE INTO deduplicates the same events written twice.
This commit is contained in:
parent
c2422c56fe
commit
5c44365c4e
|
@ -1603,7 +1603,7 @@ void IcingaDB::SendStateChange(const ConfigObject::Ptr& object, const CheckResul
|
||||||
|
|
||||||
void IcingaDB::SendSentNotification(
|
void IcingaDB::SendSentNotification(
|
||||||
const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
|
const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
|
||||||
NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text
|
NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text, double sendTime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!m_Rcon || !m_Rcon->IsConnected())
|
if (!m_Rcon || !m_Rcon->IsConnected())
|
||||||
|
@ -1620,10 +1620,15 @@ void IcingaDB::SendSentNotification(
|
||||||
|
|
||||||
auto usersAmount (users.size());
|
auto usersAmount (users.size());
|
||||||
auto notificationHistoryId = Utility::NewUniqueID();
|
auto notificationHistoryId = Utility::NewUniqueID();
|
||||||
|
auto sendTs (TimestampToMilliseconds(sendTime));
|
||||||
|
|
||||||
|
Array::Ptr rawId = new Array(Prepend(GetEnvironment(), GetObjectIdentifiersWithoutEnv(notification)));
|
||||||
|
rawId->Add(GetNotificationTypeByEnum(type));
|
||||||
|
rawId->Add(sendTs);
|
||||||
|
|
||||||
std::vector<String> xAdd ({
|
std::vector<String> xAdd ({
|
||||||
"XADD", "icinga:history:stream:notification", "*",
|
"XADD", "icinga:history:stream:notification", "*",
|
||||||
"id", notificationHistoryId,
|
"id", HashValue(rawId),
|
||||||
"environment_id", m_EnvironmentId,
|
"environment_id", m_EnvironmentId,
|
||||||
"notification_id", GetObjectIdentifier(notification),
|
"notification_id", GetObjectIdentifier(notification),
|
||||||
"host_id", GetObjectIdentifier(host),
|
"host_id", GetObjectIdentifier(host),
|
||||||
|
@ -1633,7 +1638,7 @@ void IcingaDB::SendSentNotification(
|
||||||
"author", Utility::ValidateUTF8(author),
|
"author", Utility::ValidateUTF8(author),
|
||||||
"text", Utility::ValidateUTF8(finalText),
|
"text", Utility::ValidateUTF8(finalText),
|
||||||
"users_notified", Convert::ToString(usersAmount),
|
"users_notified", Convert::ToString(usersAmount),
|
||||||
"send_time", Convert::ToString(TimestampToMilliseconds(Utility::GetTime())),
|
"send_time", Convert::ToString(sendTs),
|
||||||
"event_id", Utility::NewUniqueID(),
|
"event_id", Utility::NewUniqueID(),
|
||||||
"event_type", "notification"
|
"event_type", "notification"
|
||||||
});
|
});
|
||||||
|
@ -2382,10 +2387,11 @@ void IcingaDB::NotificationSentToAllUsersHandler(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto rws (ConfigType::GetObjectsByType<IcingaDB>());
|
auto rws (ConfigType::GetObjectsByType<IcingaDB>());
|
||||||
|
auto sendTime (notification->GetLastNotification());
|
||||||
|
|
||||||
if (!rws.empty()) {
|
if (!rws.empty()) {
|
||||||
for (auto& rw : rws) {
|
for (auto& rw : rws) {
|
||||||
rw->SendSentNotification(notification, checkable, users, type, cr, author, text);
|
rw->SendSentNotification(notification, checkable, users, type, cr, author, text, sendTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,32 @@ Dictionary::Ptr IcingaDB::SerializeVars(const CustomVarObject::Ptr& object)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* IcingaDB::GetNotificationTypeByEnum(NotificationType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case NotificationDowntimeStart:
|
||||||
|
return "downtime_start";
|
||||||
|
case NotificationDowntimeEnd:
|
||||||
|
return "downtime_end";
|
||||||
|
case NotificationDowntimeRemoved:
|
||||||
|
return "downtime_removed";
|
||||||
|
case NotificationCustom:
|
||||||
|
return "custom";
|
||||||
|
case NotificationAcknowledgement:
|
||||||
|
return "acknowledgement";
|
||||||
|
case NotificationProblem:
|
||||||
|
return "problem";
|
||||||
|
case NotificationRecovery:
|
||||||
|
return "recovery";
|
||||||
|
case NotificationFlappingStart:
|
||||||
|
return "flapping_start";
|
||||||
|
case NotificationFlappingEnd:
|
||||||
|
return "flapping_end";
|
||||||
|
}
|
||||||
|
|
||||||
|
VERIFY(!"Invalid notification type.");
|
||||||
|
}
|
||||||
|
|
||||||
static const std::set<String> propertiesBlacklistEmpty;
|
static const std::set<String> propertiesBlacklistEmpty;
|
||||||
|
|
||||||
String IcingaDB::HashValue(const Value& value)
|
String IcingaDB::HashValue(const Value& value)
|
||||||
|
|
|
@ -81,7 +81,7 @@ private:
|
||||||
|
|
||||||
void SendSentNotification(
|
void SendSentNotification(
|
||||||
const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
|
const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
|
||||||
NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text
|
NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text, double sendTime
|
||||||
);
|
);
|
||||||
|
|
||||||
void SendStartedDowntime(const Downtime::Ptr& downtime);
|
void SendStartedDowntime(const Downtime::Ptr& downtime);
|
||||||
|
@ -109,6 +109,7 @@ private:
|
||||||
static String GetObjectIdentifier(const ConfigObject::Ptr& object);
|
static String GetObjectIdentifier(const ConfigObject::Ptr& object);
|
||||||
static String GetEnvironment();
|
static String GetEnvironment();
|
||||||
static Dictionary::Ptr SerializeVars(const CustomVarObject::Ptr& object);
|
static Dictionary::Ptr SerializeVars(const CustomVarObject::Ptr& object);
|
||||||
|
static const char* GetNotificationTypeByEnum(NotificationType type);
|
||||||
|
|
||||||
static String HashValue(const Value& value);
|
static String HashValue(const Value& value);
|
||||||
static String HashValue(const Value& value, const std::set<String>& propertiesBlacklist, bool propertiesWhitelist = false);
|
static String HashValue(const Value& value, const std::set<String>& propertiesBlacklist, bool propertiesWhitelist = false);
|
||||||
|
|
Loading…
Reference in New Issue