Support Marker in python logging 33/64933/2
authorliangke <lokyse@163.com>
Thu, 6 Sep 2018 07:37:38 +0000 (15:37 +0800)
committerliangke <lokyse@163.com>
Thu, 6 Sep 2018 08:05:39 +0000 (16:05 +0800)
1 Add 'Marker' feature which carry extra contextual
information for loggers, can be used to mark a single log
statement
2 Make MDC Formatter have "marker" label.

Change-Id: I21ac547b97c49190393d57ff290dcbc3ae20da2a
Issue-ID: MULTICLOUD-328
Signed-off-by: liangke <lokyse@163.com>
12 files changed:
pylog/onaplogging/__init__.py
pylog/onaplogging/logWatchDog.py
pylog/onaplogging/marker/__init__.py [new file with mode: 0644]
pylog/onaplogging/marker/marker.py [new file with mode: 0644]
pylog/onaplogging/marker/markerFactory.py [new file with mode: 0644]
pylog/onaplogging/marker/markerFilter.py [new file with mode: 0644]
pylog/onaplogging/marker/markerHandler.py [new file with mode: 0644]
pylog/onaplogging/markerFormatter.py [new file with mode: 0644]
pylog/onaplogging/markerLogAdaptor.py [new file with mode: 0644]
pylog/onaplogging/mdcContext.py
pylog/onaplogging/mdcformatter.py
pylog/onaplogging/monkey.py

index 1f2f9d9..204d7d1 100644 (file)
@@ -1,11 +1,13 @@
-# Copyright (c) 2018 VMware, Inc.
+# 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:
+# You may obtain a copy of the License at
 #
-#       http://www.apache.org/licenses/LICENSE-2.0
+#         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.
index 154dc41..f93dd12 100644 (file)
@@ -1,14 +1,16 @@
-# Copyright (c) 2018 VMware, Inc.
+# 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:
+# You may obtain a copy of the License at
 #
-#       http://www.apache.org/licenses/LICENSE-2.0
+#         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 yaml
@@ -89,7 +91,6 @@ def _yamlConfig(filepath=None, watchDog=None):
 
 
 def patch_loggingYaml():
-
     # The patch to add yam config forlogginf and runtime
     # reload logging when modify yaml file
     config.yamlConfig = _yamlConfig
diff --git a/pylog/onaplogging/marker/__init__.py b/pylog/onaplogging/marker/__init__.py
new file mode 100644 (file)
index 0000000..a1b3d89
--- /dev/null
@@ -0,0 +1,27 @@
+# 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.
+
+from __future__ import absolute_import
+
+from marker.marker import (
+    Marker, MARKER_TAG,
+    BaseMarker, matchMarkerHelp)
+
+from marker.markerFactory import MarkerFactory
+from marker.markerHandler import MarkerNotifyHandler
+from marker.markerFilter import MarkerFilter
+
+__all__ = ("Marker", "MARKER_TAG", "BaseMarker",
+           "matchMarkerHelp", "MarkerFactory",
+           "MarkerNotifyHandler", "MarkerFilter")
diff --git a/pylog/onaplogging/marker/marker.py b/pylog/onaplogging/marker/marker.py
new file mode 100644 (file)
index 0000000..5414e21
--- /dev/null
@@ -0,0 +1,142 @@
+# 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 abc
+
+MARKER_TAG = "marker"
+
+
+class Marker(object):
+
+    __metaclass__ = abc.ABCMeta
+
+    @abc.abstractmethod
+    def getName(self):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def contains(self, item=None):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def addChild(self, item):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def removeChild(self, item):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def __hash__(self):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def __iter__(self):
+        raise NotImplementedError()
+
+
+class BaseMarker(Marker):
+
+    def __init__(self, name):
+        super(BaseMarker, self).__init__()
+        if not isinstance(name, str):
+            raise TypeError("not str type")
+        if name == "":
+            raise ValueError("empty value")
+        self.__name = name
+        self.__childs = []
+
+    def getName(self):
+        return self.__name
+
+    def __iter__(self):
+        return iter(self.__childs)
+
+    def __eq__(self, other):
+
+        if not isinstance(other, Marker):
+            return False
+        if id(self) == id(other):
+            return True
+
+        return self.__name == other.getName()
+
+    def __hash__(self):
+        return hash(self.__name)
+
+    def contains(self, item=None):
+
+        if isinstance(item, Marker):
+            if item == self:
+                return True
+            return len(list(filter(
+                lambda x: x == item, self.__childs))) > 0
+
+        elif isinstance(item, str):
+            if item == self.__name:
+                return True
+
+            return len(list(filter(
+                lambda x: x.__name == item, self.__childs))) > 0
+
+        return False
+
+    def addChild(self, item):
+        if not isinstance(item, Marker):
+            raise TypeError("can only add  (not %s) marker type"
+                            % type(item))
+        if self == item:
+            return
+        if item not in self.__childs:
+            self.__childs.append(item)
+
+    def addChilds(self, childs):
+        try:
+            iter(childs)
+        except Exception as e:
+            raise e
+
+        for item in childs:
+            self.addChild(item)
+
+    def removeChild(self, item):
+        if not isinstance(item, Marker):
+            raise TypeError("can only add  (not %s) marker type"
+                            % type(item))
+        if item in self.__childs:
+            self.__childs.remove(item)
+
+
+def matchMarkerHelp(record, markerToMatch):
+
+    marker = getattr(record, MARKER_TAG, None)
+
+    if marker is None or markerToMatch is None:
+        return False
+
+    if not isinstance(marker, Marker):
+        return False
+
+    try:
+        if isinstance(markerToMatch, list):
+            return len(list(filter(
+                lambda x: marker.contains(x), markerToMatch))) > 0
+
+        return marker.contains(markerToMatch)
+    except Exception as e:
+        raise e
diff --git a/pylog/onaplogging/marker/markerFactory.py b/pylog/onaplogging/marker/markerFactory.py
new file mode 100644 (file)
index 0000000..deb9566
--- /dev/null
@@ -0,0 +1,74 @@
+# 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 abc
+import threading
+from marker import BaseMarker
+
+lock = threading.RLock()
+
+
+class IMarkerFactory(object):
+    __metaclass__ = abc.ABCMeta
+
+    @abc.abstractmethod
+    def getMarker(self, marker_name=None):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def deleteMarker(self, marker_name=None):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def exist(self, marker_name=None):
+        raise NotImplementedError()
+
+
+class MarkerFactory(IMarkerFactory):
+
+    _instance = None
+    _marker_map = {}
+
+    def __new__(cls, *args, **kwargs):
+
+        if cls._instance is None:
+            cls._instance = super(MarkerFactory, cls).__new__(cls)
+
+        return cls._instance
+
+    def getMarker(self, marker_name=None):
+        if marker_name is None:
+            raise ValueError("not empty")
+
+        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()
+
+        return marker
+
+    def deleteMarker(self, marker_name=None):
+        lock.acquire()
+        if self.exist(marker_name):
+            del self._marker_map[marker_name]
+            return True
+        lock.release()
+        return False
+
+    def exist(self, marker_name=None):
+
+        return self._marker_map.get(
+            marker_name, None) is not None
diff --git a/pylog/onaplogging/marker/markerFilter.py b/pylog/onaplogging/marker/markerFilter.py
new file mode 100644 (file)
index 0000000..4ae5478
--- /dev/null
@@ -0,0 +1,32 @@
+# 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 sys
+from logging import Filter
+from marker import matchMarkerHelp
+
+
+class MarkerFilter(Filter):
+
+    def __init__(self, name="", markers=None):
+        if sys.version_info > (2, 7):
+            super(MarkerFilter, self).__init__(name)
+        else:
+            Filter.__init__(self, name)
+
+        self.markerToMatch = markers
+
+    def filter(self, record):
+        # compare filter's markers with record's marker
+        return matchMarkerHelp(record, self.markerToMatch)
diff --git a/pylog/onaplogging/marker/markerHandler.py b/pylog/onaplogging/marker/markerHandler.py
new file mode 100644 (file)
index 0000000..ca5f483
--- /dev/null
@@ -0,0 +1,51 @@
+# 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 sys
+from logging.handlers import SMTPHandler
+from marker import matchMarkerHelp
+
+
+class MarkerNotifyHandler(SMTPHandler):
+
+    def __init__(self, mailhost, fromaddr, toaddrs, subject,
+                 credentials=None, secure=None, timeout=5.0, markers=None):
+
+        if sys.version_info > (3, 2):
+            super(MarkerNotifyHandler, self).__init__(
+                mailhost, fromaddr, toaddrs, subject,
+                credentials, secure, timeout)
+        elif sys.version_info > (2, 7):
+            super(MarkerNotifyHandler, self).__init__(
+                mailhost, fromaddr, toaddrs, subject,
+                credentials, secure)
+        else:
+            SMTPHandler.__init__(self,
+                                 mailhost, fromaddr, toaddrs, subject,
+                                 credentials, secure)
+
+        self.markers = markers
+
+    def handle(self, record):
+
+        if self.markers is None:
+            return False
+
+        if matchMarkerHelp(record, self.markers):
+            if sys.version_info > (2, 7):
+                return super(SMTPHandler, self).handle(record)
+            else:
+                return SMTPHandler.handle(self, record)
+
+        return False
diff --git a/pylog/onaplogging/markerFormatter.py b/pylog/onaplogging/markerFormatter.py
new file mode 100644 (file)
index 0000000..f33bfc2
--- /dev/null
@@ -0,0 +1,72 @@
+# 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 sys
+import logging
+from marker import MARKER_TAG
+from marker import Marker
+
+
+class MarkerFormatter(logging.Formatter):
+
+    def __init__(self, fmt=None, datefmt=None, style='%'):
+
+        if sys.version_info > (3, 2):
+            super(MarkerFormatter, self).__init__(
+                fmt=fmt, datefmt=datefmt, style=style)
+        elif sys.version_info > (2, 7):
+            super(MarkerFormatter, self).__init__(
+                fmt=fmt, datefmt=datefmt)
+        else:
+            logging.Formatter.__init__(self, fmt, datefmt)
+
+        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}"
+
+        self._tmpFmt = self._fmt
+
+    def format(self, record):
+
+        try:
+            if self._fmt.find(self._marker_tag) != -1 \
+                    and hasattr(record, MARKER_TAG):
+                marker = getattr(record, MARKER_TAG)
+
+                if isinstance(marker, Marker):
+                    self._fmt = self._fmt.replace(
+                        self._marker_tag, marker.getName())
+            elif self._fmt.find(self._marker_tag) != -1 \
+                    and not hasattr(record, MARKER_TAG):
+
+                    self._fmt = self._fmt.replace(self._marker_tag, "")
+
+            if sys.version_info > (3, 2):
+                self._style = logging._STYLES[self.style][0](self._fmt)
+
+            if sys.version_info > (2, 7):
+                return super(MarkerFormatter, self).format(record)
+            else:
+                return logging.Formatter.format(self, record)
+
+        finally:
+                self._fmt = self._tmpFmt
diff --git a/pylog/onaplogging/markerLogAdaptor.py b/pylog/onaplogging/markerLogAdaptor.py
new file mode 100644 (file)
index 0000000..d787f2b
--- /dev/null
@@ -0,0 +1,85 @@
+# 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 sys
+from logging import LoggerAdapter
+from threading import RLock
+from functools import wraps
+from marker import MARKER_TAG
+from marker import Marker
+from mdcContext import _getmdcs
+
+lock = RLock()
+
+
+def addMarker(func):
+
+    @wraps(func)
+    def wrapper(self, marker, msg, *args, **kwargs):
+        lock.acquire()
+        if not isinstance(marker, Marker):
+            raise TypeError("not marker type %s"
+                            % type(marker))
+
+        if self.extra and MARKER_TAG in self.extra:
+            raise Exception("cann't  add 'marker' in extra")
+        setattr(self.logger, MARKER_TAG, marker)
+        func(self, marker, msg, *args, **kwargs)
+        if hasattr(self.logger, MARKER_TAG):
+            delattr(self.logger, MARKER_TAG)
+        lock.release()
+    return wrapper
+
+
+class MarkerLogAdaptor(LoggerAdapter):
+
+    def process(self, msg, kwargs):
+
+        if sys.version_info > (3, 2):
+            kwargs['extra'] = _getmdcs(self.extra)
+        else:
+            kwargs['extra'] = self.extra
+        return msg, kwargs
+
+    @addMarker
+    def infoMarker(self, marker, msg, *args, **kwargs):
+
+        self.info(msg, *args, **kwargs)
+
+    @addMarker
+    def debugMarker(self, marker, msg, *args, **kwargs):
+
+        self.debug(msg, *args, **kwargs)
+
+    @addMarker
+    def warningMarker(self, marker, msg, *args, **kwargs):
+
+        self.warning(msg, *args, **kwargs)
+
+    @addMarker
+    def errorMarker(self, marker, msg, *args, **kwargs):
+
+        self.error(msg, *args, **kwargs)
+
+    @addMarker
+    def exceptionMarker(self, marker, msg, *arg, **kwargs):
+        self.exception(msg, *arg, **kwargs)
+
+    @addMarker
+    def criticalMarker(self, marker, msg, *arg, **kwargs):
+        self.critical(msg, *arg, **kwargs)
+
+    @addMarker
+    def logMarker(self, marker, level, msg, *arg, **kwargs):
+        self.log(level, msg, *arg, **kwargs)
index 60075b4..4fdc99c 100644 (file)
@@ -1,15 +1,16 @@
-# Copyright (c) 2018 VMware, Inc.
+# 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:
+# You may obtain a copy of the License at
 #
-#       http://www.apache.org/licenses/LICENSE-2.0
+#         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
 import threading
@@ -18,12 +19,14 @@ import os
 import traceback
 import sys
 import functools
-
+from marker import Marker
+from marker import MARKER_TAG
 
 __all__ = ['patch_loggingMDC', 'MDC']
 
 _replace_func_name = ['info', 'critical', 'fatal', 'debug',
-                      'error', 'warn', 'warning', 'log', 'findCaller']
+                      'error', 'warn', 'warning', 'log',
+                      'handle', 'findCaller']
 
 
 class MDCContext(threading.local):
@@ -80,7 +83,7 @@ def _getmdcs(extra=None):
     :return: mdc dict
     """
     if MDC.isEmpty():
-        return
+        return extra
 
     mdc = MDC.result()
 
@@ -93,6 +96,7 @@ def _getmdcs(extra=None):
         extra = {}
 
     extra['mdc'] = mdc
+
     del mdc
     return extra
 
@@ -106,7 +110,6 @@ def info(self, msg, *args, **kwargs):
 
 @fetchkeys
 def debug(self, msg, *args, **kwargs):
-
     if self.isEnabledFor(logging.DEBUG):
         self._log(logging.DEBUG, msg, args, **kwargs)
 
@@ -150,6 +153,17 @@ def log(self, level, msg, *args, **kwargs):
         self._log(level, msg, args, **kwargs)
 
 
+def handle(self, record):
+
+    cmarker = getattr(self, MARKER_TAG, None)
+
+    if isinstance(cmarker, Marker):
+        setattr(record, MARKER_TAG, cmarker)
+
+    if (not self.disabled) and self.filter(record):
+        self.callHandlers(record)
+
+
 def findCaller(self, stack_info=False):
 
     f = logging.currentframe()
index 01056a4..087497d 100644 (file)
@@ -1,19 +1,23 @@
-# Copyright (c) 2018 VMware, Inc.
+# 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:
+# You may obtain a copy of the License at
 #
-#       http://www.apache.org/licenses/LICENSE-2.0
+#         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 sys
 import logging
+from markerFormatter import MarkerFormatter
 
 
-class MDCFormatter(logging.Formatter):
+class MDCFormatter(MarkerFormatter):
     """
     A custom MDC formatter to prepare Mapped Diagnostic Context
     to enrich log message.
