Skip to content
This repository was archived by the owner on Nov 28, 2022. It is now read-only.

Latest commit

 

History

History
394 lines (266 loc) · 13 KB

index.rst

File metadata and controls

394 lines (266 loc) · 13 KB

logzero: Python logging made easy

Robust and effective logging for Python 2 and 3.

Logo

Features

  • Easy logging to console and/or (rotating) file.
  • Provides a fully configured Python logger object.
  • Pretty formatting, including level-specific colors in the console.
  • JSON logging support (with integrated python-json-logger)
  • Windows color output supported by colorama
  • Robust against str/bytes encoding problems, works with all kinds of character encodings and special characters.
  • Multiple loggers can write to the same logfile (also works across multiple Python files).
  • Any directory structured mentioned is automatically created, if it doesn't exist.
  • Global default logger with logzero.logger and custom loggers with logzero.setup_logger(..).
  • Compatible with Python 2 and 3.
  • All contained in a single file.
  • Licensed under the MIT license.
  • Heavily inspired by the Tornado web framework.
  • Hosted on GitHub: https://github.com/metachris/logzero

Installation

Install logzero with pip:

$ pip install -U logzero

If you don't have pip installed, this Python installation guide can guide you through the process.

You can also install logzero from the public Github repo:

$ git clone https://github.com/metachris/logzero.git
$ cd logzero
$ python setup.py install

Example usage

You can use logzero like this (logs only to the console by default):

from logzero import logger

logger.debug("hello")
logger.info("info")
logger.warning("warn")
logger.error("error")

# This is how you'd log an exception
try:
    raise Exception("this is a demo exception")
except Exception as e:
    logger.exception(e)

# JSON logging
import logzero
logzero.json()

logger.info("JSON test")

# Start writing into a logfile
logzero.logfile("/tmp/logzero-demo.log")

If this was a file called demo.py, the output will look like this:

Demo output in color

Logging to files

You can add logging to a (rotating) logfile like this:

import logzero
from logzero import logger

# non-rotating logfile
logzero.logfile("/tmp/logfile.log")

# rotating logfile
logzero.logfile("/tmp/rotating-logfile.log", maxBytes=1e6, backupCount=3)

# log messages
logger.info("This log message goes to the console and the logfile")

JSON logging

JSON logging can be enabled for the default logger with logzero.json(), or with setup_logger(json=True) for custom loggers:

# Configure the default logger to output JSON
>>> logzero.json()
>>> logger.info("test")
{"asctime": "2020-10-21 10:42:45,808", "filename": "<stdin>", "funcName": "<module>", "levelname": "INFO", "levelno": 20, "lineno": 1, "module": "<stdin>", "message": "test", "name": "logzero_default", "pathname": "<stdin>", "process": 76179, "processName": "MainProcess", "threadName": "MainThread"}

# Configure a custom logger to output JSON
>>> my_logger = setup_logger(json=True)
>>> my_logger.info("test")
{"asctime": "2020-10-21 10:42:45,808", "filename": "<stdin>", "funcName": "<module>", "levelname": "INFO", "levelno": 20, "lineno": 1, "module": "<stdin>", "message": "test", "name": "logzero_default", "pathname": "<stdin>", "process": 76179, "processName": "MainProcess", "threadName": "MainThread"}

The logged JSON object has these fields:

{
    "asctime": "2020-10-21 10:43:40,765",
    "filename": "test.py",
    "funcName": "test_this",
    "levelname": "INFO",
    "levelno": 20,
    "lineno": 9,
    "module": "test",
    "message": "info",
    "name": "logzero",
    "pathname": "_tests/test.py",
    "process": 76204,
    "processName": "MainProcess",
    "threadName": "MainThread"
}

An exception logged with logger.exception(e) has these:

{
    "asctime": "2020-10-21 10:43:25,193",
    "filename": "test.py",
    "funcName": "test_this",
    "levelname": "ERROR",
    "levelno": 40,
    "lineno": 17,
    "module": "test",
    "message": "this is a demo exception",
    "name": "logzero",
    "pathname": "_tests/test.py",
    "process": 76192,
    "processName": "MainProcess",
    "threadName": "MainThread",
    "exc_info": "Traceback (most recent call last):\n  File \"_tests/test.py\", line 15, in test_this\n    raise Exception(\"this is a demo exception\")\nException: this is a demo exception"
}

Advanced usage examples

Here are more examples which show how to use logfiles, custom formatters and setting a minimum loglevel.

