Python日志,如何为同一个项目的多个脚本使用一个日志记录器(Python 2.7)?

yh2wf1be  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(438)

对于任何需要保留运行历史的脚本,我使用以下代码通过logging模块创建一个日志记录进程,并将其复制粘贴进去:

from datetime import datetime
    import logging
    from logging import handlers
   
    dt_now = datetime.today().strftime('%Y%m%d')
    sender = 'sender@domainname.com'
    recipients ='recipient@domainname.com'
    sub_err = "Process Failed"

    # Set up logging 
    log_file = ("//some_server/some_dir/another_dir/"
                "logs/{}.txt".format(dt_now))
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    file_handle = logging.FileHandler(log_file)
    stream_handle = logging.StreamHandler()
    email_handle = handlers.SMTPHandler(mailhost="mailhost.domain.com",
                                                fromaddr=sender,
                                                toaddrs=recipients,
                                                subject=sub_err,
                                                secure=None)
    email_handle.setLevel(logging.WARNING)
    file_handle.setLevel(logging.DEBUG)
    stream_handle.setLevel(logging.DEBUG)
    log_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handles = [email_handle, file_handle, stream_handle]
    for handle in handles:
        handle.setFormatter(log_format)
        logger.addHandler(handle)

这对我来说很有效,它将所有内容记录到一个文件中,如果遇到异常,它会向我发送电子邮件,如果我正在调试一个脚本,它会打印到控制台。现在对于任何项目来说,我通常有2个或更多的脚本,我通常做的是复制并粘贴到每个脚本中,我会得到一个过程的日志文件。此外,我通常有一个项目模块,其中包含一些两个脚本都会使用的常用函数。我想知道的是,我将如何在这个公共文件中放置日志记录过程,以便每个脚本都只导入它,并使用所有相同的句柄和日志文件。

dbf7pr2w

dbf7pr2w1#

正如@chepner所评论的,您可以创建一个函数来启用日志记录器,也可以创建一个日志配置文件,通过logging.config.fileConfig解析该文件。

功能

您可以创建一个函数,使用正确的处理程序创建日志记录器。请注意,在整个应用程序运行期间,此函数只需调用一次。实际上,logging配置是在整个应用程序中全局定义的。

def init_logging():
    from datetime import datetime
    import logging
    from logging import handlers

    dt_now = datetime.today().strftime('%Y%m%d')
    sender = 'sender@domainname.com'
    recipients ='recipient@domainname.com'
    sub_err = "Process Failed"

    # Set up logging 
    log_file = ("//some_server/some_dir/another_dir/logs/{}.txt".format(dt_now))
    logger = logging.getLogger("foobar")
    logger.setLevel(logging.DEBUG)
    file_handle = logging.FileHandler(log_file)
    stream_handle = logging.StreamHandler()
    email_handle = handlers.SMTPHandler(
        mailhost="mailhost.domain.com",
        fromaddr=sender,
        toaddrs=recipients,
        subject=sub_err,
        secure=None
    )
    email_handle.setLevel(logging.WARNING)
    file_handle.setLevel(logging.DEBUG)
    stream_handle.setLevel(logging.DEBUG)
    log_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handles = [email_handle, file_handle, stream_handle]
    for handle in handles:
        handle.setFormatter(log_format)
        logger.addHandler(handle)

然后,您可以在任何脚本中使用此处创建的日志记录器,如下所示:

from .logging import init_logging

init_logging()

# foobar is accessible, and has all the handlers as defined in init_logging
foobarlogger = getLogger("foobar")
foobarlogger.info("Hello, world!")
    • 注:**由于处理程序的定义是全局的,您也可以将代码放在模块的__init__.py文件中,而不是放在函数中,在第一次导入时定义它,并使其在整个应用中可用。

fileConfig

另一种方法是使用logging.config.fileConfig,你可以在这个文件中设置你的日志处理器,记录器,格式化器等等。
创建logging.conf文件:

[loggers]
keys=root, foobar

[handlers]
keys=console, file, email

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=console

[logger_foobar]
level=DEBUG
handlers=file, console, email
qualname=foobar
propagate=0

[handler_file]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=({"/some_server/some_dir/another_dir/logs/log.txt"})

[handler_console]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter

[handler_email]
class=handlers.SMTPHandler
level=WARNING
args=('mailhost.domain.com', 'sender@domainname.com', ['recipient@domainname.com'], 'Process Failed')
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s - %(levelname)s - %(message)s

然后,您可以加载此文件并使用以下命令创建所有日志环境:

import logging.config

# only do it once, since the loaded logging config is global!
logging.config.fileConfig("logging.conf")

# then, in any file, you can do:
foobarlogger = logging.getLogger("foobar")
foobarlogger.info("Hello, world!")

相关问题