Tutorial

Stream Python logging output to a browser in 5 minutes

Feb. 10, 2025 BunnyLogs Team

This is a minimal guide — from zero to a live log stream in five minutes. No theory, just the steps.

Step 1: Create a stream

Sign up at bunnylogs.com and click "New log stream". You'll land on a URL like bunnylogs.com/live/3f2a1b0c-d4e5-6789-abcd-ef0123456789. Keep that tab open — this is where your logs will appear.

Step 2: Install the package

pip install bunnylogs

Step 3: Add the handler

For a standalone script:

import logging
from bunnylogs import BunnyLogsHandler

logging.getLogger().addHandler(BunnyLogsHandler("your-uuid-here"))
logging.warning("hello from Python")

For a Django app — add to settings.py:

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "bunnylogs": {
            "class": "bunnylogs.BunnyLogsHandler",
            "uuid": "your-uuid-here",
        },
    },
    "root": {"handlers": ["bunnylogs"], "level": "WARNING"},
}

Run your script (or start Django). Switch to the browser tab you left open. Log lines will appear within milliseconds.

What you'll see

Each log record appears as a row with:

  • Timestamp (server time of receipt)
  • Level (DEBUG, INFO, WARNING, ERROR, CRITICAL) — colour-coded
  • Program (the logger name)
  • Message text

New lines appear at the bottom automatically. The stream pauses if you scroll up (so you can read) and resumes when you scroll back to the bottom.

Log levels

To control which levels are forwarded, pass a level argument to the handler:

from bunnylogs import BunnyLogsHandler
import logging

# Only forward WARNING and above
handler = BunnyLogsHandler("your-uuid", level=logging.WARNING)
logging.getLogger().addHandler(handler)

Or set it in the Django dict config as shown above.

Multiple loggers

You can add the handler to any logger, not just the root logger. To forward output from a specific module:

import logging
from bunnylogs import BunnyLogsHandler

logging.getLogger("myapp.payments").addHandler(
    BunnyLogsHandler("your-uuid")
)

The handler is non-blocking

Records are placed on an in-process queue and sent by a daemon thread, so emit() returns in microseconds. It won't slow down your application even if the network is slow.

Before your process exits, call logging.shutdown() to flush any queued records:

if __name__ == "__main__":
    try:
        main()
    finally:
        logging.shutdown()

Create your first stream →


Related posts