AWS - 将多个lambda日志订阅到一个elasticsearch服务

时间:2018-03-01 08:28:43

标签: amazon-web-services elasticsearch logging elastic-stack amazon-cloudwatch

我有两个不同的lambda生成的两个日志组。当我将一个日志组订阅到我的elasticsearch服务时,它正在运行。但是,当我添加其他日志组时,我在cloudwatch生成的日志中出现以下错误:

"responseBody": "{\"took\":5,\"errors\":true,\"items\":[{\"index\":{\"_index\":\"cwl-2018.03.01\",\"_type\":\"/aws/lambda/lambda-1\",\"_id\":\"33894733850010958003644005072668130559385092091818016768\",\"status\":400,\"error\":
{\"type\":\"illegal_argument_exception\",\"reason\":\"Rejecting mapping update to [cwl-2018.03.01] as the final mapping would have more than 1 type: [/aws/lambda/lambda-1, /aws/lambda/lambda-2]\"}}}]}"

如何解决此问题,并且仍然在我的Elasticsearch服务中同时拥有两个日志组,并可视化所有日志?

谢谢。

3 个答案:

答案 0 :(得分:17)

问题是ElasticSearch 6.0.0进行了一项更改,允许索引只包含一个映射类型。 (https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html)我假设您正在运行使用6.0版的ElasticSearch服务实例。

如果通过AWS控制台创建的默认Lambda JS文件将索引类型设置为日志组名称。 JS文件的一个示例是在这个要点(https://gist.github.com/iMilnb/27726a5004c0d4dc3dba3de01c65c575

第86行:action.index._type = payload.logGroup;

我个人正在使用该脚本的修改版本,并将该行更改为:

action.index._type = 'cwl';

我将来自各种不同日志组的日志流式传输到同一个ElasticSearch实例。将它们全部设为相同类型是有意义的,因为它们都是CloudWatch日志而不是类型是日志组名称。该名称也在@log_group字段中设置,因此查询可以使用该名称进行过滤。

就我而言,我做了以下事情:

  1. 部署已修改的Lambda
  2. 今天重新索引索引(例如cwl-2018.03.07)来更改类型 对于从<log group name>cwl
  3. 的旧文档
  4. 来自不同日志组的条目现在将共存。

答案 1 :(得分:4)

您还可以如下所示修改生成的Lambda代码,使其与多个CW日志组一起使用。如果Lambda函数可以为同一日志组下的不同日志流创建不同的ES索引,则可以避免此问题。因此,您需要找到Lambda函数LogsToElasticsearch_<AWS-ES-DOMAIN-NAME>,然后找到函数function transform(payload),最后像下面一样更改索引名称的形成部分。

    // index name format: cwl-YYYY.MM.DD
    //var indexName = [
        //'cwl-' + timestamp.getUTCFullYear(),              // year
        //('0' + (timestamp.getUTCMonth() + 1)).slice(-2),  // month
        //('0' + timestamp.getUTCDate()).slice(-2)          // day
    //].join('.');

    var indexName = [
        'cwl-' + payload.logGroup.toLowerCase().split('/').join('-') + '-' + timestamp.getUTCFullYear(),              // log group + year
        ('0' + (timestamp.getUTCMonth() + 1)).slice(-2),  // month
        ('0' + timestamp.getUTCDate()).slice(-2)          // day
    ].join('.');

答案 2 :(得分:0)

是否可以将所有cloudwatch日志组转发到ES中的单个索引?就像使用一个索引“ rds-logs- *”来流式处理所有可用RDS实例中的日志一样。 例如:是否需要将所有RDS实例的错误日志,慢速查询日志,常规日志等推入相同的索引(rds-logs- *)下?

我尝试了上述代码更改,但是它仅推送我配置的最后一个日志组。

从AWS:默认情况下,只有1个日志组可以将日志数据流式传输到ElasticSearch服务。尝试同时传输两个日志组将导致一个日志组的日志数据覆盖另一个日志组的日志数据。

想检查我们是否有解决方法。