Skip to main content

A Python logging helper module that allows multiple levels of debug logging

Project description

tiered-debug

PyPI - Version PyPI - Python Version


Table of Contents

Description

The class in this module provides a way to enable multiple tiers of debug logging. It's not doing anything fancy. It's just a wrapper around a standard logger.debug() call that caps the highest tier of debug logging to a value which can be set at class instantiation, or defaults to 1. It's a class attribute, .level, which can be set to any value between 1 and 5 at any time.

Installation

pip install -U tiered-debug

Usage

Basic

from tiered_debug import TieredDebug

# Establish a class instance
debug = TieredDebug()

# Set the debug level for this class instance
debug.set_level(3)

# Log messages from any module
debug.lv1("This will log")  # Logs because 1 <= 3
debug.lv3("This will log")  # Logs because 3 <= 3
debug.lv4("This won't log") # Doesn't log because 4 > 3

Best Practices

Make use of the sample debug.py module. Deploy it in your own project at the root level as-is and it should be usable:

from .debug import debug

debug.lv1("This will now log")

You can also use the @begin_end() decorator factory function to put BEGIN and END debug messages before and after the function or method runs:

from .debug import debug, begin_end

@begin_end()
def my_function():
    debug.lv1("This is in the function")

def other_function():
    my_function()

Advanced

Each "level" can manually override default settings using these keyword arguments:

def lv[1-5](self, msg: str, stklvl: t.Optional[StackLevel] = None) -> None:

These will simply default to self.stacklevel if no value for stklvl is given.

The ability to manually override the stacklevel, stack index number, and frame index number are in case you ever need to reference something that isn't caught by @wraps correctly, or make a custom decorator, or similar.

Decorator

The decorator can be applied like any other, but there's an interesting side effect to wrapping logging statements before and after a function or method:

from .debug import debug, begin_end

debug.set_level(3)


@begin_end()
def myfunction():
    debug.lv1("My function just executed")


def run():
    myfunction()

With these values, the first and last log lines output from myfunction() will look like this:

2025-04-15 13:23:27,046 DEBUG       mymodule          run:12   DEBUG2 BEGIN CALL: myfunction()
2025-04-15 13:23:27,046 DEBUG       mymodule   myfunction:8    DEBUG1 My function just executed
2025-04-15 13:23:27,046 DEBUG       mymodule          run:12   DEBUG3 END CALL: myfunction()

Note that the BEGIN CALL log line appears to have been logged by the run() function, then the log from myfunction(), then the END CALL line appears to have been logged by the run() function again, and both CALL lines appear to have come from the same line 12. What's going on?

Well, the decorator is wrapping our function in between those two debug.lv# calls, and so Python has lovingly decided to make those appear right where the call to myfunction() is made. It would be weird to add lines to the code, wouldn't it? So here, the decorator is doing the logical thing, which is to make it all happen right where the function is called.

Configuring the global stacklevel

The stacklevel parameter is passed to the logging.debug() function as the stacklevel argument. The stacklevel parameter is the stack level to use for the log message. The default value is 2, which means that the log message will appear to come from the caller of the caller each lv# method. In other words, if you call lv1() from a function, the log message will appear to come from that function rather than from lv1() or the TieredDebug class. If your log formatter is set up to include the module name, function name, and/or line of code in the log message, having the stacklevel properly set will ensure the correct data is displayed.

In the event that you use this module as part of another module or class, you may need to increase the stacklevel to 3. This can be done using the .stacklevel attribute. This will need to be done before any logging takes place.

License

tiered-debug is distributed under the terms of the Apache license.

©Copyright 2025 Aaron Mildenstein

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tiered_debug-1.1.0.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tiered_debug-1.1.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file tiered_debug-1.1.0.tar.gz.

File metadata

  • Download URL: tiered_debug-1.1.0.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for tiered_debug-1.1.0.tar.gz
Algorithm Hash digest
SHA256 be29ad3ab862dc6781d22f8b0dfa42d5d108959cafff61f2192bce795e3437d0
MD5 56be01936a9355a252bc22160b3c3e75
BLAKE2b-256 12b384ef3578f4d6ab88fe8abdf8a621db51cea6bbc237467b4c213ad56f435f

See more details on using hashes here.

File details

Details for the file tiered_debug-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: tiered_debug-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for tiered_debug-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e88dba9836b135b200d051fe085df455fde869d55e3365f7661989f7856c55d
MD5 5c5d1bfe7d690e0cc1c201a55e4adae0
BLAKE2b-256 b09ba360a87a4b841635b7b6c02e7f049568560b5f6feccdff4d09188ddcbfc4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page