2010-10-23 81 views
3

我认为在我的应用程序(绘图类型的程序)中添加一些调试日志记录并将此信息写入文件可能会有所帮助。我目前的调试策略是连接一个自定义异常侦听器(sys.excepthook),并允许用户通过电子邮件向我发送导致崩溃的堆栈跟踪副本。图形用户界面程序的日志记录策略

这看起来很方便,看看用户做了什么导致程序崩溃,但我觉得一个日志文件可以帮助。 我想知道做这件事的最好方法是什么。我正在考虑通过命令行开关启用日志记录,并根据程序的“运行”创建日志,并在发生崩溃时通过电子邮件发送自己的日志副本。但是,如果应用程序不处于调试模式,日志将无法帮助!

我有点担心日志填满速度太快 - 如果我把日志记录放在一些鼠标移动事件处理程序中,那么它会创建很多条目。另外,日志文件可能会变得非常大,并且在检查错误报告时只会填充不相关的信息。

你们怎么处理这个问题?我对日志记录的频率感兴趣 - 因为我的应用程序响应许多事件(例如,鼠标移动;取决于用户输入),我不想创建多余的日志记录。

+0

你读过这个:http://docs.python.org/library/logging.html? – 2010-10-23 14:12:31

+0

是的,但我想知道有多少信息要真正记录,特别是在鼠标事件处理程序中,因为它们可能会被频繁调用。 – 2010-10-23 14:32:47

+0

请**更新**问题,以便它包含**全部**的详细信息。 – 2010-10-23 14:33:36

回答

5

如前所述,您可以使用记录器模块。您可以设置默认的日志级别(例如警告),并将所有类型的消息放入代码中,因为调试至关键为止。作为简单的解释,如果将日志级别设置为警告,即使代码记录调试消息,它们也不会出现在文件(或stdout)中。这是因为日志模块将只记录优先级高于或等于警告(警告,错误和严重)的消息。

举一个简单的解释一下这段代码:

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文件:

[email protected]~: 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! 
[email protected]~: 

如果你担心,你可以使用一个旋转的文件大小日志,女巫将根据您的标准丢弃最古老的日志:

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) 

在这种情况下,我使用了一个log fil e的最大大小为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字节。

看看发生了什么事:

[email protected]~: ls /tmp/log/ 
myapp.log myapp.log.1 myapp.log.2 myapp.log.3 myapp.log.4 myapp.log.5 
[email protected]~: cat /tmp/log/myapp.log 
2010-11-05 12:33:52,369 ERROR: error19! 
2010-11-05 12:33:52,376 CRITICAL: critical19! 
[email protected]~: cat /tmp/log/myapp.log.1 
2010-11-05 12:33:52,362 CRITICAL: critical18! 
2010-11-05 12:33:52,369 WARNING: warning19! 
[email protected]~: cat /tmp/log/myapp.log.2 
2010-11-05 12:33:52,355 WARNING: warning18! 
2010-11-05 12:33:52,362 ERROR: error18! 
[email protected]~: cat /tmp/log/myapp.log.3 
2010-11-05 12:33:52,348 ERROR: error17! 
2010-11-05 12:33:52,355 CRITICAL: critical17! 
[email protected]~: cat /tmp/log/myapp.log.4 
2010-11-05 12:33:52,340 CRITICAL: critical16! 
2010-11-05 12:33:52,348 WARNING: warning17! 
[email protected]~: cat /tmp/log/myapp.log.5 
2010-11-05 12:33:52,333 WARNING: warning16! 
2010-11-05 12:33:52,340 ERROR: error16! 
[email protected]~: 

正如你所看到的,我们失去了很多日志(0-15),但最近都在那里,保留用户的自由空间。不要忘记从下往上看日志:)