123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- # Licensed under the Apache License, Version 2.0 (the "License"); you may
- # not use this file except in compliance with the License. You may obtain
- # a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- # License for the specific language governing permissions and limitations
- # under the License.
- import logging
- try:
- from pythonjsonlogger import jsonlogger
- except ImportError:
- jsonlogger = None
- DEFAULT_FORMAT = (
- "%(asctime)s [%(process)d] %(color)s%(levelname)-8.8s "
- "%(name)s: %(message)s%(color_stop)s"
- )
- DEFAULT_EXTRAS_FORMAT = (
- "%(asctime)s [%(process)d] %(color)s%(levelname)-8.8s "
- "%(name)s%(extras)s: %(message)s%(color_stop)s"
- )
- class ColorFormatter(logging.Formatter):
- """Colorizes log output"""
- # TODO(jd) Allow configuration
- LEVEL_COLORS = {
- logging.DEBUG: '\033[00;32m', # GREEN
- logging.INFO: '\033[00;36m', # CYAN
- logging.WARN: '\033[01;33m', # BOLD YELLOW
- logging.ERROR: '\033[01;31m', # BOLD RED
- logging.CRITICAL: '\033[01;31m', # BOLD RED
- }
- COLOR_STOP = '\033[0m'
- def add_color(self, record):
- if getattr(record, "_stream_is_a_tty", False):
- record.color = self.LEVEL_COLORS[record.levelno]
- record.color_stop = self.COLOR_STOP
- else:
- record.color = ""
- record.color_stop = ""
- def remove_color(self, record):
- del record.color
- del record.color_stop
- def format(self, record):
- self.add_color(record)
- s = super(ColorFormatter, self).format(record)
- self.remove_color(record)
- return s
- class ExtrasFormatter(logging.Formatter):
- """Formats extra keywords into %(extras)s placeholder.
- Any keywords passed to a logging call will be formatted into a
- "extras" string and included in a logging message.
- Example:
- logger.info('my message', extra='keyword')
- will cause an "extras" string of:
- [extra: keyword]
- to be inserted into the format in place of %(extras)s.
- The optional `keywords` argument must be passed into the init
- function to enable this functionality. Without it normal daiquiri
- formatting will be applied. Any keywords included in the
- `keywords` parameter will not be included in the "extras" string.
- Special keywords:
- keywords
- A set of strings containing keywords to filter out of the
- "extras" string.
- extras_template
- A format string to use instead of '[{0}: {1}]'
- extras_separator
- What string to "join" multiple "extras" with.
- extras_prefix and extras_suffix
- Strings which will be prepended and appended to the "extras"
- string respectively. These will only be prepended if the
- "extras" string is not empty.
- """
- def __init__(self,
- keywords=None,
- extras_template='[{0}: {1}]',
- extras_separator=' ',
- extras_prefix=' ',
- extras_suffix='',
- *args, **kwargs):
- self.keywords = set() if keywords is None else keywords
- self.extras_template = extras_template
- self.extras_separator = extras_separator
- self.extras_prefix = extras_prefix
- self.extras_suffix = extras_suffix
- super(ExtrasFormatter, self).__init__(*args, **kwargs)
- def add_extras(self, record):
- if not hasattr(record, '_daiquiri_extra_keys'):
- record.extras = ''
- return
- extras = self.extras_separator.join(
- self.extras_template.format(k, getattr(record, k))
- for k in record._daiquiri_extra_keys
- if k != '_daiquiri_extra_keys' and k not in self.keywords
- )
- if extras != '':
- extras = self.extras_prefix + extras + self.extras_suffix
- record.extras = extras
- def remove_extras(self, record):
- del record.extras
- def format(self, record):
- self.add_extras(record)
- s = super(ExtrasFormatter, self).format(record)
- self.remove_extras(record)
- return s
- class ColorExtrasFormatter(ColorFormatter, ExtrasFormatter):
- """Combines functionality of ColorFormatter and ExtrasFormatter."""
- def format(self, record):
- self.add_color(record)
- s = ExtrasFormatter.format(self, record)
- self.remove_color(record)
- return s
- TEXT_FORMATTER = ColorExtrasFormatter(fmt=DEFAULT_EXTRAS_FORMAT)
- if jsonlogger:
- JSON_FORMATTER = jsonlogger.JsonFormatter()
|