ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 02.01.2026

Просмотров: 2736

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

18.1. LOGGING CONFIGURATION

1 pcreate -s starter MyApp

The logging configuration will literally be:

1 # Begin logging configuration

2

3 [loggers]

4

keys

=

root, myapp

5

 

 

 

6

[handlers]

7

keys

=

console

8

 

 

 

9 [formatters]

10 keys = generic

11

12[logger_root]

13level = INFO

14handlers = console

15

16[logger_myapp]

17level = DEBUG

18handlers =

19qualname = myapp

20

21[handler_console]

22class = StreamHandler

23args = (sys.stderr,)

24level = NOTSET

25formatter = generic

26

27[formatter_generic]

28format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

29

30 # End logging configuration

In this logging configuration:

a logger named root is created that logs messages at a level above or equal to the INFO level to stderr, with the following format:

2007-08-17 15:04:08,704 INFO [packagename]

Loading resource, id: 86

199

18. LOGGING

a logger named myapp is configured that logs messages sent at a level above or equal to DEBUG to stderr in the same format as the root logger.

The root logger will be used by all applications in the Pyramid process that ask for a logger (via logging.getLogger) that has a name which begins with anything except your project’s package name (e.g. myapp). The logger with the same name as your package name is reserved for your own usage in your Pyramid application. Its existence means that you can log to a known logging location from any Pyramid application generated via a scaffold.

Pyramid and many other libraries (such as Beaker, SQLAlchemy, Paste) log a number of messages to the root logger for debugging purposes. Switching the root logger level to DEBUG reveals them:

[logger_root]

#level = INFO level = DEBUG handlers = console

Some scaffolds configure additional loggers for additional subsystems they use (such as SQLALchemy). Take a look at the production.ini and development.ini files rendered when you create a project from a scaffold.

18.2 Sending Logging Messages

Python’s special __name__ variable refers to the current module’s fully qualified name. From any module in a package named myapp, the __name__ builtin variable will always be something like myapp, or myapp.subpackage or myapp.package.subpackage if your project is named myapp. Sending a message to this logger will send it to the myapp logger.

To log messages to the package-specific logger configured in your .ini file, simply create a logger object using the __name__ builtin and call methods on it.

1import logging

2log = logging.getLogger(__name__)

3

4def myview(request):

5 content_type = ’text/plain’

6content = ’Hello World!’

7 log.debug(’Returning: %s (content-type: %s)’, content, content_type) 8 request.response.content_type = content_type

9return request.response

This will result in the following printed to the console, on stderr:

200



18.3. FILTERING LOG MESSAGES

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

18.3 Filtering log messages

Often there’s too much log output to sift through, such as when switching the root logger’s level to DEBUG.

An example: you’re diagnosing database connection issues in your application and only want to see SQLAlchemy’s DEBUG messages in relation to database connection pooling. You can leave the root logger’s level at the less verbose INFO level and set that particular SQLAlchemy logger to DEBUG on its own, apart from the root logger:

[logger_sqlalchemy.pool] level = DEBUG

handlers =

qualname = sqlalchemy.pool

then add it to the list of loggers:

[loggers]

keys = root, myapp, sqlalchemy.pool

No handlers need to be configured for this logger as by default non root loggers will propagate their log records up to their parent logger’s handlers. The root logger is the top level parent of all loggers.

This technique is used in the default development.ini. The root logger’s level is set to INFO, whereas the application’s log level is set to DEBUG:

# Begin logging configuration

[loggers]

keys = root, myapp

[logger_myapp] level = DEBUG handlers =

qualname = helloworld

201

18. LOGGING

All of the child loggers of the myapp logger will inherit the DEBUG level unless they’re explicitly set differently. Meaning the myapp.views, myapp.models (and all your app’s modules’) loggers by default have an effective level of DEBUG too.

For more advanced filtering, the logging module provides a Filter object; however it cannot be used directly from the configuration file.

18.4 Advanced Configuration

To capture log output to a separate file, use a FileHandler (or a RotatingFileHandler):

[handler_filelog] class = FileHandler

args = (’%(here)s/myapp.log’,’a’) level = INFO

formatter = generic

Before it’s recognized, it needs to be added to the list of handlers:

[handlers]

keys = console, myapp, filelog

and finally utilized by a logger.

[logger_root] level = INFO

handlers = console, filelog

These final 3 lines of configuration directs all of the root logger’s output to the myapp.log as well as the console.

18.5 Logging Exceptions

To log (or email) exceptions generated by your Pyramid application, use the pyramid_exclog package. Details about its configuration are in its documentation.

202

18.6.REQUEST LOGGING WITH PASTE’S TRANSLOGGER

18.6Request Logging with Paste’s TransLogger

Paste provides the TransLogger middleware for logging requests using the Apache Combined Log Format. TransLogger combined with a FileHandler can be used to create an access.log file similar to Apache’s.

