Logging

logging instead of leftover print, levels, and basicConfig.

print is for the user of a script. logging is for operators: what happened, at what level, without mixing it into return values.

Goal

Configure a logger and emit INFO and WARNING for a kiosk shift.

basicConfig

import logging

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s %(message)s")
log = logging.getLogger("kiosk")

log.info("opened Nairobi kiosk")
log.warning("low stock for product B")
print("shift started")

The log lines go to stderr in this editor (often shown as warn). The print is stdout.

Levels

import logging

logging.basicConfig(level=logging.DEBUG, format="%(levelname)s %(message)s")
log = logging.getLogger("kiosk")

log.debug("units=12 price=10.5")
log.info("priced Nairobi line")
log.error("missing product C")
print("done")

DEBUG is noisy. In a real service you often ship INFO and keep DEBUG for local work.

Do not log instead of returning

import logging

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
log = logging.getLogger("kiosk")

def line_total(units, price):
    total = round(units * price * 1.16, 2)
    log.info("line_total units=%s price=%s total=%s", units, price, total)
    return total

print(line_total(2, 10))

The function still returns total. The log is extra.

Tip

Use %(message)s and pass values as extra arguments (log.info("x=%s", x)). Do not build the string with + if you can avoid it.