什么是最python的方式记录多个模块和具有指定编码的多个处理程序? [英] What is the most pythonic way of logging for multiple modules and multiple handlers with specified encoding?

查看:100
本文介绍了什么是最python的方式记录多个模块和具有指定编码的多个处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找关于如何执行多个模块和多个处理程序日志记录的具体建议。我已经在这里添加了我的简化代码,但我不想偏见的答案 - 告诉我最好的做法是什么。



我想记录一切文件,以及警告和以上的控制台。



这是我的 level0.py 指定的文件:

  import logging 
from flask import Flask
来自level1 import function1

app = Flask(__ name__)

logger = logging.getLogger('logger0')
logger.setLevel(logging.DEBUG)
$ b file_handler = logging.FileHandler('../ logs / logger0','w','utf-8')
file_handler.setLevel(logging.DEBUG)
file_format = logging.Formatter('%(asctime) s%(levelname)s:%(message)s [%(pathname)s:%(lineno)d in%(funcName)s]')
file_handler.setFormatter(file_format)
logger。 addHandler(file_handler)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_format = logging.Formatter('%(message)s')
console_handler.setFormatter(console_format)
logger.addHandler(console_handler)

@ app.route('/',methods = ['GET','POST'])
def function0(foo):
bar = function1(foo)
logger.debug('function0')
...
pre>

此外,当作为脚本调用时, level1 可以是独立模块。在这种情况下,我想要它记录到另一个文件。下面是 level1.py (具有重复的日志记录行):

 导入日志
logger = logging.getLogger('level0.level1')

来自level2 import function2

def function1(foo):
bar =如果__name__ ==__main__:
logger = logging.getLogger('function')





$ b logger0')
logger.setLevel(logging.DEBUG)

file_handler = logging.FileHandler('../ logs / logger1','w','utf-8')
file_handler.setLevel(logging.DEBUG)
file_format = logging.Formatter('%(asctime)s%(levelname)s:%(message)s [%(路径名)s:% in%(funcName)s]')
file_handler.setFormatter(file_format)
logger.addHandler(file_handler)

console_handler = logging.StreamHandler()
console_handler。 setLevel(logging.INFO)
console_format = logging.Formatter('%(message)s')
console_handler.setFormatter(console_format)
logger.addHandler(console_handler)

bar = function1('foo')
logger.info('level1 main')
...


$ b

我从 level0 复制了这个日志块,因为我想要相同的日志记录,它似乎直观地放在主。 level2 不是独立的,因此只有:

  import logging 
logger = logging.getLogger('level0.level1.level2')

def function2(foo):
logger.info('function2')
... 。



我开始使用 logging.basicSetup 但无法设置该文件的编码,并且在尝试记录非ASCII字符串时始终会收到 UnicodeEncodeError

  logger.warn(u'foo bar {}'。format(NON_ASCII_STR))

(我仍然得到错误,因为记录器传递消息给它的父母)



那么,这种情况下最好的日志设计是什么或更一般 - 多个模块(带编码选择 - 我想要utf-8)

解决方案

对于由许多部分组成的模块,在文档中推荐,每个模块只有一行, logger = logging.getLogger(__ name __)。正如你所指出的,模块不应该知道或关心它的消息如何或在哪里,它只是传递到记录器应该由主程序设置。



为了减少cut-n-paste,这取决于你的主要程序,确保你的模块有一个层次结构有意义,并有一个功能在某处设置你的日志,然后可以被任何

 <$ c $ 



例如,建立一个logsetup.py: import logging

def configure_log(level = None,name = None):
logger = logging.getLogger(name)
logger.setLevel(level)

file_handler = logging.FileHandler('../ logs /%s'%name,'w','utf-8')
file_handler.setLevel(logging.DEBUG)
file_format = logging.Formatter('%(asctime)s%(levelname)s:%(message)s [in%(pathname)s:%(lineno)d in%(funcName)s]')
file_handler.setFormatter (file_format)
logger.addHandler(file_handler)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_format = logging.Formatter '%(message)s')
console_handler.setFormatter(console_format)
logger.addHandler(console_handler)

要使您的单个模块具有它们作为主模块的模式,请定义一个单独的函数,例如 main



在level0.py和/或level1.py中:

  def main():
#do whatever

