1"""
2Example: using a logging context.
3
4This example uses a instance-level dictionary to inject values into
5log messages. This is useful when you are writing code that processes
6messages repeatedly (e.g., a poller or consumer) and each message has
7it's own contextual identifier. At the start of message processing,
8you clear the context and store the contextual identifier that you want
9to appear in each log message. Use this in conjunction with the
10:class:`jsonscribe.AttributeSetter` to ensure that the value is always
11present and you can use it in logging format lines without exploding.
12
13Note that this pattern can be used with or without the JSON formatter
14since it is simply a usage of :class:`logging.LoggerAdapter`.
15
16"""
17import logging
18import uuid
19
20import jsonscribe
21
22
23class Processor(object):
24 def __init__(self):
25 self.context = {}
26 logger = logging.getLogger('adapter.Processor')
27 self.logger = logging.LoggerAdapter(logger, self.context)
28
29 def prepare(self, message):
30 self.context.clear()
31 self.context['correlation_id'] = message.get('correlation_id',
32 uuid.uuid4())
33
34 def process(self, message):
35 self.logger.info('processing %r', message['body'])
36
37
38if __name__ == '__main__':
39 logging.basicConfig(
40 level=logging.INFO,
41 format=('%(levelname)1.1s %(name)s: %(message)s'
42 '\t{correlation_id=%(correlation_id)s}'))
43 root_logger = logging.getLogger()
44 handler = root_logger.handlers[0]
45 handler.addFilter(
46 jsonscribe.AttributeSetter(
47 add_fields={'correlation_id': 'ext://UUID'}))
48
49 processor = Processor()
50 for i in range(0, 10):
51 msg = {
52 'correlation_id': str(uuid.uuid4()),
53 'body': [i for i in range(0, i)]
54 }
55 processor.prepare(msg)
56 processor.process(msg)