Request Attributes in Log Messages
What It Does
The pyramid_log distribution includes a Python logging formatter
which makes Pyramid request attributes available for use in its
format string. Specifically,
pyramid_log.Formatter is special in
the following ways:
- It sets a
.requestattribute on the log record (if one doesn’t already exist.)
- It supports dotted attribute access in its format string. For
"%(request.matched_route.name)s"will work in the format string.
- There is a syntax for explicitly specifying fallback values. For
example, a format string of
"%(request.method|<no request>)s"will format to
"<no request>"if there is no current request (or if the current request has no
The pyramid request has many attributes which can be useful when included in the logs of a web app. These include, but are not limited to:
See the Pyramid documentation for a more complete list of available request attributes.
pip install pyramid-log
It has been tested on python 2.7, 3.4–3.6 and pypy.
Development happens at https://github.com/dairiki/pyramid_log/.
Configuring Logging in a File
If you configure logging in your application configuration (or some other) file you can do something like:
[loggers] key = root [handlers] keys = console [formatters] keys = pyramid [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = pyramid [formatter_pyramid] # NB: Here is the interesting part! class = pyramid_log.Formatter format = %(asctime)s %(request.method|no request)s %(request.path_qs|)s %(levelname)-5.5s [%(name)s] %(message)s
This will result in your log messages looking something like:
2014-10-01 17:55:02,001 GET /path?arg=foo WARNI [myapp.views] This is some log message!
You can of course configure logging imperatively. For example, with:
import logging from pyramid_log import Formatter fmt = Formatter( '%(asctime)s %(request.client_addr|-)s' ' %(request.method|-)s %(request.path_qs|-)s: %(message)s') logging.basicConfig() root_logger = logging.getLogger() for handler in root_logger.handlers: handler.setFormatter(fmt)
Then, a view can log a message like so:
log = logging.getLogger(__name__) @view_config(name='persimmon') def persimmon_view(request): log.warning("%s was called!", request.view_name)
Which will yield a log message like:
2014-10-01 17:55:02,001 192.168.1.1 GET /persimmon: persimmon was called
Accessing Dict-like Values
The dot notation can be used to access not only instance attributes,
but also to access items in
dict-like values. Attribute access is
tried first; if there is no attribute of the given name, then the
__getitem__ method is tried. For example,
"%(request.matchdict.id)s" will get at
Explicit fallback values are always interpreted as strings, however,
if the fallback is used in a numeric context, an attempt will be made
at conversion to the requested type. For example, if there is no
"%+(request.status_code|555)d" will format to
If the fallback string can not be converted to a numeric value, then
0 (zero) is used in integer contexts and NaN is used in
Default Fallback Values
If no fallback value is explicitly specified, then a default fallback
value will be used if the requested attribute does not exist. The
missing attribute name is included in the default fallback value. For
"%(request.method)s" will produce
if there is no current request.
The pyramid_logging distribution provides similar functionality.
Jeff Dairiki <email@example.com>