@@ -33,7 +37,7 @@ class MDCFormatter(logging.Formatter):
         elif sys.version_info > (2, 7):
             super(MDCFormatter, self).__init__(fmt=fmt, datefmt=datefmt)
         else:
-            logging.Formatter.__init__(self, fmt, datefmt)
+            MarkerFormatter.__init__(self, fmt, datefmt)
 
         self.style = style
         self._mdc_tag = "%(mdc)s"
@@ -46,7 +50,6 @@ class MDCFormatter(logging.Formatter):
             elif self.style == "$":
                 self._mdc_tag = "${mdc}"
 
-        self._tmpfmt = self._fmt
         if mdcfmt:
             self._mdcFmt = mdcfmt
         else:
@@ -111,20 +114,19 @@ class MDCFormatter(logging.Formatter):
             if sys.version_info > (2, 7):
                 return super(MDCFormatter, self).format(record)
             else:
-                return logging.Formatter.format(self, record)
+                return MarkerFormatter.format(self, record)
 
         mdcFmtkeys, mdcFmtWords = self._mdcfmtKey()
 
         if mdcFmtWords is None:
+            self._fmt = self._fmt.replace(self._mdc_tag, "")
             if sys.version_info > (3, 2):
-                self._style = logging._STYLES[self.style][0](
-                    self._fmt.replace(self._mdc_tag, ""))
-            else:
-                self._fmt = self._fmt.replace(self._mdc_tag, "")
+                self._style = logging._STYLES[self.style][0](self._fmt)
+
             if sys.version_info > (2, 7):
                 return super(MDCFormatter, self).format(record)
             else:
