risclog.logging


Namerisclog.logging JSON
Version 1.3.1 PyPI version JSON
download
home_pagehttps://github.com/risclog-solution/risclog.logging
SummaryA logger based on structlog
upload_time2025-09-08 07:17:29
maintainerNone
docs_urlNone
authorriscLOG Solution GmbH
requires_python>=3.8
licenseMIT license
keywords risclog.logging
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ===================
risclog.logging
===================

.. image:: https://github.com/risclog-solution/risclog.logging/actions/workflows/test.yml/badge.svg
   :target: https://github.com/risclog-solution/risclog.logging/actions/workflows/test.yml
   :alt: CI Status

.. image:: https://img.shields.io/pypi/v/risclog.logging.svg
   :target: https://pypi.python.org/pypi/risclog.logging

The **risclog.logging** package provides a comprehensive solution for structured logging in Python
applications. It combines Python’s built-in logging module with [structlog](https://www.structlog.org/)
to generate detailed and formatted log entries. In this new release, the API has been updated to use:

- **`getLogger`** – the new factory function for creating logger instances (the legacy ``get_logger`` is deprecated).
- **`log_decorator`** – a decorator for automatic logging of function calls, including arguments, return values,
  durations, and exceptions.
- **Rich Traceback Integration** – by default, the package installs a beautiful exception renderer via:

  .. code-block:: python

      from rich import traceback
      traceback.install()

Features
========

- **Structured logging:** Combines standard logging with structlog for rich, contextual logs.
- **Synchronous and asynchronous logging:** Use the same API in both sync and async environments.
- **Automatic function logging:** Use the ``log_decorator`` to automatically log function calls and errors.
- **Email notifications:** Optionally send email notifications on exceptions (requires setting specific environment variables).
- **Rich traceback:** Enhanced exception display is provided by default via Rich.
- **Flexible configuration:** Programmatically set log levels and add handlers (e.g. file handlers).

Installation
============

Install via pip:

.. code-block:: bash

    pip install risclog.logging

Configuration and Usage
=======================

Creating a Logger
-----------------

Use the new ``getLogger`` function to obtain a logger. (Note that the old ``get_logger`` is now deprecated.)

.. code-block:: python

    from risclog.logging import getLogger

    logger = getLogger(__name__)
    logger.set_level("DEBUG")  # You can pass a string (e.g. "DEBUG") or a logging constant (logging.DEBUG)

You can also add a file handler to write warnings and above to a file:

.. code-block:: python

    file_logger = logger.add_file_handler('test.log', level=logging.WARNING)

Logging Messages
----------------

Log messages synchronously:

.. code-block:: python

    logger.debug("This is a debug message")
    logger.info("This is an info message")
    logger.warning("This is a warning message")
    logger.error("This is an error message")
    logger.critical("This is a critical message")

Or asynchronously (e.g. within async functions):

.. code-block:: python

    await logger.debug("Async debug message")
    await logger.info("Async info message")
    # etc.

Automatic Function Logging with Decorators
--------------------------------------------

The ``log_decorator`` automatically logs function calls (including arguments, execution time, results,
and any exceptions). It works with both synchronous and asynchronous functions.

.. code-block:: python

    from risclog.logging import getLogger, log_decorator
    import asyncio

    logger = getLogger(__name__)
    logger.set_level("DEBUG")

    @log_decorator
    def sync_function(a, b):
        result = a + b
        return result

    @log_decorator
    async def async_function(a, b):
        await asyncio.sleep(1)
        result = a + b
        return result

Using the Decorator in Classes
------------------------------

You can use the decorator on class methods as well. For example:

.. code-block:: python

    from risclog.logging import getLogger, log_decorator
    import asyncio

    class AwesomeClass:
        def __init__(self):
            self.logger = getLogger("AwesomeLogger")

        @log_decorator
        def class_sync_add(self, a: int, b: int):
            self.logger.warn("Debugging class_sync_add", a=a, b=b)
            self.logger.info("Information in class_sync_add", a=a, b=b)
            self.logger.info("class_sync_add called", a=a, b=b)
            return a + b

        @log_decorator
        async def class_async_add(self, a: int, b: int, c: dict):
            await self.logger.info("class_async_add called", a=a, b=b)
            await self.logger.info("Dependency class name:", c=c['dependency'].__class__.__name__)
            await asyncio.sleep(1)
            result = a + b
            await self.logger.info("class_async_add result", result=result)
            return result

    class DependencyClass:
        pass

Email Notification on Exceptions
---------------------------------

To enable email notifications when an exception occurs, pass ``send_email=True`` to the decorator.
**Remember:** The following environment variables must be set:

- ``logging_email_smtp_user``
- ``logging_email_smtp_password``
- ``logging_email_to``
- ``logging_email_smtp_server``

.. code-block:: python

    @log_decorator(send_email=True)
    def function_with_exception():
        # Your code that might raise an exception
        ...

Rich Traceback Integration
---------------------------

The package now automatically installs a beautiful traceback handler via Rich:

.. code-block:: python

    from rich import traceback
    traceback.install()

This provides enhanced, colored, and more informative tracebacks when errors occur.

Full Example
============

Below is a complete example demonstrating the usage of the new logger, decorators, and asynchronous logging.

.. code-block:: python

    import asyncio
    import logging
    from risclog.logging import getLogger, log_decorator

    # Configure logger
    logger = getLogger(__name__)
    logger.set_level(logging.DEBUG)
    logger.add_file_handler('test.log', level=logging.WARNING)

    @log_decorator
    def sync_function(a, b):
        result = a + b
        return result

    @log_decorator
    async def async_function(a, b):
        await asyncio.sleep(1)
        result = a + b
        return result

    class AwesomeClass:
        def __init__(self):
            self.logger = getLogger("AwesomeLogger")

        @log_decorator
        def class_sync_add(self, a: int, b: int):
            self.logger.warn("Debugging class_sync_add", a=a, b=b)
            self.logger.info("Information in class_sync_add", a=a, b=b)
            self.logger.info("class_sync_add called", a=a, b=b)
            return a + b

        @log_decorator
        async def class_async_add(self, a: int, b: int, c: dict):
            await self.logger.info("class_async_add called", a=a, b=b)
            await self.logger.info("Dependency class name:", c=c['dependency'].__class__.__name__)
            await asyncio.sleep(1)
            result = a + b
            await self.logger.info("class_async_add result", result=result)
            return result

    class DependencyClass:
        pass

    @log_decorator
    def sample_function(*args, **kwargs):
        logger.debug("Debugging sample_function", args=args, kwargs=kwargs)
        logger.info("Called with args", args=args)
        logger.info("Called with kwargs", kwargs=kwargs)

        result = {'sum_args': sum(args) if args else 0, **kwargs}
        logger.info("Result", result=result)
        if result['sum_args'] > 5:
            logger.warning("Sum of arguments is greater than 5", sum=result['sum_args'])

        try:
            1 / 0
        except ZeroDivisionError:
            logger.error("Division by zero error occurred during calculation. Check the input values",
                         exc_info=True)
        return result

    @log_decorator
    def sample_critical_function(*args, **kwargs):
        logger.critical("Critical issue in sample_critical_function", args=args, kwargs=kwargs)
        raise RuntimeError("Simulated critical problem")

    async def main():
        dc = DependencyClass()
        ac = AwesomeClass()
        sync_result = sync_function(3, 5)
        await async_function(4, 6)
        ac.class_sync_add(6, 7)
        await ac.class_async_add(8, 9, {'dependency': dc})
        sample_function(1, 2, 3, name='Alice', age=30)

        try:
            sample_critical_function(10, 20)
        except RuntimeError:
            pass

    if __name__ == '__main__':
        logger.info("Starting main function")
        sync_result = sync_function(3, 5)
        asyncio.run(main())

        # Trigger an exception to test rich traceback formatting:
        raise ValueError("Test exception")

Example Output
==============

Below is an example output generated by running the new logger code:

.. code-block:: bash

    2025-02-07 13:23:18 [info     ] [4311754480 Decorator start: sync_function] [__main__] _function=sync_function _script=all_in_one.py args=('a:int=3', 'b:int=5') kwargs={}
    2025-02-07 13:23:18 [info     ] [4311754480 Decorator success: sync_function] [__main__] _function=sync_function _script=all_in_one.py duration=0.00044sec result=8
    2025-02-07 13:23:19 [info     ] [4311754480 Decorator start: sync_function] [__main__] _function=sync_function _script=all_in_one.py args=('a:int=3', 'b:int=5') kwargs={}
    2025-02-07 13:23:19 [info     ] [4311754480 Decorator success: sync_function] [__main__] _function=sync_function _script=all_in_one.py duration=0.01749sec result=8
    2025-02-07 13:23:19 [info     ] [4311755376 Decorator start: async_function] [__main__] _function=async_function _script=all_in_one.py args=('a:int=4', 'b:int=6') kwargs={}
    2025-02-07 13:23:20 [info     ] [4311755376 Decorator success: async_function] [__main__] _function=async_function _script=all_in_one.py duration=1.00177sec result=10
    2025-02-07 13:23:20 [info     ] [4312228144 Decorator start: class_sync_add] [__main__] _function=class_sync_add _script=all_in_one.py args=('self:AwesomeClass=<__main__.AwesomeClass object at 0x10310b110>', 'a:int=6', 'b:int=7') kwargs={}
    2025-02-07 13:23:20 [warning  ] [4312228144 Debugging class_sync_add] [AwesomeLogger] a=6 b=7
    2025-02-07 13:23:20 [info     ] [4312228144 Information in class_sync_add] [AwesomeLogger] a=6 b=7
    2025-02-07 13:23:20 [info     ] [4312228144 class_sync_add called] [AwesomeLogger] a=6 b=7
    2025-02-07 13:23:20 [info     ] [4312228144 Decorator success: class_sync_add] [__main__] _function=class_sync_add _script=all_in_one.py duration=0.00189sec result=13
    2025-02-07 13:23:20 [info     ] [4312228528 Decorator start: class_async_add] [__main__] _function=class_async_add _script=all_in_one.py args=('self:AwesomeClass=<__main__.AwesomeClass object at 0x10310b110>', 'a:int=8', 'b:int=9', "c:dict={'dependency': <__main__.DependencyClass object at 0x10310af90>}") kwargs={}
    2025-02-07 13:23:20 [info     ] [4312228528 class_async_add called] [AwesomeLogger] a=8 b=9
    2025-02-07 13:23:20 [info     ] [4312228528 dependency class name:] [AwesomeLogger] c=DependencyClass
    2025-02-07 13:23:21 [info     ] [4312228528 class_async_add result] [AwesomeLogger] result=17
    2025-02-07 13:23:21 [info     ] [4312228528 Decorator success: class_async_add] [__main__] _function=class_async_add _script=all_in_one.py duration=1.00326sec result=17
    2025-02-07 13:23:21 [info     ] [4312229040 Decorator start: sample_function] [__main__] _function=sample_function _script=all_in_one.py args=('args:int=1', 'kwargs:int=2', 'name:str=Alice', 'age:int=30') kwargs={'name': 'Alice', 'age': 30}
    2025-02-07 13:23:21 [debug    ] [4312229040 Debugging sample_function] [__main__] args=(1, 2, 3) kwargs={'name': 'Alice', 'age': 30}
    2025-02-07 13:23:21 [info     ] [4312229040 Called with args]  [__main__] args=(1, 2, 3)
    2025-02-07 13:23:21 [info     ] [4312229040 Called with kwargs] [__main__] kwargs={'name': 'Alice', 'age': 30}
    2025-02-07 13:23:21 [info     ] [4312229040 Result]            [__main__] result={'sum_args': 6, 'name': 'Alice', 'age': 30}
    2025-02-07 13:23:21 [warning  ] [4312229040 Sum of arguments is greater than 5] [__main__] sum=6
    2025-02-07 13:23:21 [error    ] [4312229040 Division by zero error occurred during calculation. Check the input values] [__main__]
    2025-02-07 13:23:21 [info     ] [4312229040 Decorator success: sample_function] [__main__] _function=sample_function _script=all_in_one.py duration=0.00297sec result={'sum_args': 6, 'name': 'Alice', 'age': 30}
    2025-02-07 13:23:21 [info     ] [4312158640 Decorator start: sample_critical_function] [__main__] _function=sample_critical_function _script=all_in_one.py args=('args:int=10', 'kwargs:int=20') kwargs={}
    2025-02-07 13:23:21 [critical ] [4312158640 Critical issue in sample_critical_function] [__main__] args=(10, 20) kwargs={}
    2025-02-07 13:23:21 [error    ] ('[4312158640 Decorator error in sample_critical_function]',) [__main__] _function=sample_critical_function _script=all_in_one.py error='Simuliertes kritisches Problem'

Running Tests
=============

To run the tests for this package, simply execute:

.. code-block:: bash

    ./pytest

Credits
=======

This package was created using Cookiecutter_ and the
`risclog-solution/risclog-cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`risclog-solution/risclog-cookiecutter-pypackage`: https://github.com/risclog-solution/risclog-cookiecutter-pypackage

Additional Notes
================

- The legacy functions ``get_logger`` and the method ``decorator`` are deprecated and will be removed in version 1.3.0.
- For advanced configuration (custom processors, multiple handlers, etc.), please refer to the documentation.
- The package automatically configures loggers to filter out excessive log messages from libraries like Uvicorn and asyncio.


==============================
Change log for risclog.logging
==============================


1.3.1 (2025-09-08)
==================

- Unify default log level and set it from DEBUG to WARNING.


1.3.0 (2025-02-06)
==================

- added `add_file_handler` method to add a file handler to a logger

- added `set_level` method to set the level of a logger

- Fix log decorator mixed async sync Problem

- old `decorator` function is now deprecated

- old `get_logger` function is now deprecated


1.2.1 (2024-09-20)
==================

- forward exceptions


1.2.0 (2024-09-19)
==================

- rename email environments


1.1.0 (2024-08-27)
==================

- Allow logging with multiple loggers in a single module.


1.0.2 (2024-08-06)
==================

- Fix CI status badge.


1.0.1 (2024-08-06)
==================

- Fix `classifiers` and README structure.


1.0 (2024-08-06)
================

* initial release

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/risclog-solution/risclog.logging",
    "name": "risclog.logging",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "risclog.logging",
    "author": "riscLOG Solution GmbH",
    "author_email": "info@risclog.de",
    "download_url": "https://files.pythonhosted.org/packages/5e/9b/a63f8282121aaf3bea8cd5ac7e306ebd21feafaffb7d21b178779c797a6b/risclog.logging-1.3.1.tar.gz",
    "platform": null,
    "description": "===================\nrisclog.logging\n===================\n\n.. image:: https://github.com/risclog-solution/risclog.logging/actions/workflows/test.yml/badge.svg\n   :target: https://github.com/risclog-solution/risclog.logging/actions/workflows/test.yml\n   :alt: CI Status\n\n.. image:: https://img.shields.io/pypi/v/risclog.logging.svg\n   :target: https://pypi.python.org/pypi/risclog.logging\n\nThe **risclog.logging** package provides a comprehensive solution for structured logging in Python\napplications. It combines Python\u2019s built-in logging module with [structlog](https://www.structlog.org/)\nto generate detailed and formatted log entries. In this new release, the API has been updated to use:\n\n- **`getLogger`** \u2013 the new factory function for creating logger instances (the legacy ``get_logger`` is deprecated).\n- **`log_decorator`** \u2013 a decorator for automatic logging of function calls, including arguments, return values,\n  durations, and exceptions.\n- **Rich Traceback Integration** \u2013 by default, the package installs a beautiful exception renderer via:\n\n  .. code-block:: python\n\n      from rich import traceback\n      traceback.install()\n\nFeatures\n========\n\n- **Structured logging:** Combines standard logging with structlog for rich, contextual logs.\n- **Synchronous and asynchronous logging:** Use the same API in both sync and async environments.\n- **Automatic function logging:** Use the ``log_decorator`` to automatically log function calls and errors.\n- **Email notifications:** Optionally send email notifications on exceptions (requires setting specific environment variables).\n- **Rich traceback:** Enhanced exception display is provided by default via Rich.\n- **Flexible configuration:** Programmatically set log levels and add handlers (e.g. file handlers).\n\nInstallation\n============\n\nInstall via pip:\n\n.. code-block:: bash\n\n    pip install risclog.logging\n\nConfiguration and Usage\n=======================\n\nCreating a Logger\n-----------------\n\nUse the new ``getLogger`` function to obtain a logger. (Note that the old ``get_logger`` is now deprecated.)\n\n.. code-block:: python\n\n    from risclog.logging import getLogger\n\n    logger = getLogger(__name__)\n    logger.set_level(\"DEBUG\")  # You can pass a string (e.g. \"DEBUG\") or a logging constant (logging.DEBUG)\n\nYou can also add a file handler to write warnings and above to a file:\n\n.. code-block:: python\n\n    file_logger = logger.add_file_handler('test.log', level=logging.WARNING)\n\nLogging Messages\n----------------\n\nLog messages synchronously:\n\n.. code-block:: python\n\n    logger.debug(\"This is a debug message\")\n    logger.info(\"This is an info message\")\n    logger.warning(\"This is a warning message\")\n    logger.error(\"This is an error message\")\n    logger.critical(\"This is a critical message\")\n\nOr asynchronously (e.g. within async functions):\n\n.. code-block:: python\n\n    await logger.debug(\"Async debug message\")\n    await logger.info(\"Async info message\")\n    # etc.\n\nAutomatic Function Logging with Decorators\n--------------------------------------------\n\nThe ``log_decorator`` automatically logs function calls (including arguments, execution time, results,\nand any exceptions). It works with both synchronous and asynchronous functions.\n\n.. code-block:: python\n\n    from risclog.logging import getLogger, log_decorator\n    import asyncio\n\n    logger = getLogger(__name__)\n    logger.set_level(\"DEBUG\")\n\n    @log_decorator\n    def sync_function(a, b):\n        result = a + b\n        return result\n\n    @log_decorator\n    async def async_function(a, b):\n        await asyncio.sleep(1)\n        result = a + b\n        return result\n\nUsing the Decorator in Classes\n------------------------------\n\nYou can use the decorator on class methods as well. For example:\n\n.. code-block:: python\n\n    from risclog.logging import getLogger, log_decorator\n    import asyncio\n\n    class AwesomeClass:\n        def __init__(self):\n            self.logger = getLogger(\"AwesomeLogger\")\n\n        @log_decorator\n        def class_sync_add(self, a: int, b: int):\n            self.logger.warn(\"Debugging class_sync_add\", a=a, b=b)\n            self.logger.info(\"Information in class_sync_add\", a=a, b=b)\n            self.logger.info(\"class_sync_add called\", a=a, b=b)\n            return a + b\n\n        @log_decorator\n        async def class_async_add(self, a: int, b: int, c: dict):\n            await self.logger.info(\"class_async_add called\", a=a, b=b)\n            await self.logger.info(\"Dependency class name:\", c=c['dependency'].__class__.__name__)\n            await asyncio.sleep(1)\n            result = a + b\n            await self.logger.info(\"class_async_add result\", result=result)\n            return result\n\n    class DependencyClass:\n        pass\n\nEmail Notification on Exceptions\n---------------------------------\n\nTo enable email notifications when an exception occurs, pass ``send_email=True`` to the decorator.\n**Remember:** The following environment variables must be set:\n\n- ``logging_email_smtp_user``\n- ``logging_email_smtp_password``\n- ``logging_email_to``\n- ``logging_email_smtp_server``\n\n.. code-block:: python\n\n    @log_decorator(send_email=True)\n    def function_with_exception():\n        # Your code that might raise an exception\n        ...\n\nRich Traceback Integration\n---------------------------\n\nThe package now automatically installs a beautiful traceback handler via Rich:\n\n.. code-block:: python\n\n    from rich import traceback\n    traceback.install()\n\nThis provides enhanced, colored, and more informative tracebacks when errors occur.\n\nFull Example\n============\n\nBelow is a complete example demonstrating the usage of the new logger, decorators, and asynchronous logging.\n\n.. code-block:: python\n\n    import asyncio\n    import logging\n    from risclog.logging import getLogger, log_decorator\n\n    # Configure logger\n    logger = getLogger(__name__)\n    logger.set_level(logging.DEBUG)\n    logger.add_file_handler('test.log', level=logging.WARNING)\n\n    @log_decorator\n    def sync_function(a, b):\n        result = a + b\n        return result\n\n    @log_decorator\n    async def async_function(a, b):\n        await asyncio.sleep(1)\n        result = a + b\n        return result\n\n    class AwesomeClass:\n        def __init__(self):\n            self.logger = getLogger(\"AwesomeLogger\")\n\n        @log_decorator\n        def class_sync_add(self, a: int, b: int):\n            self.logger.warn(\"Debugging class_sync_add\", a=a, b=b)\n            self.logger.info(\"Information in class_sync_add\", a=a, b=b)\n            self.logger.info(\"class_sync_add called\", a=a, b=b)\n            return a + b\n\n        @log_decorator\n        async def class_async_add(self, a: int, b: int, c: dict):\n            await self.logger.info(\"class_async_add called\", a=a, b=b)\n            await self.logger.info(\"Dependency class name:\", c=c['dependency'].__class__.__name__)\n            await asyncio.sleep(1)\n            result = a + b\n            await self.logger.info(\"class_async_add result\", result=result)\n            return result\n\n    class DependencyClass:\n        pass\n\n    @log_decorator\n    def sample_function(*args, **kwargs):\n        logger.debug(\"Debugging sample_function\", args=args, kwargs=kwargs)\n        logger.info(\"Called with args\", args=args)\n        logger.info(\"Called with kwargs\", kwargs=kwargs)\n\n        result = {'sum_args': sum(args) if args else 0, **kwargs}\n        logger.info(\"Result\", result=result)\n        if result['sum_args'] > 5:\n            logger.warning(\"Sum of arguments is greater than 5\", sum=result['sum_args'])\n\n        try:\n            1 / 0\n        except ZeroDivisionError:\n            logger.error(\"Division by zero error occurred during calculation. Check the input values\",\n                         exc_info=True)\n        return result\n\n    @log_decorator\n    def sample_critical_function(*args, **kwargs):\n        logger.critical(\"Critical issue in sample_critical_function\", args=args, kwargs=kwargs)\n        raise RuntimeError(\"Simulated critical problem\")\n\n    async def main():\n        dc = DependencyClass()\n        ac = AwesomeClass()\n        sync_result = sync_function(3, 5)\n        await async_function(4, 6)\n        ac.class_sync_add(6, 7)\n        await ac.class_async_add(8, 9, {'dependency': dc})\n        sample_function(1, 2, 3, name='Alice', age=30)\n\n        try:\n            sample_critical_function(10, 20)\n        except RuntimeError:\n            pass\n\n    if __name__ == '__main__':\n        logger.info(\"Starting main function\")\n        sync_result = sync_function(3, 5)\n        asyncio.run(main())\n\n        # Trigger an exception to test rich traceback formatting:\n        raise ValueError(\"Test exception\")\n\nExample Output\n==============\n\nBelow is an example output generated by running the new logger code:\n\n.. code-block:: bash\n\n    2025-02-07 13:23:18 [info     ] [4311754480 Decorator start: sync_function] [__main__] _function=sync_function _script=all_in_one.py args=('a:int=3', 'b:int=5') kwargs={}\n    2025-02-07 13:23:18 [info     ] [4311754480 Decorator success: sync_function] [__main__] _function=sync_function _script=all_in_one.py duration=0.00044sec result=8\n    2025-02-07 13:23:19 [info     ] [4311754480 Decorator start: sync_function] [__main__] _function=sync_function _script=all_in_one.py args=('a:int=3', 'b:int=5') kwargs={}\n    2025-02-07 13:23:19 [info     ] [4311754480 Decorator success: sync_function] [__main__] _function=sync_function _script=all_in_one.py duration=0.01749sec result=8\n    2025-02-07 13:23:19 [info     ] [4311755376 Decorator start: async_function] [__main__] _function=async_function _script=all_in_one.py args=('a:int=4', 'b:int=6') kwargs={}\n    2025-02-07 13:23:20 [info     ] [4311755376 Decorator success: async_function] [__main__] _function=async_function _script=all_in_one.py duration=1.00177sec result=10\n    2025-02-07 13:23:20 [info     ] [4312228144 Decorator start: class_sync_add] [__main__] _function=class_sync_add _script=all_in_one.py args=('self:AwesomeClass=<__main__.AwesomeClass object at 0x10310b110>', 'a:int=6', 'b:int=7') kwargs={}\n    2025-02-07 13:23:20 [warning  ] [4312228144 Debugging class_sync_add] [AwesomeLogger] a=6 b=7\n    2025-02-07 13:23:20 [info     ] [4312228144 Information in class_sync_add] [AwesomeLogger] a=6 b=7\n    2025-02-07 13:23:20 [info     ] [4312228144 class_sync_add called] [AwesomeLogger] a=6 b=7\n    2025-02-07 13:23:20 [info     ] [4312228144 Decorator success: class_sync_add] [__main__] _function=class_sync_add _script=all_in_one.py duration=0.00189sec result=13\n    2025-02-07 13:23:20 [info     ] [4312228528 Decorator start: class_async_add] [__main__] _function=class_async_add _script=all_in_one.py args=('self:AwesomeClass=<__main__.AwesomeClass object at 0x10310b110>', 'a:int=8', 'b:int=9', \"c:dict={'dependency': <__main__.DependencyClass object at 0x10310af90>}\") kwargs={}\n    2025-02-07 13:23:20 [info     ] [4312228528 class_async_add called] [AwesomeLogger] a=8 b=9\n    2025-02-07 13:23:20 [info     ] [4312228528 dependency class name:] [AwesomeLogger] c=DependencyClass\n    2025-02-07 13:23:21 [info     ] [4312228528 class_async_add result] [AwesomeLogger] result=17\n    2025-02-07 13:23:21 [info     ] [4312228528 Decorator success: class_async_add] [__main__] _function=class_async_add _script=all_in_one.py duration=1.00326sec result=17\n    2025-02-07 13:23:21 [info     ] [4312229040 Decorator start: sample_function] [__main__] _function=sample_function _script=all_in_one.py args=('args:int=1', 'kwargs:int=2', 'name:str=Alice', 'age:int=30') kwargs={'name': 'Alice', 'age': 30}\n    2025-02-07 13:23:21 [debug    ] [4312229040 Debugging sample_function] [__main__] args=(1, 2, 3) kwargs={'name': 'Alice', 'age': 30}\n    2025-02-07 13:23:21 [info     ] [4312229040 Called with args]  [__main__] args=(1, 2, 3)\n    2025-02-07 13:23:21 [info     ] [4312229040 Called with kwargs] [__main__] kwargs={'name': 'Alice', 'age': 30}\n    2025-02-07 13:23:21 [info     ] [4312229040 Result]            [__main__] result={'sum_args': 6, 'name': 'Alice', 'age': 30}\n    2025-02-07 13:23:21 [warning  ] [4312229040 Sum of arguments is greater than 5] [__main__] sum=6\n    2025-02-07 13:23:21 [error    ] [4312229040 Division by zero error occurred during calculation. Check the input values] [__main__]\n    2025-02-07 13:23:21 [info     ] [4312229040 Decorator success: sample_function] [__main__] _function=sample_function _script=all_in_one.py duration=0.00297sec result={'sum_args': 6, 'name': 'Alice', 'age': 30}\n    2025-02-07 13:23:21 [info     ] [4312158640 Decorator start: sample_critical_function] [__main__] _function=sample_critical_function _script=all_in_one.py args=('args:int=10', 'kwargs:int=20') kwargs={}\n    2025-02-07 13:23:21 [critical ] [4312158640 Critical issue in sample_critical_function] [__main__] args=(10, 20) kwargs={}\n    2025-02-07 13:23:21 [error    ] ('[4312158640 Decorator error in sample_critical_function]',) [__main__] _function=sample_critical_function _script=all_in_one.py error='Simuliertes kritisches Problem'\n\nRunning Tests\n=============\n\nTo run the tests for this package, simply execute:\n\n.. code-block:: bash\n\n    ./pytest\n\nCredits\n=======\n\nThis package was created using Cookiecutter_ and the\n`risclog-solution/risclog-cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`risclog-solution/risclog-cookiecutter-pypackage`: https://github.com/risclog-solution/risclog-cookiecutter-pypackage\n\nAdditional Notes\n================\n\n- The legacy functions ``get_logger`` and the method ``decorator`` are deprecated and will be removed in version 1.3.0.\n- For advanced configuration (custom processors, multiple handlers, etc.), please refer to the documentation.\n- The package automatically configures loggers to filter out excessive log messages from libraries like Uvicorn and asyncio.\n\n\n==============================\nChange log for risclog.logging\n==============================\n\n\n1.3.1 (2025-09-08)\n==================\n\n- Unify default log level and set it from DEBUG to WARNING.\n\n\n1.3.0 (2025-02-06)\n==================\n\n- added `add_file_handler` method to add a file handler to a logger\n\n- added `set_level` method to set the level of a logger\n\n- Fix log decorator mixed async sync Problem\n\n- old `decorator` function is now deprecated\n\n- old `get_logger` function is now deprecated\n\n\n1.2.1 (2024-09-20)\n==================\n\n- forward exceptions\n\n\n1.2.0 (2024-09-19)\n==================\n\n- rename email environments\n\n\n1.1.0 (2024-08-27)\n==================\n\n- Allow logging with multiple loggers in a single module.\n\n\n1.0.2 (2024-08-06)\n==================\n\n- Fix CI status badge.\n\n\n1.0.1 (2024-08-06)\n==================\n\n- Fix `classifiers` and README structure.\n\n\n1.0 (2024-08-06)\n================\n\n* initial release\n",
    "bugtrack_url": null,
    "license": "MIT license",
    "summary": "A logger based on structlog",
    "version": "1.3.1",
    "project_urls": {
        "Homepage": "https://github.com/risclog-solution/risclog.logging"
    },
    "split_keywords": [
        "risclog.logging"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "07f220e874bc3e525286d804ccf9274ec456b1a526e86234eab940e567a37180",
                "md5": "a5f3a9bd2eb2089efed708f98aea91b4",
                "sha256": "00cbca6bd76d145ecc3a7356da030d95125c5e71fd8453b9cb5e5ca9bd2e21e6"
            },
            "downloads": -1,
            "filename": "risclog.logging-1.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a5f3a9bd2eb2089efed708f98aea91b4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 16214,
            "upload_time": "2025-09-08T07:17:27",
            "upload_time_iso_8601": "2025-09-08T07:17:27.696099Z",
            "url": "https://files.pythonhosted.org/packages/07/f2/20e874bc3e525286d804ccf9274ec456b1a526e86234eab940e567a37180/risclog.logging-1.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5e9ba63f8282121aaf3bea8cd5ac7e306ebd21feafaffb7d21b178779c797a6b",
                "md5": "8feb0812a8117d58d010bff71123fdf8",
                "sha256": "e09c0f831d4ef30251a5d38c47eb38fce17b4962e93bba7f073e4806d2e75be0"
            },
            "downloads": -1,
            "filename": "risclog.logging-1.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "8feb0812a8117d58d010bff71123fdf8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 24783,
            "upload_time": "2025-09-08T07:17:29",
            "upload_time_iso_8601": "2025-09-08T07:17:29.285462Z",
            "url": "https://files.pythonhosted.org/packages/5e/9b/a63f8282121aaf3bea8cd5ac7e306ebd21feafaffb7d21b178779c797a6b/risclog.logging-1.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-08 07:17:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "risclog-solution",
    "github_project": "risclog.logging",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "risclog.logging"
}
        
Elapsed time: 2.49691s