自动补测、推送审计/退避重试、监控指标与监控页面

This commit is contained in:
DeepFal committed 2026-10-19 13:29:30 +08:00
1 parent 7445dcc51a
commit 24afb9e1dc
9 files changed
+831 -23

No files matched your search

+49
View File
@@ -8,6 +8,7 @@ HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(HERE))
from graylog_ops import watch # noqa: E402
from graylog_ops.behavior import notify_fused # noqa: E402
NOW = "2026-10-17T16:00:00Z"
@@ -99,6 +100,54 @@ class FusedTests(unittest.TestCase):
store.close()
class PushRetryTests(unittest.TestCase):
def test_failure_backoff_and_audit(self):
with tempfile.TemporaryDirectory() as directory:
store = watch.Store(os.path.join(directory, "ips.db"))
try:
store.replace_behavior_profiles([_behavior("198.51.100.8")])
store.sync_fused()
with store.lock, store.conn:
store.conn.execute(
"UPDATE ip_fused SET last_pushed_at=NULL WHERE ip=?",
("198.51.100.8",))
class Failing:
kind = "dingtalk"
def link_for(self, ip): return ""
def post(self, text, title=None): raise RuntimeError("boom")
notify_fused(store, Failing())
notif = store.notification_stats(24)
self.assertEqual(notif["failed"], 1)
self.assertEqual(notif["sent"], 0)
row = store.fused_row("198.51.100.8")
self.assertEqual(row["push_fail_count"], 1)
self.assertTrue(row["push_next_at"])
self.assertEqual(store.due_pushes(24, 24), []) # backoff active
self.assertEqual(store.get_meta("push_consecutive_failures"), "1")
with store.lock, store.conn:
store.conn.execute(
"UPDATE ip_fused SET push_next_at=NULL WHERE ip=?",
("198.51.100.8",))
class Working:
kind = "dingtalk"
def link_for(self, ip): return ""
def post(self, text, title=None): return None
notify_fused(store, Working())
row = store.fused_row("198.51.100.8")
self.assertEqual(row["push_fail_count"], 0)
self.assertIsNone(row["push_next_at"])
self.assertEqual(store.get_meta("push_consecutive_failures"), "0")
notif = store.notification_stats(24)
self.assertEqual(notif["sent"], 1)
finally:
store.close()
class HistoricalBehaviourTests(unittest.TestCase):
def test_historical_profile_survives_live_refresh(self):
with tempfile.TemporaryDirectory() as directory: