diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2013-01-22 15:58:34 (GMT) |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2013-01-22 15:58:34 (GMT) |
commit | 88069d217abc03ae2563f240b8f1e1fadd9f1acc (patch) | |
tree | ebf755b78b57ea200cd0425aecb46dc0ca6ad343 /Doc/howto/logging-cookbook.rst | |
parent | cc0172c00704e8292c90e02e776b0c193ca75477 (diff) | |
parent | a3bdce8c914c38f985fc70589488d0d01019250b (diff) | |
download | cpython-88069d217abc03ae2563f240b8f1e1fadd9f1acc.zip cpython-88069d217abc03ae2563f240b8f1e1fadd9f1acc.tar.gz cpython-88069d217abc03ae2563f240b8f1e1fadd9f1acc.tar.bz2 |
Merged doc update from 3.3.
Diffstat (limited to 'Doc/howto/logging-cookbook.rst')
-rw-r--r-- | Doc/howto/logging-cookbook.rst | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index b336a4a..a61d24b 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -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 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]} + |