在我的程序中,我在开头定义了一个类似于此的记录器:
BUILD file looks like this:
package(default_visibility = ["//visibility:public"])
java_library(
name = "X-thrift-s",
srcs = glob(["*.java"]),
deps = [
"//thrift/services/X:XService",
"//java/com/.../services/X/service:thrift-server",
]
)
java_import(
name = "X-thrift-p",
jars = [
"//external:thrift-jar",
"//external:opencsv-jar",
"//java/lib:cspj-jar",
]
)
load("//tools/bzl:genthrift.bzl","thrift_java_library")
thrift_java_library(
name = "XService",
srcs = [
"XService.thrift"
],
)
java_binary(
name = "XHandler-Test",
srcs = glob(["*.java"]),
main_class = "com.......service.tests.XHandlerTest",
deps = [
"//java/....:X-thrift",
"//java/com.....:thrift-server",
"//java/com.....:XService",
],
)
然后我有多个从我的主程序调用的文件。为了使它们正常工作,我需要执行以下操作:
def start_logger():
fh = logging.handlers.RotatingFileHandler('logger.log',
maxBytes=1000000,
backupCount=100)
fh.setLevel(logging.DEBUG)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
fh_fmt = '%(asctime)s %(levelname)8s %(message)s [%(filename)s:%(lineno)d]'
#fh_fmt = '%(asctime)s - %(funcName)s - %(levelname)s - %(message)s'
ch_fmt = '%(asctime)s %(levelname)8s %(message)s [%(filename)s:%(lineno)d]'
#ch_fmt = '%(funcName)s - %(levelname)s - %(message)s'
fh.setFormatter(logging.Formatter(fh_fmt))
ch.setFormatter(logging.Formatter(ch_fmt))
root = logging.getLogger()
root.addHandler(fh)
root.addHandler(ch)
为什么我导入的所有模块的默认级别都设置为警告。当我们使用log = logging.getLogger( name )导入我的根记录器时,为什么我必须为每个级别再次设置DEBUG级别?这是在具有不同模块的包中创建日志记录模块的最佳方法,还是有更好的解决方案?
答案 0 :(得分:6)
让我们先来看看Handler.setLevel does:
将此处理程序的阈值设置为lvl。记录不如lvl严重的消息将被忽略。创建处理程序时,级别设置为NOTSET(这会导致处理所有消息)。
忽略任何比lvl严重的消息。实际上,将其设置为DEBUG是没有意义的(除非您定义自己的日志级别),因为没有比调试更严重的消息。所以,这意味着处理程序不会忽略任何消息。
setLevel
是正确的想法,但你在错误的对象上调用它。看看Logger.setLevel:
将此记录器的阈值设置为lvl。记录不如lvl严重的消息将被忽略。创建记录器时,级别设置为NOTSET(当记录器是根记录器时会导致处理所有消息,或者当记录器是非root记录器时委托给父级)。请注意,根记录器的创建级别为WARNING。
术语“委托给父母”意味着如果记录器具有NOTSET级别,则遍历其祖先记录器链,直到找到具有NOTSET以外级别的祖先,或者到达根目录。
如果发现祖先的级别不是NOTSET,那么祖先的级别将被视为祖先搜索开始的记录器的有效级别,并用于确定如何处理日志记录事件。
您正在创建孩子,但他们都是根记录器的孩子。它们的级别设置为NOTSET
,并传播到根,其默认值为WARNING
。因此,您没有看到任何消息。
<强> TL; DR:强> 解决方案很简单:在记录器上设置级别,而不是处理程序。以下代码应该满足您的需求:
def start_logger():
fh = logging.handlers.RotatingFileHandler('logger.log',
maxBytes=1000000,
backupCount=100)
ch = logging.StreamHandler(sys.stdout)
fh_fmt = '%(asctime)s %(levelname)8s %(message)s [%(filename)s:%(lineno)d]'
#fh_fmt = '%(asctime)s - %(funcName)s - %(levelname)s - %(message)s'
ch_fmt = '%(asctime)s %(levelname)8s %(message)s [%(filename)s:%(lineno)d]'
#ch_fmt = '%(funcName)s - %(levelname)s - %(message)s'
fh.setFormatter(logging.Formatter(fh_fmt))
ch.setFormatter(logging.Formatter(ch_fmt))
logging.basicConfig(level=logging.DEBUG)
root = logging.getLogger()
root.addHandler(fh)
root.addHandler(ch)
一旦你这样做,你就不应该在生孩子时需要setLevel
电话。
哦,并回答你的其他问题:这正是你应该使用日志库的方式。 (我实际上只是将所有内容记录到根记录器中,因为我不需要你开发的那种粒度,但是当你有一个案例时,你就是按照你应该做的那样。)
编辑:显然,setLevel似乎不能在根记录器上运行。相反,在访问根记录器之前,您必须设置basicConfig。在logging.basicConfig
中设置级别将满足您的需求(至少,它在我的测试中有效)。请注意,这样做符合Logging from multiple modules中给出的示例,因此应解决您的问题。