mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-10-07 22:16:39 +00:00
fix: deduplicate repeated LXC digest results
This commit is contained in:
@@ -1636,20 +1636,33 @@ class NotificationManager:
|
|||||||
conn = sqlite3.connect(str(DB_PATH), timeout=10)
|
conn = sqlite3.connect(str(DB_PATH), timeout=10)
|
||||||
conn.execute('PRAGMA journal_mode=WAL')
|
conn.execute('PRAGMA journal_mode=WAL')
|
||||||
conn.execute('PRAGMA busy_timeout=5000')
|
conn.execute('PRAGMA busy_timeout=5000')
|
||||||
# Adjacent collectors can observe the same completed task. Only
|
# Adjacent collectors can observe one completed LXC update with
|
||||||
# coalesce byte-for-byte identical rows, so a different version,
|
# different transport details (for example source or duration).
|
||||||
# source or result stays visible in the same digest.
|
# The rendered title already identifies its LXC and result, so
|
||||||
|
# coalesce that narrowly. Other event types retain the stricter
|
||||||
|
# title-and-body comparison so distinct updates stay visible.
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
duplicate = conn.execute(
|
if event_type == 'lxc_update_applied':
|
||||||
'SELECT 1 FROM digest_pending '
|
duplicate = conn.execute(
|
||||||
'WHERE channel = ? AND event_type = ? AND event_group = ? '
|
'SELECT 1 FROM digest_pending '
|
||||||
'AND severity = ? AND title = ? AND body = ? AND ts >= ? '
|
'WHERE channel = ? AND event_type = ? AND event_group = ? '
|
||||||
'LIMIT 1',
|
'AND severity = ? AND title = ? AND ts >= ? LIMIT 1',
|
||||||
(
|
(
|
||||||
ch_name, event_type, event_group, severity, title, body,
|
ch_name, event_type, event_group, severity, title,
|
||||||
now - self._DIGEST_DUPLICATE_WINDOW,
|
now - self._DIGEST_DUPLICATE_WINDOW,
|
||||||
),
|
),
|
||||||
).fetchone()
|
).fetchone()
|
||||||
|
else:
|
||||||
|
duplicate = conn.execute(
|
||||||
|
'SELECT 1 FROM digest_pending '
|
||||||
|
'WHERE channel = ? AND event_type = ? AND event_group = ? '
|
||||||
|
'AND severity = ? AND title = ? AND body = ? AND ts >= ? '
|
||||||
|
'LIMIT 1',
|
||||||
|
(
|
||||||
|
ch_name, event_type, event_group, severity, title, body,
|
||||||
|
now - self._DIGEST_DUPLICATE_WINDOW,
|
||||||
|
),
|
||||||
|
).fetchone()
|
||||||
if duplicate:
|
if duplicate:
|
||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -707,7 +707,7 @@ class RuntimeCatalogTests(unittest.TestCase):
|
|||||||
self.assertNotIn("System", channel.payload[1])
|
self.assertNotIn("System", channel.payload[1])
|
||||||
self.assertTrue(channel.payload[3]["_quiet_hours_summary"])
|
self.assertTrue(channel.payload[3]["_quiet_hours_summary"])
|
||||||
|
|
||||||
def test_digest_buffer_coalesces_only_identical_recent_events(self):
|
def test_digest_buffer_coalesces_lxc_results_despite_detail_changes(self):
|
||||||
manager = notification_manager.NotificationManager()
|
manager = notification_manager.NotificationManager()
|
||||||
with tempfile.TemporaryDirectory() as directory:
|
with tempfile.TemporaryDirectory() as directory:
|
||||||
db_path = Path(directory) / "settings.db"
|
db_path = Path(directory) / "settings.db"
|
||||||
@@ -721,21 +721,26 @@ class RuntimeCatalogTests(unittest.TestCase):
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
with mock.patch.object(notification_manager, "DB_PATH", db_path), \
|
with mock.patch.object(notification_manager, "DB_PATH", db_path), \
|
||||||
mock.patch.object(notification_manager.time, "time", side_effect=(1000, 1060, 1070, 1301)):
|
mock.patch.object(notification_manager.time, "time", side_effect=(1000, 1060, 1070, 1080, 1301)):
|
||||||
manager._buffer_digest_event(
|
manager._buffer_digest_event(
|
||||||
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
||||||
"pve01: LXC wireguard (101) update completed", "Source: Manual",
|
"pve01: LXC wireguard (101) update completed", "Source: Manual",
|
||||||
)
|
)
|
||||||
# Same completed task from an adjacent collector: do not list it twice.
|
# An adjacent collector can report the same completion with
|
||||||
manager._buffer_digest_event(
|
# a different source or duration. It must not appear twice.
|
||||||
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
|
||||||
"pve01: LXC wireguard (101) update completed", "Source: Manual",
|
|
||||||
)
|
|
||||||
# Different result/body for the same LXC remains visible.
|
|
||||||
manager._buffer_digest_event(
|
manager._buffer_digest_event(
|
||||||
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
||||||
"pve01: LXC wireguard (101) update completed", "Source: Scheduled",
|
"pve01: LXC wireguard (101) update completed", "Source: Scheduled",
|
||||||
)
|
)
|
||||||
|
# Other event types still require the full message to match.
|
||||||
|
manager._buffer_digest_event(
|
||||||
|
"telegram", "app_update_available", "applications", "INFO",
|
||||||
|
"pve01: Update available", "Version: 1.0 → 1.1",
|
||||||
|
)
|
||||||
|
manager._buffer_digest_event(
|
||||||
|
"telegram", "app_update_available", "applications", "INFO",
|
||||||
|
"pve01: Update available", "Version: 1.0 → 1.2",
|
||||||
|
)
|
||||||
# The same result is allowed again outside the short window.
|
# The same result is allowed again outside the short window.
|
||||||
manager._buffer_digest_event(
|
manager._buffer_digest_event(
|
||||||
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
"telegram", "lxc_update_applied", "vm_ct", "INFO",
|
||||||
@@ -750,7 +755,12 @@ class RuntimeCatalogTests(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
rows,
|
rows,
|
||||||
[(1000, "Source: Manual"), (1070, "Source: Scheduled"), (1301, "Source: Manual")],
|
[
|
||||||
|
(1000, "Source: Manual"),
|
||||||
|
(1070, "Version: 1.0 → 1.1"),
|
||||||
|
(1080, "Version: 1.0 → 1.2"),
|
||||||
|
(1301, "Source: Manual"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_visible_templates_use_known_backend_and_frontend_groups(self):
|
def test_visible_templates_use_known_backend_and_frontend_groups(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user