在最顶层的程序中,调用该函数:

  import logging 
来自logsetup import configure_log
configure_log(logging.DEBUG,'level0')#或'level1'
来自level0 import main#或level1

如果__name__ ==__main__
main()

您还应该有 __ name__ ==__main __子句,有些模块(多重处理 )根据该子句是否存在而具有不同的行为。


I'm looking for concrete advice about how the multiple module and multiple handler logging should be done. I have added my simplified code here, but I don't want to bias the answers - tell me what the best practice is.

I would like to log everything to a file, and warn and above to console.

This is my level0.py which I want it to log to the specified file:

import logging
from flask import Flask
from level1 import function1

app = Flask(__name__)

logger = logging.getLogger('logger0')
logger.setLevel(logging.DEBUG)

file_handler = logging.FileHandler('../logs/logger0','w','utf-8')
file_handler.setLevel(logging.DEBUG)
file_format = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d in %(funcName)s]')
file_handler.setFormatter(file_format)
logger.addHandler(file_handler)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_format = logging.Formatter('%(message)s')
console_handler.setFormatter(console_format)
logger.addHandler(console_handler)

@app.route('/', methods=['GET', 'POST'])
def function0(foo):
    bar = function1(foo)
    logger.debug('function0')
    ...

Also, level1 can be a standalone module, when called as a script. In that case I want it logged to another file. Below is the level1.py (has duplicated logging lines):

import logging
logger = logging.getLogger('level0.level1')

from level2 import function2

def function1(foo):
    bar = function2(foo)
    logger.debug('function1')
    ...

if __name__ == "__main__":
    logger = logging.getLogger('logger0')
    logger.setLevel(logging.DEBUG)

    file_handler = logging.FileHandler('../logs/logger1','w','utf-8')
    file_handler.setLevel(logging.DEBUG)
    file_format = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d in %(funcName)s]')
    file_handler.setFormatter(file_format)
    logger.addHandler(file_handler)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_format = logging.Formatter('%(message)s')
    console_handler.setFormatter(console_format)
    logger.addHandler(console_handler)

    bar = function1('foo')
    logger.info('level1 main')
    ...

I've copied this logging chunk from level0, because I wanted the same logging and it seemed intuitive to put it in main. level2 is not standalone, so it only has:

import logging
logger = logging.getLogger('level0.level1.level2')

def function2(foo):
    logger.info('function2')
    ....

I started with logging.basicSetup, but couldn't set encoding for the file and kept getting UnicodeEncodeError when trying to log non-ascii strings:

logger.warn(u'foo bar {}'.format(NON_ASCII_STR))

(I still get the error as the logger passes the message to its parents)

So, what is the best log design for this case or more generally - multiple modules (with encoding selection - I want utf-8)

解决方案

For modules consisting of many parts, I use the method recommended in the documentation, which just has one line per module, logger = logging.getLogger(__name__). As you point out, the module shouldn't know or care how or where its messages are going, it just passes it on to the logger that should have been set up by the main program.

To reduce cut-n-paste depending on which is your main program, make sure your modules have a hierarchy that makes sense, and have just one function somewhere that sets up your logging, which can then be called by any main you wish.

For example, make a logsetup.py:

import logging

def configure_log(level=None,name=None):
    logger = logging.getLogger(name)
    logger.setLevel(level)

    file_handler = logging.FileHandler('../logs/%s' % name,'w','utf-8')
    file_handler.setLevel(logging.DEBUG)
    file_format = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d in %(funcName)s]')
    file_handler.setFormatter(file_format)
    logger.addHandler(file_handler)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_format = logging.Formatter('%(message)s')
    console_handler.setFormatter(console_format)
    logger.addHandler(console_handler)

To have your individual modules have a mode in which they behave as main, define a separate function, such as main.

In level0.py and/or level1.py:

def main():
  # do whatever

And in the very top level program, call that function:

import logging
from logsetup import configure_log
configure_log(logging.DEBUG,'level0') # or 'level1'
from level0 import main # or level1

if __name__ == "__main__"
  main()

You should still have the __name__ == "__main__" clause there, some modules (cough multiprocessing cough) have different behavior depending on whether or not the clause exists.

这篇关于什么是最python的方式记录多个模块和具有指定编码的多个处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