Skip to content

Instantly share code, notes, and snippets.

@glenfant
Last active November 11, 2021 14:08
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save glenfant/4358668 to your computer and use it in GitHub Desktop.
Save glenfant/4358668 to your computer and use it in GitHub Desktop.
A example of logging medium complex configuration using YAML on Python 2.7 or 3.2
# -*- coding: utf-8
"""\
A simple demo of logging configuration with YAML (Python 2.7)
=============================================================
Requires PyYAML -> "easy_install PyYAML"
See the recipes for configuring logging with dicts and YAML
- http://docs.python.org/2.7/howto/logging-cookbook.html
- http://stackoverflow.com/questions/10519392/python2-7-logging-configuration-with-yaml
"""
import logging
import logging.config
import yaml
import StringIO
# Should be a config file in real app
YAML_CONF = """\
%YAML 1.2
---
# Config for my application
# --------------------------
myapp:
foo: bar
bar: [1, 2]
# Config for logging
# ------------------
# See http://docs.python.org/2.7/library/logging.config.html#configuration-dictionary-schema
logging:
version: 1
disable_existing_loggers: true
# Configuring the default (root) logger is highly recommended
root:
level: !!python/name:logging.NOTSET
handlers: [console]
loggers:
# Logging from my application
myapp.lib:
level: !!python/name:logging.WARN
handlers: [logfile]
qualname: myapp.lib
propagate: false
myapp.cli:
level: !!python/name:logging.WARN
handlers: [console]
qualname: myapp.cli
propagate: false
# Controlling logging of 3rd party libs
sqlalchemy.engine:
level: !!python/name:logging.WARN
handlers: [logfile]
qualname: sqlalchemy.engine
propagate: false
sqlalchemy.pool:
level: !!python/name:logging.WARN
handlers: [logfile]
qualname: sqlalchemy.pool
propagate: false
handlers:
logfile:
class: logging.FileHandler
filename: sample.log
formatter: simpleFormatter
level: !!python/name:logging.NOTSET
console:
class: logging.StreamHandler
stream: ext://sys.stdout
formatter: simpleFormatter
level: !!python/name:logging.NOTSET
formatters:
simpleFormatter:
class: !!python/name:logging.Formatter
format: '%(name)s %(asctime)s %(levelname)s %(message)s'
datefmt: '%d/%m/%Y %H:%M:%S'
"""
# Loading config. Of course this is in another file in the real life
global_config = yaml.load(StringIO.StringIO(YAML_CONF))
# Configuring logging with the subset of the dict
#
logging.config.dictConfig(global_config['logging'])
# Using explicitely the root logger always logs to the console
logging.info("This is an info of the root logger")
# The unconfigured loggers are captured by the root logger (-> console)
unconfigured_logger = logging.getLogger('unconfigured')
unconfigured_logger.info("This is an info from an unknown / unconfigured source")
# Logging from myapp.cli
myapp_cli_logger = logging.getLogger('myapp.cli')
myapp_cli_logger.info("This is an info from myapp.cli") # Not recorded
myapp_cli_logger.warning("This is a warning from myapp.cli") # -> console
# Logging from myapp.lib
myapp_lib_logger = logging.getLogger('myapp.lib')
myapp_lib_logger.info("This is an info from myapp.lib") # Not recorded
myapp_lib_logger.warning("This is a warning from myapp.lib") # -> sample.log
# Controlling logs from 3rd party libs
sqla_logger = logging.getLogger('sqlalchemy.engine')
sqla_logger.info("This is an info from SQLAlchemy") # Not recorded
sqla_logger.warning("This is a warning from SQLAlchemy") # -> sample.log
print "Now look at the file 'sample.log'"
@adamailru
Copy link

great example !

but you repeated twice the same link
http://docs.python.org/2.7/howto/logging-cookbook.html ;)

@glenfant
Copy link
Author

glenfant commented Jan 6, 2015

Thanks for this. I removed the noise.

@ipmcc
Copy link

ipmcc commented May 26, 2016

For future readers: The qualname key does not apply to dictionary-based configuration. It's only relevant to the fileConfig method, which uses the ConfigParser/.ini file configuration method. It doesn't cause a problem in this example because the qualnames are always the same as the dictionary key (which is what's actually used with dictionary-based config), but if you try to use a shorthand name for the dictionary key and then use a real/qualified name in qualname, your configured logger will not be picked up at runtime.

@pypeach
Copy link

pypeach commented May 10, 2018

Thank you from japan.

@doowonee
Copy link

doowonee commented Jul 7, 2018

Thank youso much. It was totally helpful from Korea.

@Olegt0rr
Copy link

Olegt0rr commented Oct 8, 2018

What about custom filters?

@rochamorelli
Copy link

@Olegt0rr
Please, check my comment at this other gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment