代码之家  ›  专栏  ›  技术社区  ›  Akash Sharma

导出中的“事件”参数。cloudwatch日志触发的nodejs lambda函数处理程序

  •  1
  • Akash Sharma  · 技术社区  · 8 年前

    我有一个用NodeJS编写的AWS Lambda函数,它由CloudWatch订阅过滤器触发。有人告诉我,出口的“事件”论点。Lambda函数中的处理程序是我用来获取日志数据的。

    当我打印时,我看到了以下内容,与我在实际的CloudWatch控制台中看到的人类可读数据完全不同。这是什么意思?!?以下是我得到的:

    { awslogs: { data: 'H4sIAAAAAAAAAKWS207jMBRFf8XyMwFfYztvURpQpFIqEmYeUIV8S4nUJlXizggh/p3D7Qt4Xfvs47O3/IqPcVnsPnYvp4gLvCq78um2btvypsYXePo/xhmwNlQSKZk0QgE+TPubeTqfQCn/ts2U1tN++eJtmqM9guBD0JzF2CuleiWJ9rLvuZfWyyAAM0u4NULaGIxw1hjgOvggeueYYBHWLWe3+Hk4pWEar4dDivOCi0e8tkcX7NdDTzaEahrH6D+Gumnl7BLx7vOU+l8c04fjFQ8BLuJcaqm1ZkTo3EAUKSUEy3NNieQiJ1wzRSEpBQa61oRSQjRckgaoKdkjJIYiciI4p4Lk/OKnPljPCFUZMRljiNCC0UKKSxhB3X1Z1c2qyF2vvPU00yr6zFCjMglhM+cFM8oCpRRt75tN1WzLNRh+2yB6bDbXdzuE6j/1piu2Z3cYlufPVlB3t22qTXlbF80YhnhFOKnkSvCrdkgRfX+AH0szojbZdF4K1D5UFYj4bff2DvK/Lnc7AgAA' } }
    

    根据以下链接,该数据没有错: http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-cloudwatch-logs

    根据StackOverflow中的回答,这是数据也没有错: KeyError: 'awslogs' ... outEvent = str(event['awslogs']['data']) - Python

    2 回复  |  直到 8 年前
        1
  •  3
  •   Jamie Starke    8 年前

    你准确地找到了一个 Amazon CloudWatch Logs Sample Event . 因此,基于此 event 对象的结构如下:

    {
      "awslogs": {
        "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA=="
      }
    }
    

    这是怎么一回事?

    让我们把它拆开,更好地了解这里发生了什么。在这种情况下 event.awslogs.data

    "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA=="
    

    该值实际上是一个 基准64

    如果我们对其进行Base64解码,然后将其解压,则得到以下值:

    {
      "messageType": "DATA_MESSAGE",
      "owner": "123456789123",
      "logGroup": "testLogGroup",
      "logStream": "testLogStream",
      "subscriptionFilters": [
        "testFilter"
      ],
      "logEvents": [
        {
          "id": "eventId1",
          "timestamp": 1440442987000,
          "message": "[ERROR] First test message"
        },
        {
          "id": "eventId2",
          "timestamp": 1440442987001,
          "message": "[ERROR] Second test message"
        }
      ]
    }
    

    其要素如下:

    • messageType :be或be DATA_MESSAGE CONTROL_MESSAGE ,如果我的理解正确, 用于检查lambda的可达性
    • owner :原始日志的AWS帐户ID
    • logGroup
    • logStream :原始日志的日志流
    • subscriptionFilter :匹配的订阅筛选器名称
    • logEvents :与您在控制台中看到的内容相关的实际日志

    我该如何使用它?

    Subscription Filters with AWS Lambda

    var zlib = require('zlib');
    exports.handler = function(input, context) {
        var payload = new Buffer(input.awslogs.data, 'base64');
        zlib.gunzip(payload, function(e, result) {
            if (e) { 
                context.fail(e);
            } else {
                result = JSON.parse(result.toString('ascii'));
                console.log("Event Data:", JSON.stringify(result, null, 2));
                context.succeed();
            }
        });
    };
    

    希望这有帮助。

        2
  •  0
  •   Michael - sqlbot    8 年前

    这是什么意思?!?

    [A-Z][a-z][0-9][+/=]

    为什么数据是二进制的?

    因为它是压缩的。Gzip是一种压缩算法,它在压缩文本方面非常好而且非常快。。。但是gzip文本生成任意二进制数据,因此无法在JSON中序列化,JSON只支持文本(以及数字和true/false/null)。

    因此,gzip数据在base64中编码,以便在JSON内传输。

    您需要将base64表示转换为二进制,并对其进行g-un-zip。

    http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample :

    var zlib = require('zlib');
    exports.handler = function(input, context) {
        var payload = new Buffer(input.awslogs.data, 'base64'); // decode base64 to binary
        zlib.gunzip(payload, function(e, result) { // gunzip the binary data
            if (e) { 
                context.fail(e);
            } else {
                result = JSON.parse(result.toString('ascii'));
                console.log("Event Data:", JSON.stringify(result, null, 2));
                context.succeed();
            }
        });
    };
    

    注意,这使用了旧的 context.fail() context.succeed() 约定,它显然仍然支持向后兼容,但不应在新代码中使用。看见 http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#nodejs-prog-model-oldruntime-context-methods