Like any standard middleware with a Paste entry point, TransLogger can be configured to wrap your application using .ini file syntax. First, rename your Pyramid .ini file’s [app:main] section to [app:mypyramidapp], then add a [filter:translogger] section, then use a

[pipeline:main] section file to form a WSGI pipeline with both the translogger and your application in it. For instance, change from this:

[app:main]

use = egg:MyProject

To this:

[app:mypyramidapp] use = egg:MyProject

[filter:translogger]

use = egg:Paste#translogger setup_console_handler = False

[pipeline:main] pipeline = translogger

mypyramidapp

Using PasteDeploy this way to form and serve a pipeline is equivalent to wrapping your app in a TransLogger instance via the bottom the main function of your project’s __init__ file:

...

app = config.make_wsgi_app()

from paste.translogger import TransLogger

app = TransLogger(app, setup_console_handler=False) return app

TransLogger will automatically setup a logging handler to the console when called with no arguments, so it ‘just works’ in environments that don’t configure logging. Since we’ve configured our own logging handlers, we need to disable that option via setup_console_handler = False.

With the filter in place, TransLogger’s logger (named the ‘wsgi’ logger) will propagate its log messages to the parent logger (the root logger), sending its output to the console when we request a page:

203


18. LOGGING

00:50:53,694 INFO [myapp.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 Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"

To direct TransLogger to an access.log FileHandler, we need to add that FileHandler to the wsgi logger’s list of handlers:

# Begin logging configuration

[loggers]

keys = root, myapp, wsgi

[logger_wsgi] level = INFO

handlers = handler_accesslog qualname = wsgi

propagate = 0

[handler_accesslog] class = FileHandler

args = (’%(here)s/access.log’,’a’) level = INFO

formatter = generic

As mentioned above, non-root loggers by default propagate their log records to the root logger’s handlers (currently the console handler). Setting propagate to 0 (false) here disables this; so the wsgi logger directs its records only to the accesslog handler.

Finally, there’s no need to use the generic formatter with TransLogger as TransLogger itself provides all the information we need. We’ll use a formatter that passes-through the log messages as is:

[formatters]

keys = generic, accesslog

[formatter_accesslog] format = %(message)s

Then wire this new accesslog formatter into the FileHandler:

204

18.6. REQUEST LOGGING WITH PASTE’S TRANSLOGGER

[handler_accesslog] class = FileHandler

args = (’%(here)s/access.log’,’a’) level = INFO

formatter = accesslog

205

18. LOGGING

206


CHAPTER

NINETEEN

PASTEDEPLOY CONFIGURATION FILES

Packages generated via a scaffold make use of a system created by Ian Bicking named PasteDeploy. PasteDeploy defines a way to declare WSGI application configuration in an .ini file.

Pyramid uses this configuration file format in input to its WSGI server runner pserve, as well as other commands such as pviews, pshell, proutes, and ptweens.

PasteDeploy is not a particularly integral part of Pyramid. It’s possible to create a Pyramid application which does not use PasteDeploy at all. We show a Pyramid application that doesn’t use PasteDeploy in Creating Your First Pyramid Application. However, all Pyramid scaffolds render PasteDeploy configuration files, to provide new developers with a standardized way of setting deployment values, and to provide new users with a standardized way of starting, stopping, and debugging an application.

This chapter is not a replacement for documentation about PasteDeploy; it only contextualizes the use of PasteDeploy within Pyramid. For detailed documentation, see http://pythonpaste.org.

19.1 PasteDeploy

PasteDeploy is the system that Pyramid uses to allow deployment settings to be spelled using an .ini configuration file format. It also allows the pserve command to work. Its configuration format provides a convenient place to define application deployment settings and WSGI server settings, and its server runner allows you to stop and start a Pyramid application easily.

207

19. PASTEDEPLOY CONFIGURATION FILES

19.1.1 Entry Points and PasteDeploy .ini Files

In the Creating a Pyramid Project chapter, we breezed over the meaning of a configuration line in the deployment.ini file. This was the use = egg:MyProject line in the [app:main] section. We breezed over it because it’s pretty confusing and “too much information” for an introduction to the system. We’ll try to give it a bit of attention here. Let’s see the config file again:

1

[app:main]

 

2

use = egg:MyProject

 

3

 

 

4

pyramid.reload_templates

= true

5

pyramid.debug_authorization = false

6

pyramid.debug_notfound =

false

7

pyramid.debug_routematch

= false

8

pyramid.default_locale_name = en

9

pyramid.includes =

 

10

pyramid_debugtoolbar

 

11

 

 

12[server:main]

13use = egg:waitress#main

14host = 0.0.0.0

15port = 6543

16

17 # Begin logging configuration

18

19[loggers]

20keys = root, myproject

21

22[handlers]

23keys = console

24

25[formatters]

26keys = generic

27

28[logger_root]

29level = INFO

30handlers = console

31

32[logger_myproject]

33level = DEBUG

34handlers =

35qualname = myproject

36

37[handler_console]

38class = StreamHandler

39args = (sys.stderr,)

208