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
.request
attribute on the log record (if one doesn’t already exist.) - It supports dotted attribute access in its format string. For
example,
"%(request.method)s"
and even"%(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 nomethod
attribute.)
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:
request.method
request.url
(orrequest.path
,request.path_qs
, etc…)request.unauthenticated_userid
request.client_addr
request.GET
(orrequest.POST
orrequest.params
)request.matched_route.name
,request.view_name
See the Pyramid documentation for a more complete list of available request attributes.
The distribution may be downloaded from pypi, but it may be easier to install using pip:
pip install pyramid-log
It has been tested on python 3.7–3.11 and pypy.
Development happens at https://github.com/dairiki/pyramid_log/.
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!
Refer to Pyramid’s chapter on logging and the documentation for the Python logging module’s configuration file format for more details on how this works.
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
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
instances __getitem__
method is tried. For example,
"%(request.matchdict.id)s"
will get at
request.matchdict['id']
.
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, "%+(request.status_code|555)d"
will format to "+555"
.
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 float
contexts.
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
example "%(request.method)s"
will produce "<?request.method?>"
if there is no current request.
The pyramid_logging distribution provides similar functionality.
Jeff Dairiki <[email protected]>