繁体   English   中英

AWS Lambda记录到一条JSON行

[英]AWS Lambda Logs to One JSON Line

我在AWS lambda中执行小的Python代码,但是Lambda以非常不方便的格式将日志放入CloudWatch Logs中: 在此处输入图片说明

我想将这些日志发送给ELK以进行可视化。 有没有办法将所有Lambda迭代日志放到一个json文件中?

预加载的LambdaLoggerHandler使用标准的类logging.Formatter 资料来源: https : //www.denialof.services/lambda/

将格式化程序替换为输出到JSON的自定义类。 另外, extra字典可能包含附加值, extra['data']避免与其他logrecord属性冲突。

import logging
import json

class FormatterJSON(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))

但是,任何堆栈跟踪都照常进行渲染。

然后CloudWatch得到这个:

{
    "levelname": "INFO",
    "time": "2018-12-13T11:35:24.130Z",
    "aws_request_id": "2e0f7055-fecb-11e8-8376-b77695872964",
    "message": "Process Info: Hello",
    "module": "lambda_function",
    "extra_data": {
        "key1": "value1",
        "key2": "value2"
    }
}

尝试通过以下方式编写日志:

import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def my_logging_handler(event, context):
    logger.error(
        json.dumps(
            {
                'key1': 'value1',
                'key2': 'value2'
            }
        )
    )
    return 'Hello from Lambda!'  

您应该将应用程序设置为以JSON身份登录。 这样,您可以将所有信息记录为单个JSON行。 这也将使在ELK中进行下游分析变得更加容易。

例如,您可以使用Watch望塔

import watchtower, logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.addHandler(watchtower.CloudWatchLogHandler())
logger.info("Hi")
logger.info(dict(foo="bar", details={}))

这将不包括START和END行,但是您可以始终让您的应用程序根据需要添加该信息。

简而言之,没有一种方法可以强制所有日志进入一个日志流。 他们都应该在同一个日志组中。 每当部署新版本或启动Lambda的新实例时,Lambda都会创建新的日志流。 将这些数据导入ELK时,您有两种选择。

  1. 您可以调查Cloudwatch Logstash插件 我从未使用过它,所以我不能保证它的简便性和/或有效性。
  2. 您可以将Cloudwatch Logs连接为另一个进行处理的Lambda 的触发器
  3. Cloudwatch提供了非常强大的搜索。 您可以定期从Cloudwatch查询数据并将其发布到Logstash。
  4. 将手动将此数据发布到Logstash服务器,而不是将其记录到Cloudwatch。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM