Merged doc update from 3.3.
This commit is contained in:
commit
88069d217a
|
@ -1613,3 +1613,78 @@ The formatted message *will* be encoded using UTF-8 encoding by
|
||||||
RFC 5424-compliant messages. If you don't, logging may not complain, but your
|
RFC 5424-compliant messages. If you don't, logging may not complain, but your
|
||||||
messages will not be RFC 5424-compliant, and your syslog daemon may complain.
|
messages will not be RFC 5424-compliant, and your syslog daemon may complain.
|
||||||
|
|
||||||
|
|
||||||
|
Implementing structured logging
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Although most logging messages are intended for reading by humans, and thus not
|
||||||
|
readily machine-parseable, there might be cirumstances where you want to output
|
||||||
|
messages in a structured format which *is* capable of being parsed by a program
|
||||||
|
(without needed complex regular expressions to parse the log message). This is
|
||||||
|
straightforward to achieve using the logging package. There are a number of
|
||||||
|
ways in which this could be achieved, but the following is a simple approach
|
||||||
|
which uses JSON to serialise the event in a machine-parseable manner::
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
class StructuredMessage(object):
|
||||||
|
def __init__(self, message, **kwargs):
|
||||||
|
self.message = message
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '%s >>> %s' % (self.message, json.dumps(self.kwargs))
|
||||||
|
|
||||||
|
_ = StructuredMessage # optional, to improve readability
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
||||||
|
logging.info(_('message 1', foo='bar', bar='baz', num=123, fnum=123.456))
|
||||||
|
|
||||||
|
If the above script is run, it prints::
|
||||||
|
|
||||||
|
message 1 >>> {"fnum": 123.456, "num": 123, "bar": "baz", "foo": "bar"}
|
||||||
|
|
||||||
|
If you need more specialised processing, you can use a custom JSON encoder,
|
||||||
|
as in the following complete example::
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
try:
|
||||||
|
unicode
|
||||||
|
except NameError:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
|
class Encoder(json.JSONEncoder):
|
||||||
|
def default(self, o):
|
||||||
|
if isinstance(o, set):
|
||||||
|
return tuple(o)
|
||||||
|
elif isinstance(o, unicode):
|
||||||
|
return o.encode('unicode_escape').decode('ascii')
|
||||||
|
return super(Encoder, self).default(o)
|
||||||
|
|
||||||
|
class StructuredMessage(object):
|
||||||
|
def __init__(self, message, **kwargs):
|
||||||
|
self.message = message
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
s = Encoder().encode(self.kwargs)
|
||||||
|
return '%s >>> %s' % (self.message, s)
|
||||||
|
|
||||||
|
_ = StructuredMessage
|
||||||
|
|
||||||
|
def main():
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
||||||
|
logging.info(_('message 1', set_value=set([1, 2, 3]), snowman='\u2603'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
When the above script is run, it prints::
|
||||||
|
|
||||||
|
message 1 >>> {"snowman": "\u2603", "set_value": [1, 2, 3]}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue