Delgan / loguru

Python logging made (stupidly) simple
MIT License
19.62k stars 695 forks source link

How to include all args in the logged record? #1134

Closed andreasciamanna closed 4 months ago

andreasciamanna commented 5 months ago

For an hour or so, I've been struggling to figure out how to include the current functions **args and **kwargs in the records.

Before moving to Loguru, I could see a data object in the JSON log entry containing all the arguments provided to the function.

Here, unless I use bind or contextualize (which are not meant to be used like that, in my opinion), I can't find how to tell the logger to simply always include this data.

I'm sure it is there in the docs. I just can't find where it is.

Delgan commented 5 months ago

Which version of Loguru are you using?

Only **kwargs are added to the extra dict, it's mentioned here in the docs:

Note that while calling a logging method, the keyword arguments (if any) are automatically added to the extra dict for convenient contextualization (in addition to being used for formatting).

andreasciamanna commented 5 months ago

Thanks.

Which version of Loguru are you using?

0.7.2, installed today for the first time

Only **kwargs are added to the extra dict, it's mentioned here in the docs:

Note that while calling a logging method, the keyword arguments (if any) are automatically added to the extra dict for convenient contextualization (in addition to being used for formatting).

Missed this part.

Still, other than what I add to bind and contextualize, **kwargs are not added.

This is how I configure the Loguru:

import logging
import os
import sys

from loguru import logger

class PropagateHandler(logging.Handler):
    def emit(self, record: logging.LogRecord) -> None:
        logging.getLogger(record.name).handle(record)

class AppLogger:
    def __init__(self):
        self.logger = logger

    def get_logger(self):
        return self.logger

logger.remove()
logger.add(sys.stdout, colorize=True, enqueue=True)

log_filename = "logs/app.log"
log_path = os.path.dirname(log_filename)
if log_path and not os.path.exists(log_path):
    logger.bind(log_path=log_path).info(
        "Creating log directory",
    )
    os.makedirs(log_path)

logger.add(
    "logs/app.log",
    rotation="1 hour",
    enqueue=True,
    serialize=True,
    retention="1 days",
    compression="zip",
)

logger.add(PropagateHandler())

The script is a bit messy because, until a few hours ago, I wasn't using Loguru: I was using Rich and other handlers instead.

Still, it should give an idea of how I have configured Loguru.

I would also like to understand how to include extra to sys.stdout, but that's less urgent.

Delgan commented 4 months ago

@andreasciamanna The code snippet you shared does not involve usage of **kwargs?

Try this and we should observe the extra being logged:

from loguru import logger

logger.remove()
logger.add(sys.stderr, format="{message} {extra}")

logger.info("Some message", data="foobar")
andreasciamanna commented 4 months ago

I think you both misunderstood my question.

I know I can pass parameters to the log functions.

However, using other loggers, I can have in extra all the current functions's arguments, out of the box, without having me to pass these information manually and remember to update them every time I change the signature of my functions.

Example:

def my_function(param1, param2, *, param3, param4):
     # do something
     logger.info("Log something")

The log entry will have param1, param2 as extra.args = [param1, param2] and extra.param3=value2+ extra.param4=value4. No additional code required by me.

In other words, no need to write something like logger.info("Log something", param1=param1, param2=param2, param3=param3, param4=param4).

Delgan commented 4 months ago

I'm not aware of such feature in the standard logging library. Is that a feature from Rich?

In any case, this is not possible using Loguru.

andreasciamanna commented 4 months ago

I'm not aware of such feature in the standard logging library. Is that a feature from Rich?

I guess so. I'm relatively new to Python, so I followed the various documents I found when I needed to implement a logging system and decided to use Rich. Probably, that feature came out of the box, because I don't remember having to do anything special.

In any case, this is not possible using Loguru.

I figured out that :)

I like Loguru's approach, but it's trying to reinvent a bit too much.

Considering that the standard logging library won't go away anytime soon and that the majority of the developers will be accustomed to it rather than other creative libraries (even if they have many valid good reasons to exist like Loguru), I think I'll return to the standard logging approach or libraries that use it.

It's hard, if not impossible, to integrate it properly with other tools (e.g., Celery: the little information I've found doesn't work correctly, and I have no more time to invest in that).

Maybe I'll try it again in future projects, even though I'll do everything in my power to stay as far as possible from Python.

Delgan commented 4 months ago

Thanks for the feedback, you're right to use the standard library if it suits you. :+1: