登录中

Pyramid 允许您使用Python标准库 logging 模块。本章介绍如何配置日志,以及如何将日志消息发送到您配置的记录器。

警告

本章假设您使用了 cookiecutter 创建包含 development.iniproduction.ini 帮助配置日志记录的文件。塔架项目提供的金字塔炊具就是这样做的。如果您没有使用我们的CookieCutter,或者您使用了没有创建这些文件的第三方CookieCutter,则本章中的配置信息可能不适用。

日志记录配置

A Pyramid 从我们创建的项目 cookiecutter 配置为允许您将消息发送到 Python standard library logging package 应用程序中的记录器。尤其是, PasteDeploy development.iniproduction.ini 使用我们的cookiecutter时创建的文件包括Python的基本配置 logging 包裹。这些 .ini 文件节传递到 logging module's config file configuration engine .

PasteDeploy .ini 文件使用python标准库 ConfigParser format . 这与Python使用的格式相同 logging module's Configuration file format . 配置文件中与应用程序相关的部分和日志相关的部分可以和平共存。文件中与日志记录相关的部分在运行时配置日志记录 pserve .

如果配置 .ini 文件,调用时指定 pserve 包含一个 [loggers] 然后节 startup 以下过程发生:

  1. 这个 pserve 命令调用 pyramid.paster.setup_logging() 函数,传递 .ini 文件。
  2. setup_logging 是一个薄包装,它调用Python标准库的 logging.config.fileConfig() .
  3. logging.config.fileConfig() 从中读取日志配置 .ini 文件和配置日志记录。

默认日志配置在两个默认值中都提供 development.ini 以及 production.ini 文件夹。如果您使用我们的cookiecutter生成一个名为 hello_world ,然后是中的日志配置 development.ini 文件如下:

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###

[loggers]
keys = root, myproject

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_myproject]
level = DEBUG
handlers =
qualname = myproject

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s

这个 production.ini 文件使用 WARN 其记录器配置中的级别,而不是 DEBUG ,但在其他方面是相同的。

在此日志配置中:

  • 名为记录器 root 创建的日志级别高于或等于 INFO 级别为stderr,格式如下:

    2007-08-17 15:04:08,704 INFO [packagename] Loading resource, id: 86
    
  • 名为记录器 myproject 配置为记录以高于或等于的级别发送的消息 DEBUG 以与根记录器相同的格式发送到stderr。

这个 root 在金字塔进程中,所有需要记录器的应用程序都将使用记录器(通过 logging.getLogger )它的名称以除项目包名称以外的任何内容开头(例如, myproject )与包名称同名的记录器保留供您在 Pyramid 应用。它的存在意味着您可以从任何 Pyramid 通过我们的cookiecutter生成的应用程序。

Pyramid 许多其他的库(如烧杯、SQLAlchemy、Paste)将一些消息记录到根日志记录器中,以便进行调试。将根记录器级别切换为 DEBUG 揭示它们:

[logger_root]
#level = INFO
level = DEBUG
handlers = console

一些配置 Pyramid cookiecutter为使用的其他子系统(如sqlacalchemy)配置其他记录器。看看 production.inidevelopment.ini 从我们的CookieCutter创建项目时呈现的文件。

发送日志消息

Python 的特色菜 __name__ 变量引用当前模块的完全限定名。从名为 myproject , the __name__ 内置变量总是类似于 myprojectmyproject.subpackagemyproject.package.subpackage 如果您的项目已命名 myproject . 将消息发送到此记录器将其发送到 myproject 记录器。

将消息记录到您的 .ini 文件,只需使用 __name__ 内置并对其调用方法。

1
2
3
4
5
6
7
8
9
import logging
log = logging.getLogger(__name__)

def myview(request):
    content_type = 'text/plain'
    content = 'Hello World!'
    log.debug('Returning: %s (content-type: %s)', content, content_type)
    request.response.content_type = content_type
    return request.response

这将导致以下内容打印到控制台上, stderr

16:20:20,440 DEBUG [myproject.views] Returning: Hello World!
                   (content-type: text/plain)

筛选日志消息

通常有太多的日志输出需要筛选,例如当将根日志记录器的级别切换到 DEBUG .

例如,您正在诊断应用程序中的数据库连接问题,只想查看sqlachemy的 DEBUG 与数据库连接池相关的消息。您可以将根日志记录器的级别保留在不太冗长的级别。 INFO 级别并将特定的sqlAlchemy记录器设置为 DEBUG 除根记录器外,单独使用:

[logger_sqlalchemy.pool]
level = DEBUG
handlers =
qualname = sqlalchemy.pool

然后将其添加到记录器列表中:

[loggers]
keys = root, myproject, sqlalchemy.pool

无需为此记录器配置任何处理程序,因为默认情况下,非根记录器会将其日志记录传播到其父记录器的处理程序。根记录器是所有记录器的顶级父级。