Outcome Method
Set a minimum log level logzero.loglevel(..)
Add logging to a logfile logzero.logfile(..)
Setup a rotating logfile logzero.logfile(..)
Disable logging to a logfile logzero.logfile(None)
JSON logging logzero.json(...)
Log to syslog logzero.syslog(...)
Use a custom formatter logzero.formatter(..)
import logging
import logzero
from logzero import logger

# This log message goes to the console
logger.debug("hello")

# Set a minimum log level
logzero.loglevel(logzero.INFO)

# Set a logfile (all future log messages are also saved there)
logzero.logfile("/tmp/logfile.log")

# Set a logfile (all future log messages are also saved there), but disable the default stderr logging
logzero.logfile("/tmp/logfile.log", disableStderrLogger=True)

# You can also set a different loglevel for the file handler
logzero.logfile("/tmp/logfile.log", loglevel=logzero.ERROR)

# Set a rotating logfile (replaces the previous logfile handler)
logzero.logfile("/tmp/rotating-logfile.log", maxBytes=1000000, backupCount=3)

# Disable logging to a file
logzero.logfile(None)

# Enable JSON log format
logzero.json()

# Disable JSON log format
logzero.json(False)

# Log to syslog, using default logzero logger and 'user' syslog facility
logzero.syslog()

# Log to syslog, using default logzero logger and 'local0' syslog facility
logzero.syslog(facility=SysLogHandler.LOG_LOCAL0)

# Set a custom formatter
formatter = logging.Formatter('%(name)s - %(asctime)-15s - %(levelname)s: %(message)s');
logzero.formatter(formatter)

# Log some variables
logger.info("var1: %s, var2: %s", var1, var2)

Custom logger instances

Instead of using the default logger you can also setup specific logger instances with logzero.setup_logger(..):

from logzero import setup_logger
logger1 = setup_logger(name="mylogger1")
logger2 = setup_logger(name="mylogger2", logfile="/tmp/test-logger2.log", level=logzero.INFO)
logger3 = setup_logger(name="mylogger3", logfile="/tmp/test-logger3.log", level=logzero.INFO, disableStderrLogger=True)

# Log something:
logger1.info("info for logger 1")
logger2.info("info for logger 2")

# log to a file only, excluding the default stderr logger
logger3.info("info for logger 3")

# JSON logging in a custom logger
jsonLogger = setup_logger(name="jsonLogger", json=True)
jsonLogger.info("info in json")

Adding custom handlers (eg. SocketHandler)

Since logzero uses the standard Python logger object, you can attach any Python logging handlers you can imagine!

This is how you add a SocketHandler:

import logzero
import logging
from logging.handlers import SocketHandler

# Setup the SocketHandler
socket_handler = SocketHandler(address=('localhost', logging.DEFAULT_TCP_LOGGING_PORT))
socket_handler.setLevel(logzero.DEBUG)
socket_handler.setFormatter(logzero.LogFormatter(color=False))

# Attach it to the logzero default logger
logzero.logger.addHandler(socket_handler)

# Log messages
logzero.logger.info("this is a test")

Documentation

logzero.logger

logzero.logger is an already set up standard Python logger instance for your convenience. You can use it from all your files and modules directly like this:

from logzero import logger

logger.debug("hello")
logger.info("info")
logger.warning("warning")
logger.error("error")

You can reconfigure the default logger globally with logzero.setup_default_logger(..).

See the documentation for the Python logger instance for more information about how you can use it.

logzero.loglevel(..)

.. autofunction:: logzero.loglevel

logzero.logfile(..)

.. autofunction:: logzero.logfile

logzero.formatter(..)

.. autofunction:: logzero.formatter

logzero.setup_logger(..)

.. autofunction:: logzero.setup_logger

Default Log Format

This is the default log format string:

DEFAULT_FORMAT = '%(color)s[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d]%(end_color)s %(message)s'

See also the Python LogRecord attributes you can use.

Custom Formatting

It is easy to use a custom formatter / a custom log format string:

  • Define your log format string (you can use any of the LogRecord attributes).
  • Create a Formatter object (based on logzero.LogFormatter to get all the encoding helpers).
  • Supply the formatter object to the formatter argument in the setup_logger(..) method.

This is a working example on how to setup logging with a custom format:

import logzero

log_format = '%(color)s[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d]%(end_color)s %(message)s'
formatter = logzero.LogFormatter(fmt=log_format)
logzero.setup_default_logger(formatter=formatter)

Issues, Feedback & Contributions

All kinds of feedback and contributions are welcome.