Skip to content

fix(sc-event): replay status-change events after a downtime ends#345

Draft
sdepassio wants to merge 1 commit into
developfrom
CTOR-2043-stream-connector-do-not-send-alerts-that-happened-during-a-downtime-when-downtime-ends
Draft

fix(sc-event): replay status-change events after a downtime ends#345
sdepassio wants to merge 1 commit into
developfrom
CTOR-2043-stream-connector-do-not-send-alerts-that-happened-during-a-downtime-when-downtime-ends

Conversation

@sdepassio

Copy link
Copy Markdown
Contributor

Description

When a status change during a downtime, the event is never sent to the stream connector.
Fix: the last status event is stored, and if at the end of the downtime the status has changed the event is sent.

Fixes CTOR-2043

Type of change

  • Patch fixing an issue (non-breaking change)
  • New functionality (non-breaking change)
  • Breaking change (patch or feature) that might cause side effects breaking part of the Software

Checklist

Community contributors & Centreon team

  • I have followed the coding style guidelines provided by Centreon
  • I have commented my code, especially new classes, functions or any legacy code modified. (docblock)
  • I have commented my code, especially hard-to-understand areas of the PR.
  • I have rebased my development branch on the base branch (master, maintenance).

@sdepassio sdepassio force-pushed the CTOR-2043-stream-connector-do-not-send-alerts-that-happened-during-a-downtime-when-downtime-ends branch from 6de8b1c to 585cbc5 Compare May 5, 2026 12:44
@sdepassio sdepassio force-pushed the CTOR-2043-stream-connector-do-not-send-alerts-that-happened-during-a-downtime-when-downtime-ends branch from 585cbc5 to 80edc33 Compare June 25, 2026 09:40
Comment on lines +78 to +80
if not self.downtimes_storage then
self.downtimes_storage = sc_storage.new(self.sc_common, self.sc_logger, self.params)
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the stream connector starts a sc_storage instance and set it as an argument of the sc_event instance.
therefore, you can already have access to the storage with self.sc_storage

By creating a new storage instance in each instance of the sc_event class you'll end up loading the sqlite db each time we receive an event

downtime_start = self.event.actual_start_time,
downtime_end = self.event.actual_end_time
}
if not self.downtimes_storage:set_multiple(object_id, storage_data) then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not self.downtimes_storage:set_multiple(object_id, storage_data) then
if not self.sc_storage:set_multiple(object_id, storage_data) then

based on my previous comment, you can just use the already existing storage instance

self.sc_logger:error("[sc_event:is_valid_element]: Cannot register downtime datas in storage.")
end
elseif self:is_valid_downtime_event_end() then
local ok, stored = self.downtimes_storage:get_multiple(object_id, {"object_type", "status", "broker_event"})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local ok, stored = self.downtimes_storage:get_multiple(object_id, {"object_type", "status", "broker_event"})
local ok, stored = self.sc_storage:get_multiple(object_id, {"object_type", "status", "broker_event"})

if stored.broker_event and pending_event_handler then
-- delete broker_event from storage before sending to prevent duplicate dispatch
-- on the second downtime end event (cancellation + deletion both trigger this path)
self.downtimes_storage:delete(object_id, "broker_event")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.downtimes_storage:delete(object_id, "broker_event")
self.sc_storage:delete(object_id, "broker_event")

else
object_id = 'downtime_host_' .. self.event.host_id
end
local ok, stored = self.downtimes_storage:get_multiple(object_id, {"object_type", "status"})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local ok, stored = self.downtimes_storage:get_multiple(object_id, {"object_type", "status"})
local ok, stored = self.sc_storage:get_multiple(object_id, {"object_type", "status"})

if ok then
if stored.status ~= self.event.state then
-- store broker_event as explicit JSON string to avoid relying on storage backend type conversion
if not self.downtimes_storage:set(object_id, "broker_event", broker.json_encode(self.broker_event)) then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not self.downtimes_storage:set(object_id, "broker_event", broker.json_encode(self.broker_event)) then
if not self.sc_storage:set(object_id, "broker_event", broker.json_encode(self.broker_event)) then

self.sc_logger:error("[sc_event:is_valid_event_downtime_state]: event hasn't been stored in storage")
end
else
self.downtimes_storage:set(object_id, "broker_event", nil)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.downtimes_storage:set(object_id, "broker_event", nil)
self.sc_storage:set(object_id, "broker_event", nil)

Comment on lines +805 to +807
if not self.downtimes_storage then
self.downtimes_storage = sc_storage.new(self.sc_common, self.sc_logger, self.params)
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not supposed to be needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants