What is Python's default logging formatter?
Asked Answered
C

6

60

I'm trying to decipher the information contained in my logs (the logging setup is using the default formatter). The documentation states:

Do formatting for a record - if a formatter is set, use it. Otherwise, use the default formatter for the module.

However, I can't find any reference actually stating what this default format is.

Corpulence answered 26/5, 2013 at 8:41 Comment(2)
It does seem like the documentation should indicate that.Loaves
For reference, here is a list of the log message attributes that can be included in the format string.Timberhead
M
89

The default format is located here which is:

BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"  

The section on formatting in the python docs will tell you how you can customize it. Here is one example on how you can customize it.

import sys
import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s",
    datefmt="%d/%b/%Y %H:%M:%S",
    stream=sys.stdout)

logging.info("HEY")

Which results in:

[26/May/2013 06:41:40] INFO [root.<module>:1] HEY
Mazonson answered 26/5, 2013 at 13:42 Comment(2)
How do you know the BASIC_FORMAT attribute of logging? it is not mentioned in the document after allPolybasite
I guess i'm a little late, but for the later generations you can look up in python's source code here for the basicConfig method and see that it defaults to _STYLES[style][1] in fs = kwargs.pop("format", _STYLES[style][1]) if the format key is not present in the method. style defaults to "%" if not present in the basicConfig method. This gives us the format _STYLE["%"][1] = BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s". You could also just infer from the documentation.Collum
W
10
import logging
print(logging.BASIC_FORMAT)

Also some comments asked about how one could have come to discover this on their own. Here is a natural thing to do:

import logging
print(dir(logging))

BASIC_FORMAT is in there, in fact it is the first entry in the result in my case.

Wharfage answered 6/4, 2017 at 17:32 Comment(0)
S
7

@rh0dium's and @Blender's answers contradict each other but they're both correct... just incomplete.

As of Python 3.10:

  • If you create a handler without specifying a formatter, the default format is "%(message)s".
  • If you call logging.basicConfig it sets up a handler on the root logger with a formatter that defaults to "%(levelname)s:%(name)s:%(message)s".
    • Note that logging.info, logging.warning etc will automatically call logging.basicConfig() if you haven't called it already.
    • But calling the root logger directly (like logging.getLogger().info(...)) won't call logging.basicConfig().

So the actual behaviour depends on whether you've ever called logging.basicConfig or logging.info/logging.warning/etc.

$ python3
Python 3.10.4 (main, Apr  2 2022, 09:04:19) [GCC 11.2.0] on linux
>>> import logging
>>> root = logging.getLogger()
>>> root.warning("W")
W
>>> logging.warning("W")
WARNING:root:W
>>> root.warning("W")
WARNING:root:W
>>> mylogger = logging.getLogger("mylogger")
>>> mylogger.addHandler(logging.StreamHandler())
>>> mylogger.propagate = False
>>> mylogger.warning("W")
W
Strohben answered 29/6, 2022 at 12:15 Comment(1)
I get the same behaviour already with Python 3.8Leftward
D
5

It's in the source of logging/__init__.py:

_defaultFormatter = Formatter()

The default formatting string is %(message)s, which is in the source as well:

if fmt:
    self._fmt = fmt
else:
    self._fmt = "%(message)s"
Derogatory answered 26/5, 2013 at 8:52 Comment(0)
S
4

The default seems to be %(levelname)s:%(name)s:%(message)s

import logging
logging.error("Some error")
print "fmt: " , logging.root.handlers[0].formatter._fmt
# ERROR:root:Some error
# fmt:  %(levelname)s:%(name)s:%(message)s
Shackleton answered 26/5, 2013 at 9:35 Comment(1)
Showing how to check the current formatter instead of the default in the source code is a better answer IMO.Gan
B
0

Here is the example of an advanced way of logging:-

import logging
class logger_con():
   def log_test(self):
      """
        :create logger
        :set logger level
        :create console handler
        :add formatter to console handler
        :add console handler to logger
        :add logging massage
        :return:
      """
    #create logger and set level
    logger=logging.getLogger(logger_con.__name__)

    logger.setLevel(logging.INFO)

    #create console handler(we are using steamHandler which is only used to display log in console)

    con_handler=logging.StreamHandler()
    con_handler.setLevel(logging.INFO)

    #create formatter and add formatter to con_handler
    formatter=logging.Formatter('%(asctime)s : %(message)s : %(levelname)s -%(name)s',datefmt='%d%m%Y %I:%M:%S %p')
    con_handler.setFormatter(formatter)
    #add console handler to logger
    logger.addHandler(con_handler)

    logger.debug('Program debugging')
    logger.info('massage conatain information')
    logger.warning('warning message')
    logger.error('massage contains error')
    logger.critical('critical massages')
Billibilliard answered 12/5, 2019 at 1:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.