diff options
-rw-r--r-- | pylog/onaplogging/colorFormatter.py | 143 | ||||
-rw-r--r-- | pylog/onaplogging/marker/markerFactory.py | 4 | ||||
-rw-r--r-- | pylog/onaplogging/markerFormatter.py | 26 | ||||
-rw-r--r-- | pylog/onaplogging/mdcformatter.py | 27 |
4 files changed, 170 insertions, 30 deletions
diff --git a/pylog/onaplogging/colorFormatter.py b/pylog/onaplogging/colorFormatter.py new file mode 100644 index 0000000..a60e441 --- /dev/null +++ b/pylog/onaplogging/colorFormatter.py @@ -0,0 +1,143 @@ +# Copyright 2018 ke liang <lokyse@163.com>. +# +# 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 os +import sys +import logging +from logging import Formatter + + +ATTRIBUTES = { + 'normal': 0, + 'bold': 1, + 'underline': 4, + 'blink': 5, + 'invert': 7, + 'hide': 8, + +} + + +HIGHLIGHTS = { + + 'black': 40, + 'red': 41, + 'green': 42, + 'yellow': 43, + 'blue': 44, + 'purple': 45, + 'cyan': 46, + 'white': 47, +} + +COLORS = { + + 'black': 30, + 'red': 31, + 'green': 32, + 'yellow': 33, + 'blue': 34, + 'purple': 35, + 'cyan': 36, + 'white': 37, +} + +COLOR_TAG = "color" +HIGHLIGHT_TAG = "highlight" +ATTRIBUTE_TAG = "attribute" + +RESET = '\033[0m' + + +def colored(text, color=None, on_color=None, attrs=None): + # It can't support windows system cmd right now! + # TODO: colered output on windows system cmd + if os.name in ('nt', 'ce'): + return text + + if isinstance(attrs, str): + attrs = [attrs] + + if os.getenv('ANSI_COLORS_DISABLED', None) is None: + fmt_str = '\033[%dm%s' + if color is not None and isinstance(color, str): + text = fmt_str % (COLORS.get(color, 0), text) + + if on_color is not None and isinstance(on_color, str): + text = fmt_str % (HIGHLIGHTS.get(on_color, 0), text) + + if attrs is not None: + for attr in attrs: + text = fmt_str % (ATTRIBUTES.get(attr, 0), text) + + # keep origin color for tail spaces + text += RESET + return text + + +class BaseColorFormatter(Formatter): + + def __init__(self, fmt=None, datefmt=None, colorfmt=None, style="%"): + if sys.version_info > (3, 2): + super(BaseColorFormatter, self).__init__( + fmt=fmt, datefmt=datefmt, style=style) + elif sys.version_info > (2, 7): + super(BaseColorFormatter, self).__init__(fmt, datefmt) + else: + Formatter.__init__(self, fmt, datefmt) + + self.style = style + if sys.version_info > (3, 2): + if self.style not in logging._STYLES: + raise ValueError('Style must be one of: %s' % ','.join( + logging._STYLES.keys())) + + self.colorfmt = colorfmt + + print(self.colorfmt, isinstance(self.colorfmt, dict)) + + def _parseColor(self, record): + """ + color formatter for instance: + { + "logging-levelname": + { + "color":"<COLORS>", + "highlight":"<HIGHLIGHTS>", + "attribute":"<ATTRIBUTES>", + } + } + :param record: + :return: text color, background color, text attribute + """ + if self.colorfmt and isinstance(self.colorfmt, dict): + + level = record.levelname + colors = self.colorfmt.get(level, None) + + if colors is not None and isinstance(colors, dict): + return colors.get(COLOR_TAG, None), \ + colors.get(HIGHLIGHT_TAG, None), \ + colors.get(ATTRIBUTE_TAG, None) + + return None, None, None + + def format(self, record): + + if sys.version_info > (2, 7): + s = super(BaseColorFormatter, self).format(record) + else: + s = Formatter.format(self, record) + color, on_color, attribute = self._parseColor(record) + return colored(s, color, on_color, attrs=attribute) diff --git a/pylog/onaplogging/marker/markerFactory.py b/pylog/onaplogging/marker/markerFactory.py index deb9566..e7b00b9 100644 --- a/pylog/onaplogging/marker/markerFactory.py +++ b/pylog/onaplogging/marker/markerFactory.py @@ -51,12 +51,12 @@ class MarkerFactory(IMarkerFactory): if marker_name is None: raise ValueError("not empty") + lock.acquire() marker = self._marker_map.get(marker_name, None) if marker is None: - lock.acquire() marker = BaseMarker(name=marker_name) self._marker_map[marker_name] = marker - lock.release() + lock.release() return marker diff --git a/pylog/onaplogging/markerFormatter.py b/pylog/onaplogging/markerFormatter.py index f33bfc2..c9b0628 100644 --- a/pylog/onaplogging/markerFormatter.py +++ b/pylog/onaplogging/markerFormatter.py @@ -16,32 +16,28 @@ import sys import logging from marker import MARKER_TAG from marker import Marker +from colorFormatter import BaseColorFormatter -class MarkerFormatter(logging.Formatter): +class MarkerFormatter(BaseColorFormatter): - def __init__(self, fmt=None, datefmt=None, style='%'): + def __init__(self, fmt=None, datefmt=None, colorfmt=None, style='%'): if sys.version_info > (3, 2): super(MarkerFormatter, self).__init__( - fmt=fmt, datefmt=datefmt, style=style) + fmt=fmt, datefmt=datefmt, colorfmt=colorfmt, style=style) elif sys.version_info > (2, 7): super(MarkerFormatter, self).__init__( - fmt=fmt, datefmt=datefmt) + fmt=fmt, datefmt=datefmt, colorfmt=colorfmt) else: - logging.Formatter.__init__(self, fmt, datefmt) + BaseColorFormatter.__init__(self, fmt, datefmt, colorfmt) - self.style = style self._marker_tag = "%(marker)s" - if sys.version_info > (3, 2): - if self.style not in logging._STYLES: - raise ValueError('Style must be one of: %s' % - ','.join(logging._STYLES.keys())) - if self.style == "{": - self._marker_tag = "{marker}" - elif self.style == "$": - self._marker_tag = "${marker}" + if self.style == "{": + self._marker_tag = "{marker}" + elif self.style == "$": + self._marker_tag = "${marker}" self._tmpFmt = self._fmt @@ -66,7 +62,7 @@ class MarkerFormatter(logging.Formatter): if sys.version_info > (2, 7): return super(MarkerFormatter, self).format(record) else: - return logging.Formatter.format(self, record) + return BaseColorFormatter.format(self, record) finally: self._fmt = self._tmpFmt diff --git a/pylog/onaplogging/mdcformatter.py b/pylog/onaplogging/mdcformatter.py index 087497d..74ff894 100644 --- a/pylog/onaplogging/mdcformatter.py +++ b/pylog/onaplogging/mdcformatter.py @@ -23,32 +23,33 @@ class MDCFormatter(MarkerFormatter): to enrich log message. """ - def __init__(self, fmt=None, mdcfmt=None, datefmt=None, style="%"): + def __init__(self, fmt=None, mdcfmt=None, + datefmt=None, colorfmt=None, style="%"): """ :param fmt: build-in format string contains standard Python %-style mapping keys :param mdcFmt: mdc format with '{}'-style mapping keys :param datefmt: Date format to use + :param colorfmt: colored output with ANSI escape code on terminal :param style: style mapping keys in python3 """ if sys.version_info > (3, 2): - super(MDCFormatter, self).__init__(fmt=fmt, datefmt=datefmt, + super(MDCFormatter, self).__init__(fmt=fmt, + datefmt=datefmt, + colorfmt=colorfmt, style=style) elif sys.version_info > (2, 7): - super(MDCFormatter, self).__init__(fmt=fmt, datefmt=datefmt) + super(MDCFormatter, self).__init__(fmt=fmt, + datefmt=datefmt, + colorfmt=colorfmt) else: - MarkerFormatter.__init__(self, fmt, datefmt) + MarkerFormatter.__init__(self, fmt, datefmt, colorfmt) - self.style = style self._mdc_tag = "%(mdc)s" - if sys.version_info > (3, 2): - if self.style not in logging._STYLES: - raise ValueError('Style must be one of: %s' % ','.join( - logging._STYLES.keys())) - if self.style == "{": - self._mdc_tag = "{mdc}" - elif self.style == "$": - self._mdc_tag = "${mdc}" + if self.style == "{": + self._mdc_tag = "{mdc}" + elif self.style == "$": + self._mdc_tag = "${mdc}" if mdcfmt: self._mdcFmt = mdcfmt |