Created
February 26, 2014 21:19
-
-
Save acdha/9238791 to your computer and use it in GitHub Desktop.
Example of how to filter or apply custom formatting using Python's logging library
This file contains 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
#!/usr/bin/env python | |
# encoding: utf-8 | |
from pprint import pformat, pprint | |
import logging | |
class PasswordMaskingFilter(logging.Filter): | |
"""Demonstrate how to filter sensitive data:""" | |
def filter(self, record): | |
# The call signature matches string interpolation: args can be a tuple or a lone dict | |
if isinstance(record.args, dict): | |
record.args = self.sanitize_dict(record.args) | |
else: | |
record.args = tuple(self.sanitize_dict(i) for i in record.args) | |
return True | |
@staticmethod | |
def sanitize_dict(d): | |
if not isinstance(d, dict): | |
return d | |
if any(i for i in d.keys() if 'password' in i): | |
d = d.copy() # Ensure that we won't clobber anything critical | |
for k, v in d.items(): | |
if 'password' in k: | |
d[k] = '*** PASSWORD ***' | |
return d | |
class CustomFormatter(logging.Formatter): | |
def format(self, record): | |
res = super(CustomFormatter, self).format(record) | |
if hasattr(record, 'request'): | |
filtered_request = PasswordMaskingFilter.sanitize_dict(record.request) | |
res += '\n\t' + pformat(filtered_request, indent=4).replace('\n', '\n\t') | |
return res | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger() | |
logger.addFilter(PasswordMaskingFilter()) | |
for handler in logger.root.handlers: | |
# This is lazy and does only the minimum alteration necessary. It'd be better to use | |
# dictConfig / fileConfig to specify the full desired configuration from the start: | |
# http://docs.python.org/2/library/logging.config.html#dictionary-schema-details | |
handler.setFormatter(CustomFormatter(handler.formatter._fmt)) | |
logging.info('This is a simple message') | |
fake_request = {'path': '/foo/bar/', 'method': 'GET', 'username': 'test_user', 'password': 's00p3r s3kr1t'} | |
logging.info('basic request request: %(method)s %(path)s', fake_request) | |
logging.info('Dumped request: %r', fake_request) | |
logging.info('extra request: %(method)s %(path)s', fake_request, extra={'request': fake_request}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment