The Log Line That Tells You Nothing
The alert fires at 2am. You ssh in, open the logs, and find this:
ERROR myapp: connection pool exhausted
One line. The error itself, and nothing else.
You know what broke. You have no idea why. Was it a sudden traffic spike? A query that held a connection too long? A retry loop that ran away? The answer was in the DEBUG logs — but you turned those off six months ago because the noise was unbearable.
Then there's the other version of this problem. A teammate pings you: "hey, can you send me the error log for that failure yesterday?" You zip it up and send it over. They come back ten minutes later: "this just has the error line, there's no context here." You know they're right. You don't have anything better to send them. The conversation stalls because the information was never captured in the first place.
The logging level trap
Every Python developer eventually ends up in the same place. You start with DEBUG because you want visibility. The files balloon. Grepping through megabytes of chatter to find anything useful makes you want to quit your job. So you raise the level to WARNING, the logs go quiet, and life is good — until the next incident, when you realize you've traded noise for blindness.
The standard advice is to log more context in your error messages. So you start stuffing state into every logger.error() call. It helps, a little. But you're essentially rebuilding, by hand, the context that the preceding DEBUG logs already had — and you still can't reconstruct the sequence of events that led there.
The real problem is that log levels are a blunt instrument. You don't want DEBUG logs. You want DEBUG logs when something goes wrong.
What you actually want
Silent during normal operation. Full context the moment an error fires.
I built incident-logging (https://pypi.org/project/incident-logging/) because I kept wanting exactly this and kept hacking around the absence of it. It's a single-file Python logging handler — no dependencies — that buffers your DEBUG and INFO records silently. The moment a WARNING, ERROR, or CRITICAL is emitted, it flushes the recent buffer followed by the triggering message, then clears and starts over.
The buffer is a ring buffer. It holds the most recent N records. Old ones fall off. So you always get the context window just before the incident — not hours of irrelevant history, not nothing. And when a teammate asks for the error log, you actually have something useful to give them.
How to use it
import logging
from logging.handlers import RotatingFileHandler
from incident_logging import IncidentHandler
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)
# Incident log — only emits when WARNING or above fires, with recent context
incident = RotatingFileHandler("incidents.log", maxBytes=1_000_000, backupCount=3)
incident.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s %(message)s"))
logger.addHandler(IncidentHandler(target_handler=incident, buffer_size=30))
Source and install instructions: https://github.com/BenLin0/EmergencyLogging
Labels: Programming, working


















