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.