默认情况下使用此技术 development.ini . 根记录器的级别设置为 INFO ,而应用程序的日志级别设置为 DEBUG

# Begin logging configuration

[loggers]
keys = root, myproject

[logger_myproject]
level = DEBUG
handlers =
qualname = myproject

所有的儿童记录员 myproject 记录器将继承 DEBUG 除非它们被明确地设置为不同的级别。意味着 myproject.viewsmyproject.models 默认情况下,应用程序的所有模块记录器的有效级别为 DEBUG 也是。

对于更高级的筛选,日志模块提供 logging.Filter 对象;但是不能直接从配置文件中使用。

高级配置

要将日志输出捕获到单独的文件,请使用 logging.FileHandler (或) logging.handlers.RotatingFileHandler ):

[handler_filelog]
class = FileHandler
args = ('%(here)s/myproject.log','a')
level = INFO
formatter = generic

在识别它之前,需要将它添加到处理程序列表中:

[handlers]
keys = console, myproject, filelog

最后被记录器利用。

[logger_root]
level = INFO
handlers = console, filelog

最后三行配置将根记录器的所有输出定向到 myproject.log 以及控制台。

异常日志

记录或通过电子邮件发送您的 Pyramid 应用程序,使用 pyramid_exclog 包裹。其配置的详细信息位于 documentation .

请求使用Paste的Translogger进行日志记录

这个 WSGI 设计是模块化的。服务生记录错误情况、调试输出等,但不记录Web流量。对于Web流量日志记录,Paste提供 TransLogger middleware . Translogger在 Apache Combined Log Format . 但是translogger不写入文件;必须配置python日志记录系统才能这样做。 Python logging.FileHandler 日志处理程序可以与Translogger一起使用来创建 access.log 类似于Apache的文件。

像任何标准一样 middleware 使用粘贴入口点,Translogger可以配置为使用 .ini 文件语法。首先重命名金字塔 .ini 文件的 [app:main] 截面至 [app:mypyramidapp] 然后添加一个 [filter:translogger] 第节,然后使用 [pipeline:main] 使用Translogger和您的应用程序组成WSGi管道的节文件。例如,从此处更改:

[app:main]
use = egg:myproject

对此:

[app:mypyramidapp]
use = egg:myproject

[filter:translogger]
use = egg:Paste#translogger
setup_console_handler = False

[pipeline:main]
pipeline = translogger
           mypyramidapp

以这种方式使用PasteDeploy来形成和服务管道相当于通过 main 项目的功能 __init__ 文件:

# ...
app = config.make_wsgi_app()
from paste.translogger import TransLogger
app = TransLogger(app, setup_console_handler=False)
return app

注解

Translogger在没有参数的情况下调用时将自动在控制台上设置一个日志处理程序,因此它在不配置日志记录的环境中“只是工作”。由于配置了日志处理程序,因此我们通过 setup_console_handler = False .

在过滤器就位的情况下,Translogger的记录器(命名为 wsgi logger)将其日志消息传播到父日志记录器(根日志记录器),当我们请求一个页面时,将其输出发送到控制台:

00:50:53,694 INFO [myproject.views] Returning: Hello World!
                  (content-type: text/plain)
00:50:53,695 INFO [wsgi] 192.168.1.111 - - [11/Aug/2011:20:09:33 -0700] "GET /hello
HTTP/1.1" 404 - "-"
"Mozilla/5.0 (Macintosh; U; Intel macOS; en-US; rv:1.8.1.6) Gecko/20070725
Firefox/2.0.0.6"

将音译器指向 access.log 文件处理程序,我们需要以下内容来添加一个文件处理程序(名为 accesslog )到处理程序列表,并确保 wsgi 记录器已配置并相应地使用此处理程序:

# Begin logging configuration

[loggers]
keys = root, myproject, wsgi

[handlers]
keys = console, accesslog

[logger_wsgi]
level = INFO
handlers = accesslog
qualname = wsgi
propagate = 0

[handler_accesslog]
class = FileHandler
args = ('%(here)s/access.log','a')
level = INFO
formatter = generic

如上所述,默认情况下,非根日志记录器将其日志记录传播到根日志记录器的处理程序(当前是控制台处理程序)。设置 propagate0 (False )这里禁用这个;所以 wsgi 记录器只将其记录指向 accesslog 处理程序。

最后,不需要使用 generic 将translogger作为translogger的格式化程序本身提供了我们需要的所有信息。我们将使用格式化程序按原样传递日志消息。添加名为 accesslog 通过在配置文件中包含以下内容:

[formatters]
keys = generic, accesslog

[formatter_accesslog]
format = %(message)s

最后更改现有配置以连接新的 accesslog 格式化程序到文件处理程序:

[handler_accesslog]
class = FileHandler
args = ('%(here)s/access.log','a')
level = INFO
formatter = accesslog