删除样板记录设置

时间:2015-03-19 19:57:26

标签: python-2.7 logging python-decorators

我看到这个非常常用的代码我用来设置日志记录。

 def has_host_running(self):
        log = CustomLogger.action_logger(name=sys._getframe().f_code.co_name, **self.menvargs)
        result = self.bash_query.check_is_server_available(log)
        self.results[sys._getframe().f_code.co_name] = result
        log.debug('result: {}'.format(result))
        return result

寻找实现此行为的干燥方法。 关键是我需要能够从 函数和任何子函数调用中引用/调用日志语句。

********* EDIT2 **************** ***************

我可以开始工作的最优雅的草率解决方案。 松散地改编自:https://wiki.python.org/moin/PythonDecoratorLibrary#Controllable_DIY_debug

heavily based on https://wiki.python.org/moin/PythonDecoratorLibrary#Controllable_DIY_debug

class ActionLog: def init(self): pass

def __call__(self, f):
    log = self.get_actionlogger(name=f.func_name)

    def newf(log, *args, **kwds):
        # pre-function call actions:
        log.debug('Start.')
        log.debug('    info: params= {args}, {kwds}'.format(args=args, kwds=kwds))

        # function call
        f_result = f(log, *args, **kwds)

        # post-function call actions:
        log.debug('    info: result= {result}'.format(result=f_result))
        log.debug('Complete.')
        return f_result

    # changes to be made to returned function
    newf.__doc__ = f.__doc__
    return newf(log)

def get_actionlogger(self, name, **kwargs):
    import logging
    import ast
    from Helper import ConfigManager

    logname = 'action.{func_name}'.format(func_name=name)
    logger = logging.getLogger(logname)

    # value stored in ini file.
    # either DEBUG or ERROR right now.
    # todo: store actual logging_level
    # todo: store an array/dict for log_name in .ini
    #       this will allow multiple parameters to be stored within the single entry.
    #       ex:
    #       action.check_stuff:    logging_level=DEBUG,handler_stream=TRUE,handler_file=stuff.log,formatter='{name} - {message}
    conf_logging_level = ConfigManager('config.ini').get_section_dict('CustomLogging_Level').get(logname, 'DEBUG')
    logging_level = logging.DEBUG
    if conf_logging_level == 'DEBUG':
        logging_level = logging.DEBUG
    if conf_logging_level == 'ERROR':
        logging_level = logging.ERROR

    logger.setLevel(logging_level)

    # very hacky
    # while logging.getLogger is a singleton, adding the handler is not.
    # without this check, this code will result in duplicate handlers added.
    # currently will not edit/replace the existing handler.
    # currently will not allow another handler to be added after the first.
    # main issue here is that I can't figure out how to determine labels/names within logger.handlers
    # todo: properly label handler
    # todo: check for existing labels & types (file, stream, etc)
    if len(logger.handlers) == 0:
        ch = logging.StreamHandler()
        ch.setLevel(logging_level)
        ch.set_name = logname

        # create formatter
        formatter = logging.Formatter(' %(name)s - %(message)s')
        ch.setFormatter(formatter)
        logger.addHandler(ch)

    return logger

def __call__(self, f): log = self.get_actionlogger(name=f.func_name) def newf(log, *args, **kwds): # pre-function call actions: log.debug('Start.') log.debug(' info: params= {args}, {kwds}'.format(args=args, kwds=kwds)) # function call f_result = f(log, *args, **kwds) # post-function call actions: log.debug(' info: result= {result}'.format(result=f_result)) log.debug('Complete.') return f_result # changes to be made to returned function newf.__doc__ = f.__doc__ return newf(log) def get_actionlogger(self, name, **kwargs): import logging import ast from Helper import ConfigManager logname = 'action.{func_name}'.format(func_name=name) logger = logging.getLogger(logname) # value stored in ini file. # either DEBUG or ERROR right now. # todo: store actual logging_level # todo: store an array/dict for log_name in .ini # this will allow multiple parameters to be stored within the single entry. # ex: # action.check_stuff: logging_level=DEBUG,handler_stream=TRUE,handler_file=stuff.log,formatter='{name} - {message} conf_logging_level = ConfigManager('config.ini').get_section_dict('CustomLogging_Level').get(logname, 'DEBUG') logging_level = logging.DEBUG if conf_logging_level == 'DEBUG': logging_level = logging.DEBUG if conf_logging_level == 'ERROR': logging_level = logging.ERROR logger.setLevel(logging_level) # very hacky # while logging.getLogger is a singleton, adding the handler is not. # without this check, this code will result in duplicate handlers added. # currently will not edit/replace the existing handler. # currently will not allow another handler to be added after the first. # main issue here is that I can't figure out how to determine labels/names within logger.handlers # todo: properly label handler # todo: check for existing labels & types (file, stream, etc) if len(logger.handlers) == 0: ch = logging.StreamHandler() ch.setLevel(logging_level) ch.set_name = logname # create formatter formatter = logging.Formatter(' %(name)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) return logger

@ActionLog() def check_stuff(log, *args, **kwds): result = True log.debug(' info: text call from within function.') return result

所以它适用于一个参数" log"被传入课堂。如果类没有log参数,则不起作用。如果还有其他参数,我不确定如何处理...可能使用* args或** kwargs,但此解决方案无法处理。

关于代码格式化的道歉...我似乎无法将类装饰器与装饰的func和func调用放在同一个块中。

* v3.0 * v2有多个参数的问题。解决了这个并简化了v3。

if check_stuff:
    print 'check_stuff is true.'

这样做效果更好,并且已经取代了我的大多数样板记录调用,以获取采用单个参数的操作。

仍然遇到名为args vs kwargs的问题。我想直接传递args并将我的自定义项添加到kwargs,但这有一些问题。

0 个答案:

没有答案