Repository URL to install this package:
| 
      
     
      
        
        
        Version: 
        
         
  
        
    
          
          0.4.139  ▾
        
         
  
      
        
      
  
      
  
     | 
    
    lib-py-b2b
  
    /
        logging.py
    | 
|---|
import json
import logging
from lib_b2b.util import UtilityEncoder
def json_formatter(obj):
    """Formatter for unserialisable values."""
    return str(obj)
class JsonFormatter(logging.Formatter):
    """AWS Lambda Logging formatter.
    Formats the log message as a JSON encoded string.  If the message is a
    dict it will be used directly.  If the message can be parsed as JSON, then
    the parse d value is used in the output record.
    """
    def __init__(self, **kwargs):
        """Return a JsonFormatter instance.
        The `json_default` kwarg is used to specify a formatter for otherwise
        unserialisable values.  It must not throw.  Defaults to a function that
        coerces the value to a string.
        Other kwargs are used to specify log field format strings.
        """
        datefmt = kwargs.pop('datefmt', None)
        super(JsonFormatter, self).__init__(datefmt=datefmt)
        self.format_dict = {
            'timestamp': '%(asctime)s',
            'level': '%(levelname)s',
            'location': '%(name)s.%(funcName)s:%(lineno)d',
            'aws_request_id': '%(aws_request_id)s'
        }
        self.format_dict.update(kwargs)
        self.default_json_formatter = kwargs.pop(
            'json_default', json_formatter)
    def format(self, record):
        record_dict = record.__dict__.copy()
        record_dict['asctime'] = self.formatTime(record, self.datefmt)
        record_dict['aws_request_id'] = getattr(record, 'aws_request_id', '00000000-0000-0000-0000-000000000000')
        log_dict = {
            k: v % record_dict
            for k, v in self.format_dict.items()
            if v
        }
        if isinstance(record_dict['msg'], dict):
            log_dict['message'] = record_dict['msg']
        else:
            log_dict['message'] = record.getMessage()
            # Attempt to decode the message as JSON, if so, merge it with the
            # overall message for clarity.
            try:
                log_dict['message'] = json.loads(log_dict['message'])
            except (TypeError, ValueError):
                pass
        if record.exc_info:
            # Cache the traceback text to avoid converting it multiple times
            # (it's constant anyway)
            # from logging.Formatter:format
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info)
        if record.exc_text:
            log_dict['exception'] = record.exc_text
        json_record = json.dumps(log_dict, default=self.default_json_formatter)
        if hasattr(json_record, 'decode'):  # pragma: no cover
            json_record = json_record.decode('utf-8')
        return json_record
def setup(level='DEBUG', formatter_cls=JsonFormatter,
          boto_level=None, **kwargs):
    """Overall Metadata Formatting."""
    if formatter_cls:
        for handler in logging.root.handlers:
            handler.setFormatter(formatter_cls(**kwargs))
    try:
        logging.root.setLevel(level)
    except ValueError:
        logging.root.error('Invalid log level: %s', level)
        level = 'INFO'
        logging.root.setLevel(level)
    if not boto_level:
        boto_level = level
    try:
        logging.getLogger('boto').setLevel(boto_level)
        logging.getLogger('boto3').setLevel(boto_level)
        logging.getLogger('botocore').setLevel(boto_level)
    except ValueError:
        logging.root.error('Invalid log level: %s', boto_level)
# 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))
#
#
# class StructuredLogFormatter(logging.Formatter):
#
#     def format(self, record):
#         record.message = record.getMessage()
#         if self.usesTime():
#             record.asctime = self.formatTime(record, self.datefmt)
#         j = {
#             'levelname': record.levelname,
#             'time': '%(asctime)s.%(msecs)dZ' % dict(asctime=record.asctime, msecs=record.msecs),
#             'aws_request_id': getattr(record, 'aws_request_id', '00000000-0000-0000-0000-000000000000'),
#             'message': record.message,
#             'module': record.module,
#             'extra_data': record.__dict__.get('data', {}),
#         }
#         return json.dumps(j)
#
#
# logger = logging.getLogger()
# logger.setLevel('INFO')
#
# formatter = FormatterJSON(
#     '[%(levelname)s]\t%(asctime)s.%(msecs)dZ\t%(levelno)s\t%(message)s\n',
#     '%Y-%m-%dT%H:%M:%S'
# )
# # Replace the LambdaLoggerHandler formatter :
# logger.handlers[0].setFormatter(formatter)
#
#
# def lambda_handler(event, context):
#     my_input = {
#         'key1': 'value1',
#         'key2': 'value2'
#     }
#     logger.info('Process Info: %s', 'Hello', extra=dict(data=my_input))