Last active
November 11, 2021 14:08
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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'" |
Thanks for this. I removed the noise.
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 qualname
s 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.
Thank you from japan.
Thank youso much. It was totally helpful from Korea.
What about custom filters?
@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
great example !
but you repeated twice the same link
http://docs.python.org/2.7/howto/logging-cookbook.html ;)