Created
February 26, 2014 21:19
-
-
Save acdha/9238791 to your computer and use it in GitHub Desktop.
Revisions
-
acdha revised this gist
Feb 26, 2014 . 1 changed file with 4 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -17,7 +17,8 @@ def filter(self, record): return True @staticmethod def sanitize_dict(d): if not isinstance(d, dict): return d @@ -35,7 +36,8 @@ 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) -
acdha created this gist
Feb 26, 2014 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,56 @@ #!/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 def sanitize_dict(self, 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'): res += '\n\t' + pformat(record.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})