loguru icon indicating copy to clipboard operation
loguru copied to clipboard

How do I change the default display format of the logger

Open stevenhubhub opened this issue 1 year ago • 12 comments

I like this powerful module very much, it is very simple to use, but I am having some trouble customizing the display format, I want to remove the main part of the default display, I tried add(), but if I set it to cause duplication of output information, I do not know how to solve, I use loguru in a multi-process program.

image

If I try to customize the display format in either of the following ways, I get repeated messages in my multiprocess program, no matter what level it is: logger.add(sys.stdout, colorize=True, format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> | <level>{message}</level>") or logger.add(sys.stderr, format="{time} {level} {message}")

stevenhubhub avatar Jun 25 '23 12:06 stevenhubhub

Hi @stevenhubhub. Did you try first to remove() the default handler? This should avoid duplicated output.

Delgan avatar Jun 25 '23 12:06 Delgan

Hi @stevenhubhub. Did you try first to remove() the default handler? This should avoid duplicated output.

Thanks for your reply, very helpful! However, I had another problem, I wanted to manually set different colors for different information levels, and here is my code, I found that after setting this, the WARING category message would repeat again, for some reason: logger.remove()

    logger.add(stdout, level='INFO', colorize=True,
               format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<w>{level}</w>-{message}")
    logger.add(stdout, level='DEBUG', colorize=True,
               format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<le>{level}</le>-{message}")
    logger.add(stdout, level='SUCCESS', colorize=True,
               format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<g>{level}</g>--{message}")
    logger.add(stdout, level='WARNING', colorize=True,
               format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<y>{level}</y>--{message}")
    logger.add(stdout, level='ERROR', colorize=True,

             format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<r>{level}</r>--{message}")

Screenshot_2023-06-26-18-48-58-99_320a9a695de7cdce83ed5281148d6f19.jpg

image

stevenhubhub avatar Jun 26 '23 08:06 stevenhubhub

I don't advise to add() multiple handlers logging to stdout. You should have only one configured handler for stdout.

You're seeing repeated WARNING message because each time logger.warning() is called, the log message is processed by all handlers with a threshold level lower than WARNING. That is, the handler you added with level="DEBUG" will process all message with severity DEBUG or above.

If you want to change the default colors, I suggest you use the level() function instead:

logger.level("WARNING", color="<blue>")

Delgan avatar Jun 26 '23 17:06 Delgan

I don't advise to add() multiple handlers logging to stdout. You should have only one configured handler for stdout.

You're seeing repeated WARNING message because each time logger.warning() is called, the log message is processed by all handlers with a threshold level lower than WARNING. That is, the handler you added with level="DEBUG" will process all message with severity DEBUG or above.

If you want to change the default colors, I suggest you use the level() function instead:

logger.level("WARNING", color="<blue>")

Oh! Thanks for details and basic teaching. I got it, I will try the level()!

stevenhubhub avatar Jun 26 '23 23:06 stevenhubhub

hey @stevenhubhub! I think this issue can be closed if it is solved for you.

goyalyashpal avatar Aug 10 '23 14:08 goyalyashpal

earlier i was going to add my answer at SO, but now i have decided to paste it here...


All the examples here are concerned with stdlib's logging module; so, this answer is for those facing it with external loguru module.

Distribution code common to all following MWE's:

import sys                      # stdlib
from loguru import logger       # external

# fmt = "<green>{time}</green> <level>{message}</level>"
sh_fmt = "<level>{message}</level>"

The better format is fmt above, but for illustration purposes; 'will use a shorter one.

  1. Buggy Code
    Erraneous double logging code:
    This code is took from: loguru overview
logger.add(sys.stderr, level="INFO", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 18:04:43.004 | INFO     | __main__:<module>:6 - STOP using stdout (print) for debgging!
STOP using stdout (print) for debgging!
  1. Trial-&-Error
    Changing logger level, or equivalently only for this demo, remove the logger.add() entirely
logger.add(sys.stderr,level="WARNING", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 17:32:21.206 | INFO     | __main__:main:12 - STOP using stdout (print) for debgging!
  1. Cause:
    Wrong method to define logger level & format.

  2. Fix:
    (with correct way to )

import sys

from loguru import logger

logger.configure(handlers=[{"sink": sys.stderr, "format": "<level>{message}</level>"}])
logger.level("WARNING")         # Edit: It just fetches info, not configures

logger.info("STOP using stdout (print) for debgging!")
STOP using stdout (print) for debgging!

goyalyashpal avatar Aug 10 '23 16:08 goyalyashpal

earlier i was going to add my answer at SO, but now i have decided to paste it here...


All the examples here are concerned with stdlib's logging module; so, this answer is for those facing it with external loguru module.

Distribution code common to all following MWE's:

import sys                      # stdlib
from loguru import logger       # external

# fmt = "<green>{time}</green> <level>{message}</level>"
sh_fmt = "<level>{message}</level>"

The better format is fmt above, but for illustration purposes; 'will use a shorter one.

  1. Buggy Code
    Erraneous double logging code:
    This code is took from: loguru overview
logger.add(sys.stderr, level="INFO", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 18:04:43.004 | INFO     | __main__:<module>:6 - STOP using stdout (print) for debgging!
STOP using stdout (print) for debgging!
  1. Trial-&-Error
    Changing logger level, or equivalently only for this demo, remove the logger.add() entirely
logger.add(sys.stderr,level="WARNING", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 17:32:21.206 | INFO     | __main__:main:12 - STOP using stdout (print) for debgging!
  1. Cause:
    Wrong method to define logger level & format.

  2. Fix:
    (with correct way to )

import sys

from loguru import logger

logger.configure(handlers=[{"sink": sys.stderr, "format": "<level>{message}</level>"}])
logger.level("WARNING")         # Edit: It just fetches info, not configures

logger.info("STOP using stdout (print) for debgging!")
STOP using stdout (print) for debgging!

Thanks for those helpful details!

stevenhubhub avatar Aug 18 '23 20:08 stevenhubhub

Hi @stevenhubhub. Did you try first to remove() the default handler? This should avoid duplicated output.

Hi @Delgan, would you please be so kind as to add information about the default handler in the README or documentation? Many loguru users I know have been confused by the default behavior when using loguru for the first time (e.g. mixed stderr/stdout, duplicated handler adding, etc.).

dichen-cd avatar Oct 30 '23 06:10 dichen-cd

@dichen-cd There is a note about this in the Readme:

Note that you may also remove() a previously added handler by using the identifier returned while adding it. This is particularly useful if you want to supersede the default stderr handler: just call logger.remove() to make a fresh start.

What improvement or clarification would you suggest? Should I also mention hat calling remove() will avoid duplicated output?

Delgan avatar Oct 30 '23 18:10 Delgan

@dichen-cd There is a note about this in the Readme:

Note that you may also remove() a previously added handler by using the identifier returned while adding it. This is particularly useful if you want to supersede the default stderr handler: just call logger.remove() to make a fresh start.

What improvement or clarification would you suggest? Should I also mention hat calling remove() will avoid duplicated output?

It's not about the remove() method itself, but rather about the (to be) removed handler. Users typically have no knowledge of this default handler, such as where it pipes to, what format it uses, or whether the message has color, etc. Without such knowledge, a safe practice is to manually add a stdout/stderr handler, which can result in duplicated message output. Therefore, I believe it would be beneficial to inform users about the default handler that is automatically created when importing loguru.

dichen-cd avatar Nov 01 '23 07:11 dichen-cd

@dichen-cd Hum, the default handler is mentioned twice:

For convenience, it is pre-configured and outputs to stderr to begin with

And bellow:

This is particularly useful if you want to supersede the default stderr handler

Please let me know how I should rephrase it t make it more explicit.

Delgan avatar Nov 01 '23 08:11 Delgan

I think it would be useful to add the logger.add(...) line that would reproduce the default sink. That would allow users to use it as a baseline for replacing it with customized sinks.

penenkel avatar Jul 26 '24 14:07 penenkel