Loguru: What's the best way to use Loguru in a library?

Created on 12 Oct 2020  路  7Comments  路  Source: Delgan/loguru

Hiya, i'm making a Python library and would like to use Loguru instead of the standard logging library.
I can find advice on the latter approach, e.g. here, but how should i proceed with the former approach?

Most helpful comment

Hi!

If you plan to use loguru in a library, the main rule is to call logger.disable("my_library") and to not use .add() at all. The users of your library should be responsible of configuring the handlers themselves.

Thanks to .disable() they will not see any logs from your library except if they explicit ask for by using logger.enable("my_library").

All 7 comments

Hi!

If you plan to use loguru in a library, the main rule is to call logger.disable("my_library") and to not use .add() at all. The users of your library should be responsible of configuring the handlers themselves.

Thanks to .disable() they will not see any logs from your library except if they explicit ask for by using logger.enable("my_library").

Thanks, will do.
And should i make loguru a development dependency in the library ---i use Poetry for dependency management--- or a production dependency?
In the former case, the user's app will depend on loguru.

I guess you need to make it a production dependency, otherwise your users will get an ImportError when they try to use your library, right? Even if the logger output is disabled, the from loguru import logger and all logger.info("...") will still be present in your code.

Righto.
Thanks for your quick and helpful response.

While this issue is open I'll let myself in to ask another question that can be also summarized with "What's the best way to use Loguru in a...?", @Delgan:

Is there a best practice where to put the configuration code when using Loguru in a project that is not a library? Currently I just place it right next to the main function (or where ever else the init happens) for example like this:

def configure_logging() -> None:
    logger.remove()

    if s.LOG_JSON:
        fmt = "{message}"
        logger.add(sys.stderr, format=fmt, serialize=True, level=s.LOG_LEVEL)
    else:
        fmt = "<green>{time:HH:mm:ss}</green> <level>{level}</level> <cyan>{function}</cyan> {message} <dim>{extra}</dim>"
        logger.add(sys.stderr, colorize=True, format=fmt, level=s.LOG_LEVEL)

But maybe something like __init__.py is more suitable?

Hi @trallnag. I guess it depends on one's preferences. I can't find any source providing authoritative answer on this issue. I think it makes sense to have this function close to where the logger is initialized. I have rarely seen functions declared in the __init__.py, do you see any benefit?

In any case, I like to call configure_logging() inside a if __name__ == "__main__" block for two reasons:

  • This allows some functions of my application to be imported and reused by other projects without touching the logger.
  • This allows to configure the logger from command line arguments (like --verbose)

Although it may be a good idea to additionally import the configure_logger in a __init__.py in case one wants to use your application programmatically (like a library).

Thanks for the helpful answer, @Delgan. I considered putting the function into __init__.py (and calling it there) to ensure that the loguru is configured for the whole module. But your approach is more reasonable

Was this page helpful?
0 / 5 - 0 ratings

Related issues

volfco picture volfco  路  5Comments

zhouxiaomao picture zhouxiaomao  路  6Comments

AllanLRH picture AllanLRH  路  6Comments

oz123 picture oz123  路  4Comments

af6140 picture af6140  路  5Comments