51

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.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Trent
  • 2,328
  • 3
  • 33
  • 51

6 Answers6

80

The default format is located here which is:

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

The Format code 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
NirIzr
  • 3,131
  • 2
  • 30
  • 49
rh0dium
  • 6,811
  • 4
  • 46
  • 79
  • How do you know the BASIC_FORMAT attribute of logging? it is not mentioned in the document after all – iMath Dec 30 '16 at 12:09
  • 2
    I guess i'm a little late, but for the later generations you can look up in [python's source code here](https://github.com/python/cpython/blob/main/Lib/logging/__init__.py) 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. – Miguel Pinheiro Aug 28 '21 at 19:13
7
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.

Melebius
  • 6,183
  • 4
  • 39
  • 52
awhan
  • 510
  • 6
  • 13
4

@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
David Röthlisberger
  • 1,786
  • 15
  • 20
3

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"
Blender
  • 289,723
  • 53
  • 439
  • 496
2

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
Salem
  • 12,808
  • 4
  • 34
  • 54
  • 1
    Showing how to check the current formatter instead of the default in the source code is a better answer IMO. – jjj Nov 18 '16 at 18:20
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')
v.k
  • 141
  • 6