All guides
Errors and events·3 min read

SEND EVENTS FROM PYTHON

Report errors and log messages from a Python app or script.

1

Send a message

This uses only the standard library:

import json, os, urllib.request

PUSH_URL = os.environ["UPGURU_PUSH_URL"]

def report(level, message, context=None):
    body = json.dumps({"level": level, "message": message, "context": context or {}}).encode()
    request = urllib.request.Request(PUSH_URL, data=body, headers={"Content-Type": "application/json"})
    try:
        urllib.request.urlopen(request, timeout=5)
    except OSError:
        pass  # Never let monitoring break your app.

report("info", "Nightly import finished", {"rows": 1200})
2

Or plug it into logging

Send every warning and error you already log, with the stack trace for exceptions:

import json, logging, os, traceback, urllib.request

PUSH_URL = os.environ["UPGURU_PUSH_URL"]

class UpguruHandler(logging.Handler):
    """Sends log records to UPGURU."""

    def emit(self, record):
        context = {"logger": record.name}
        if record.exc_info:
            cls, exc, tb = record.exc_info
            context["exception"] = {"class": cls.__name__, "message": str(exc),
                                    "trace": "".join(traceback.format_exception(cls, exc, tb))}
        body = json.dumps({"level": record.levelname.lower(), "message": record.getMessage(),
                           "context": context}).encode()
        request = urllib.request.Request(PUSH_URL, data=body, headers={"Content-Type": "application/json"})
        try:
            urllib.request.urlopen(request, timeout=5)
        except OSError:
            pass  # Never let monitoring break your app.

logging.getLogger().addHandler(UpguruHandler(level=logging.WARNING))

Now log.warning(…) shows up as a warning and log.exception(…) as an error with its stack trace.

Each message is sent right away. For an app that logs hundreds of warnings a second, raise the level to logging.ERROR.