GUI程序的日志记录策略
我在想,给我的应用程序(一个绘画类程序)加一些调试日志可能会很有帮助,并把这些信息写到一个文件里。目前我调试的方式是连接一个自定义的异常监听器(sys.excepthook),让用户可以把导致程序崩溃的堆栈信息发邮件给我。
这样做让我能看到用户做了什么导致程序崩溃,但我觉得有一个日志文件肯定会更有帮助。我在想,最好的方法是什么。我考虑通过命令行开关来启用日志记录,并为每次运行程序创建一个日志文件,当崩溃发生时再把日志发给我。不过,如果应用程序不在调试模式下,日志就没什么用!
我有点担心日志会填满得太快——如果我把日志记录放在一些鼠标移动的事件处理器里,那就会产生很多条记录。而且,日志文件可能会变得很大,里面可能充满了我在查看错误报告时觉得无关紧要的信息。
你们是怎么处理这个问题的?我对日志记录的频率很感兴趣——因为我的应用程序会响应很多事件(比如鼠标移动,取决于用户输入),我不想产生过多的日志记录。
2 个回答
之前提到过,你可以使用日志模块。你可以设置一个默认的日志级别(比如警告),然后在代码中记录各种消息,从调试信息到严重错误都可以记录。如果你把日志级别设置为警告,那么即使你的代码中有调试信息,这些信息也不会出现在文件里(或者标准输出中)。这是因为日志模块只会记录优先级高于或等于警告的信息(比如警告、错误和严重错误)。
简单来说,看看这段代码:
import logging
import logging.handlers as handlers
logger = logging.getLogger('myapp')
hdlr = logging.FileHandler('/tmp/myapp.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.WARNING)
logger.debug('debug!')
logger.info('info!')
logger.warning('warning!')
logger.error('error!')
logger.critical('critical!')
这段代码会创建一个叫做 myapp.log 的文件:
magun@~: cat /tmp/myapp.log
2010-11-05 12:27:25,359 WARNING: warning!
2010-11-05 12:27:25,362 ERROR: error!
2010-11-05 12:27:26,071 CRITICAL: critical!
magun@~:
如果你担心文件大小,可以使用旋转日志,这样会根据你的标准丢弃最旧的日志:
import logging
import logging.handlers as handlers
logger = logging.getLogger('myapp')
hdlr = handlers.RotatingFileHandler('/tmp/log/myapp.log', maxBytes=100, backupCount=5)
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.WARNING)
for i in range(20):
logger.debug('debug%i!'%i)
logger.info('info%i!'%i)
logger.warning('warning%i!'%i)
logger.error('error%i!'%i)
logger.critical('critical%i!'%i)
在这个例子中,我设置了一个最大大小为 100 字节的日志文件(这个大小很小,你可以设置大一点),并且保留 5 个备份。这意味着当日志文件达到 100 字节时,它会被“旋转”:会创建一个新的(空的)myapp.log,旧的文件会变成 myapp.log.1。在下一次旋转时,myapp.log.1 会变成 myapp.log.2,而新的 myapp.log 会变成新的 myapp.log.1。这个过程会一直重复,直到我们有 myapp.log、myapp.log.1、myapp.log.2,... myapp.log.n(在这个例子中,最多会有 myapp.log.5)。当达到这个限制时,如果需要旋转日志,myapp.log.5 文件就会被丢弃。所以,大小限制是 5*100 字节。
看看发生了什么:
magun@~: ls /tmp/log/
myapp.log myapp.log.1 myapp.log.2 myapp.log.3 myapp.log.4 myapp.log.5
magun@~: cat /tmp/log/myapp.log
2010-11-05 12:33:52,369 ERROR: error19!
2010-11-05 12:33:52,376 CRITICAL: critical19!
magun@~: cat /tmp/log/myapp.log.1
2010-11-05 12:33:52,362 CRITICAL: critical18!
2010-11-05 12:33:52,369 WARNING: warning19!
magun@~: cat /tmp/log/myapp.log.2
2010-11-05 12:33:52,355 WARNING: warning18!
2010-11-05 12:33:52,362 ERROR: error18!
magun@~: cat /tmp/log/myapp.log.3
2010-11-05 12:33:52,348 ERROR: error17!
2010-11-05 12:33:52,355 CRITICAL: critical17!
magun@~: cat /tmp/log/myapp.log.4
2010-11-05 12:33:52,340 CRITICAL: critical16!
2010-11-05 12:33:52,348 WARNING: warning17!
magun@~: cat /tmp/log/myapp.log.5
2010-11-05 12:33:52,333 WARNING: warning16!
2010-11-05 12:33:52,340 ERROR: error16!
magun@~:
如你所见,我们丢失了很多日志(0-15),但最新的日志还在,这样可以节省用户的存储空间。别忘了从下往上看日志哦 :)