X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=cmframework%2Fsrc%2Fcmframework%2Futils%2Fcmlogger.py;fp=cmframework%2Fsrc%2Fcmframework%2Futils%2Fcmlogger.py;h=eba7fd37a2f96edebf8fa2e308c131e8d492a109;hb=c389bdee7b3845b55f443dbf04c0ce4083a55886;hp=0000000000000000000000000000000000000000;hpb=5030f0c004701dd422c78c71c014ef60f48139fc;p=ta%2Fconfig-manager.git diff --git a/cmframework/src/cmframework/utils/cmlogger.py b/cmframework/src/cmframework/utils/cmlogger.py new file mode 100644 index 0000000..eba7fd3 --- /dev/null +++ b/cmframework/src/cmframework/utils/cmlogger.py @@ -0,0 +1,151 @@ +# Copyright 2019 Nokia + +# 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 re +import sys +import logging +from logging.handlers import SysLogHandler + +from cmframework.apis import cmerror + + +class CMMaskFormatter(object): + def __init__(self, orig_formatter, patterns): + self.orig_formatter = orig_formatter + self.patterns = patterns + + def format(self, record): + msg = self.orig_formatter.format(record) + regex = r'([\\]*\"{}[\\]*\":\s[\\]*\")[^\"\\\s]+([\\]*\")' + for pattern in self.patterns: + + msg = re.sub(regex.format(pattern), + r'\1*** password ***\2', msg) + + return msg + + def __getattr__(self, attr): + return getattr(self.orig_formatter, attr) + + +class CMLogger(object): + levels = {'debug': logging.DEBUG, + 'info': logging.INFO, + 'warning': logging.WARNING, + 'error': logging.error} + + DEST_CONSOLE = 1 + DEST_SYSLOG = 2 + dests = {'console': DEST_CONSOLE, + 'syslog': DEST_SYSLOG} + + def __init__(self, dest, verbose, level, mask_names=None): + self.verbose = verbose + self.dest = dest + self.level = level + self.formatter = None + self.handler = None + self.mask_formatter = None + if mask_names is None: + mask_names = [] + self.init(mask_names) + + def init(self, mask_names): + if self.level not in CMLogger.levels.values(): + raise cmerror.CMError('Invalid level value, possible values are %s' % + str(CMLogger.levels)) + + if self.dest not in CMLogger.dests.values(): + raise cmerror.CMError('Invalid destination value, possible values are %s' % + str(CMLogger.dests)) + + if self.verbose: + if self.dest is CMLogger.DEST_CONSOLE: + format_str = '[%(asctime)s %(levelname)7s %(module)s(%(lineno)3s)] %(message)s' + else: + format_str = '[%(module)s(%(lineno)3s)] %(message)s' + else: + format_str = '%(message)s' + + self.formatter = logging.Formatter(format_str) + self.mask_formatter = CMMaskFormatter(self.formatter, mask_names) + self.set_dest(self.dest) + + logging.getLogger().setLevel(self.level) + + def set_level(self, level): + self.level = level + logging.getLogger().setLevel(self.level) + + def set_dest(self, dest): + if self.dest != dest or self.handler is None: + if self.handler: + logging.getLogger().removeHandler(self.handler) + + if self.dest is CMLogger.DEST_CONSOLE: + self.handler = logging.StreamHandler(sys.stdout) + self.handler.setFormatter(self.mask_formatter) + elif self.dest is CMLogger.DEST_SYSLOG: + print '====> setting destination to syslog' + self.handler = SysLogHandler(address='/dev/log') + self.handler.setFormatter(self.mask_formatter) + logging.getLogger().addHandler(self.handler) + + @staticmethod + def str_to_level(level): + ret = None + try: + ret = CMLogger.levels[level] + except KeyError: + raise cmerror.CMError('Invalid log level, possible values %s' % + str(CMLogger.levels.keys())) + return ret + + @staticmethod + def str_to_dest(dest): + ret = None + try: + ret = CMLogger.dests[dest] + except KeyError: + raise cmerror.CMError('Invalid destination, possible values %s' % + str(CMLogger.dests.keys())) + return ret + + @staticmethod + def level_to_str(level): + for key, value in CMLogger.levels.iteritems(): + if value is level: + return key + return None + + @staticmethod + def dest_to_str(dest): + for key, value in CMLogger.dests.iteritems(): + if value is dest: + return key + return None + + +def main(): + log_dest = CMLogger.str_to_dest('console') + log_level = CMLogger.str_to_level('debug') + _ = CMLogger(log_dest, True, log_level) + world = 'world' + logging.error('hello %s!', world) + logging.warn('hello %s!', world) + logging.info('hello %s!', world) + logging.debug('hello %s!', world) + + +if __name__ == '__main__': + main()