-                return logging.Formatter.format(self, record)
+                return MarkerFormatter.format(self, record)
 
         mdc = record.__dict__.get('mdc', None)
         res = {}
@@ -137,22 +139,17 @@ class MDCFormatter(logging.Formatter):
         del mdc
         try:
             mdcstr = self._replaceStr(keys=mdcFmtkeys).format(**res)
+            self._fmt = self._fmt.replace(self._mdc_tag, mdcstr)
+
             if sys.version_info > (3, 2):
-                self._style = logging._STYLES[self.style][0](
-                    self._fmt.replace(self._mdc_tag, mdcstr))
-            else:
-                self._fmt = self._fmt.replace(self._mdc_tag, mdcstr)
+                self._style = logging._STYLES[self.style][0](self._fmt)
+
             if sys.version_info > (2, 7):
-                s = super(MDCFormatter, self).format(record)
+                return super(MDCFormatter, self).format(record)
             else:
-                s = logging.Formatter.format(self, record)
-            return s
+                return MarkerFormatter.format(self, record)
 
         except KeyError as e:
             print("The mdc key %s format is wrong" % str(e))
         except Exception:
             raise
-
-        finally:
-            # reset fmt format
-            self._fmt = self._tmpfmt
index fcf8fdf..00659c7 100644 (file)
@@ -1,15 +1,16 @@
-# Copyright (c) 2018 VMware, Inc.
+# 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:
+# You may obtain a copy of the License at
 #
-#       http://www.apache.org/licenses/LICENSE-2.0
+#         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.
 
 from mdcContext import patch_loggingMDC
 from logWatchDog import patch_loggingYaml