1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5from __future__ import absolute_import, unicode_literals 6 7import logging 8 9 10class LoggingMixin(object): 11 """Provides functionality to control logging.""" 12 13 def populate_logger(self, name=None): 14 """Ensure this class instance has a logger associated with it. 15 16 Users of this mixin that call log() will need to ensure self._logger is 17 a logging.Logger instance before they call log(). This function ensures 18 self._logger is defined by populating it if it isn't. 19 """ 20 if hasattr(self, '_logger'): 21 return 22 23 if name is None: 24 name = '.'.join([self.__module__, self.__class__.__name__]) 25 26 self._logger = logging.getLogger(name) 27 28 def log(self, level, action, params, format_str): 29 """Log a structured log event. 30 31 A structured log event consists of a logging level, a string action, a 32 dictionary of attributes, and a formatting string. 33 34 The logging level is one of the logging.* constants, such as 35 logging.INFO. 36 37 The action string is essentially the enumeration of the event. Each 38 different type of logged event should have a different action. 39 40 The params dict is the metadata constituting the logged event. 41 42 The formatting string is used to convert the structured message back to 43 human-readable format. Conversion back to human-readable form is 44 performed by calling format() on this string, feeding into it the dict 45 of attributes constituting the event. 46 47 Example Usage 48 ------------- 49 50 self.log(logging.DEBUG, 'login', {'username': 'johndoe'}, 51 'User login: {username}') 52 """ 53 self._logger.log(level, format_str, 54 extra={'action': action, 'params': params}) 55