本文介绍了如何在Python中的函数入口,内部和出口处进行日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我希望所有现有/将来的模块和功能都具有"Entering ..."和"Done ..."日志消息.
我不想在每个函数定义中为定义日志记录参数(显示在don't want to add everywhere下)添加相同的代码段.
我希望log.info(...) etc构造可以在我在项目层次结构中定义的任何功能中使用.
I'd like all existing/future module and functions to have "Entering ..." and "Done ..." log messages.
I don't want to add the same code snippet to defining logging parameters (shown below don't want to add everywhere) in every function definition.
I want the log.info(...) etc constructs to work in any function I define in the project hierarchy.
我想避免在我编写的每个现有/新模块中定义相同的@log装饰器.
I'd like to avoid defining the same @log decorator in every existing/new module that I write.
我希望能够使用Python日志记录工具在我的代码中进行简单且一致的日志记录.
I'd like to be able to do simple and consistent logging in my code using the Python logging facility.
我能够执行以下操作:
什么是行不通的/我不知道该怎么做:
# don't want to add everywhere FORMAT = '%(asctime)s - %(name)-20s - %(levelname)-5s - %(message)s' LEVEL = logging.DEBUG logging.basicConfig(format=FORMAT, level=LEVEL) log = logging.getLogger(__name__)
我的Flask项目中的示例代码:
# app/__init__.py from a import b # various other imports required for app import logging FORMAT = '%(asctime)s - %(name)-20s - %(levelname)-5s - %(message)s' LEVEL = logging.DEBUG logging.basicConfig(format=FORMAT, level=LEVEL) log = logging.getLogger(__name__) # ... various other app init code from app import views, models#app/views.py from c import d # various other imports required for the module def logger(fn): from functools import wraps import inspect @wraps(fn) def wrapper(*args, **kwargs): global log log = logging.getLogger(inspect.stack()[1][3]) log.info('About to run %s' % fn.__name__) out = apply(fn, args, kwargs) log.info('Done running %s' % fn.__name__) # Return the return value return out return wrapper @app.route('/this_func') @logger def this_func(): log.info('I am doing logging without having to do bunch of definitions.') # some more code @app.route('/that_func') @logger def that_func(): log.info('Yet more logging without having to do bunch of definitions.') log.info('I can simply refer to the log object and be done with it.') # some more code
推荐答案
对我有用的最终设置如下:
The final setup that worked for me was the following:
# At the beginning of every .py file in the project def logger(fn): from functools import wraps import inspect @wraps(fn) def wrapper(*args, **kwargs): log = logging.getLogger(fn.__name__) log.info('About to run %s' % fn.__name__) out = apply(fn, args, kwargs) log.info('Done running %s' % fn.__name__) # Return the return value return out return wrapper # Do the following section only in application's app/__init__.py # Other files will pick it up from here. FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s' # Change logging LEVEL according to debugging needs. # Probably better to read this from a config or a launch parameter. LEVEL = logging.DEBUG logging.basicConfig(format=FORMAT, level=LEVEL) # Up to here only for app/__init__.py # This section again at the beginning of every .py file log = logging.getLogger(__name__) log.info('Entered module: %s' % __name__)现在,在模块中的每个函数定义中添加一个@logger装饰器:
Now, add a @logger decorator to every function definition in the module:
@logger def do_something(): print('doing really useful stuff.')更多推荐
如何在Python中的函数入口,内部和出口处进行日志记录
发布评论