Python日志仅记录到文件

10

我有一个cronjob运行一个Python脚本,我添加了logging,但由于它是每天运行一次,所以我每天都会收到它功能的电子邮件通知,但我似乎找不到一个设置,可以让它只记录到日志文件中。

#!/usr/bin/python
import logging, logging.handlers
LOGFILENAME = "log.log" 
logging.basicConfig()
log = logging.getLogger("nameoflog")
log.setLevel(logging.DEBUG) 
handler = logging.handlers.WatchedFileHandler(LOGFILENAME)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter("%(asctime)-15s %(levelname)-8s %(name)s %(message)s")) 
log.addHandler(handler)
log.info("something happening")

如何使logging只写入文件而不是同时写入文件和STDOUT

3个回答

9
问题在于您调用了logging.basicConfig(),这会将日志设置为stdoutbasicConfig只是一个帮助方法,用于当您不想进行更详细的日志记录调用时使用。由于您自己设置了方法,因此不应调用basicConfig

2

这是一个对我有效的示例(它不会将消息打印到 stdout,而只会打印到 example.log):

def logToFile():
    import logging
    logging.basicConfig(filename='example.log',level=logging.DEBUG)
    logging.info("trying to log to file")

logToFile()

1

在Python中记录日志可能很复杂,而默认的日志模块由于将流处理程序附加到根记录器而存在一些限制。 它不提供直接记录消息到文件而不将其记录到控制台的简单方法。 本文介绍的FileLogger类扩展了内置的记录功能以克服此限制, 使您可以将消息记录到文件和控制台,或者如果需要,仅记录到文件。

class FileLogger(logging.Logger):
def __init__(self, name, filename, mode='a', level=logging.INFO, fformatter=None, log_to_console=False, sformatter=None):
    super().__init__(name, level)

    # Create a custom file handler
    self.file_handler = logging.FileHandler(filename=filename, mode=mode)

    # Set the formatter for the file handler
    if fformatter is not None:
        self.file_handler.setFormatter(fformatter)

    # Add the file handler to the logger
    self.addHandler(self.file_handler)

    if log_to_console:
        # Create a console handler
        self.console_handler = logging.StreamHandler()  # Prints to the console

        # Set the formatter for the console handler
        if not sformatter:
            sformatter = fformatter
        self.console_handler.setFormatter(sformatter)

        # Add the console handler to the logger
        self.addHandler(self.console_handler)


def fdebug(self, msg, pre_msg=''):
    if pre_msg:
        print(pre_msg)
    self.debug(msg)

def finfo(self, msg):
    self.info(msg)

def fwarn(self, msg):
    self.warning(msg)

def ferror(self, msg):
    self.error(msg)

def fcritical(self, msg):
    self.critical(msg)



# Test the logging
if __name__ == '__main__':
    s_log_level = logging.CRITICAL
    file_log_level = logging.WARN
    log_format = "[%(asctime)s.%(msecs)03d] %(message)s"
    log_fp = f'tmp.log'

    logging.basicConfig(format=log_format, level=s_log_level, datefmt="%H:%M:%S")

    # Create an instance of the custom logger
    formatter = logging.Formatter(log_format, "%H:%M:%S")
    fLogger = FileLogger(__name__, log_fp, mode='a', level=file_log_level, fformatter=formatter)
    
    fLogger.fdebug("This will be logged to file with DEBUG level")
    fLogger.finfo("This will be logged to file with INFO level")
    fLogger.fwarn("This will be logged to file with WARNING level")
    fLogger.ferror("This will be logged to file with ERROR level")
    fLogger.fcritical("This will be logged to file with CRITICAL level")

    logging.debug("This Debug will be logged to console")
    logging.info("This info will be logged to console")
    logging.warning("This warning also be logged to console")
    logging.critical("This critical also be logged to console")

在这个解决方案中,FileLogger 类扩展了 logging.Logger 类,并提供了将消息独占记录到文件的能力。FileLogger 类的构造函数接受日志文件名(filename)和模式(mode)参数,允许自定义日志文件行为。
要使用此解决方案,只需创建 FileLogger 类的实例并在记录器实例上调用记录方法(info、debug、warning 等)。日志消息将仅写入指定的日志文件。
请记得调整 filename 参数以设置所需的日志文件名,并更改 mode 参数以控制日志文件的行为(例如,'a' 用于追加,'w' 用于覆盖)。

我还创建了同样代码的gist: https://gist.github.com/meta-ks/217ce41fc215e69a630db576bbbd23bc - kappa101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接