ihki / tests /test_log_errors.py
3v324v23's picture
Claude Opus 5.5
feat(monitoring): show the last 5 warning-or-worse log lines
d4af0e6
Raw History Blame Contribute Delete
1.48 kB
import logging
import time
from app.log_errors import MAX_LINE, ErrorCounter
def logged(counter, *calls):
logger = logging.getLogger("test_log_errors")
logger.propagate = False
logger.setLevel(logging.DEBUG)
logger.addHandler(counter)
try:
for level, message in calls:
logger.log(level, message)
finally:
logger.removeHandler(counter)
def test_counts_errors_only_and_windows():
c = ErrorCounter()
logged(c, (logging.INFO, "not counted"), (logging.WARNING, "a warning"),
(logging.ERROR, "an error"), (logging.CRITICAL, "also counted"))
now = time.time()
s = c.summary(now)
assert s["since_start"] == 2 and s["last_hour"] == 2 and s["last_24h"] == 2
# a day later the windows are empty but the total since start stays
later = c.summary(now + 2 * 86400)
assert later["since_start"] == 2 and later["last_24h"] == 0 and later["last_hour"] == 0
def test_keeps_the_last_five_warning_or_worse_lines_newest_first():
c = ErrorCounter()
logged(c, (logging.DEBUG, "debug"), (logging.INFO, "info"),
*[(logging.WARNING, f"warning {i}") for i in range(6)], (logging.ERROR, "x" * 1000))
recent = c.summary()["recent"]
assert [r["message"] for r in recent[1:]] == ["warning 5", "warning 4", "warning 3", "warning 2"]
assert recent[0]["level"] == "ERROR" and len(recent[0]["message"]) == MAX_LINE
assert all(r["logger"] == "test_log_errors" for r in recent)