1 # Copyright 2018 ke liang <lokyse@163.com>.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 from .markerFormatter import MarkerFormatter
17 from .utils import is_above_python_2_7, is_above_python_3_2
20 class MDCFormatter(MarkerFormatter):
22 A custom MDC formatter to prepare Mapped Diagnostic Context
23 to enrich log message.
26 def __init__(self, fmt=None, mdcfmt=None,
27 datefmt=None, colorfmt=None, style="%"):
29 :param fmt: build-in format string contains standard
30 Python %-style mapping keys
31 :param mdcFmt: mdc format with '{}'-style mapping keys
32 :param datefmt: Date format to use
33 :param colorfmt: colored output with ANSI escape code on terminal
34 :param style: style mapping keys in python3
36 if is_above_python_3_2():
37 super(MDCFormatter, self).__init__(fmt=fmt,
41 elif is_above_python_2_7():
42 super(MDCFormatter, self).__init__(fmt=fmt,
46 MarkerFormatter.__init__(self, fmt, datefmt, colorfmt)
48 self._mdc_tag = "%(mdc)s"
50 self._mdc_tag = "{mdc}"
51 elif self.style == "$":
52 self._mdc_tag = "${mdc}"
57 self._mdcFmt = '{reqeustID}'
61 maximum barce match algorithm to find the mdc key
62 :return: key in brace and key not in brace,such as ({key}, key)
70 for index, v in enumerate(target):
81 keys.append(target[start:end + 1])
85 keys = list(filter(lambda x: x[1:-1].strip('\n \t ') != "", keys))
88 words = map(lambda x: x[1:-1], keys)
92 def _replaceStr(self, keys):
96 fmt = fmt.replace(i, i[1:-1] + "=" + i)
100 def format(self, record):
102 Find mdcs in log record extra field, if key form mdcFmt dosen't
103 contains mdcs, the values will be empty.
104 :param record: the logging record instance
107 the mdcs dict in logging record is
108 {'key1':'value1','key2':'value2'}
109 the mdcFmt is" '{key1} {key3}'
110 the output of mdc message: 'key1=value1 key3='
113 mdcIndex = self._fmt.find(self._mdc_tag)
115 if is_above_python_2_7():
116 return super(MDCFormatter, self).format(record)
118 return MarkerFormatter.format(self, record)
120 mdcFmtkeys, mdcFmtWords = self._mdcfmtKey()
122 if mdcFmtWords is None:
123 self._fmt = self._fmt.replace(self._mdc_tag, "")
124 if is_above_python_3_2():
125 self._style = logging._STYLES[self.style][0](self._fmt)
127 if is_above_python_2_7():
128 return super(MDCFormatter, self).format(record)
130 return MarkerFormatter.format(self, record)
132 mdc = record.__dict__.get('mdc', None)
134 for i in mdcFmtWords:
142 mdcstr = self._replaceStr(keys=mdcFmtkeys).format(**res)
143 self._fmt = self._fmt.replace(self._mdc_tag, mdcstr)
145 if is_above_python_3_2():
146 self._style = logging._STYLES[self.style][0](self._fmt)
148 if is_above_python_2_7():
149 return super(MDCFormatter, self).format(record)
151 return MarkerFormatter.format(self, record)
153 except KeyError as e:
154 print("The mdc key %s format is wrong" % str(e))