【问题标题】:Specify log group for an AWS lambda?为 AWS lambda 指定日志组?
【发布时间】:2017-01-06 23:32:07
【问题描述】:

有没有办法指定 AWS lambda 记录到的 CloudWatch 日志组?它似乎是直接从 lambda 名称生成的;但是,例如,将多个 lambda 聚合到单个日志组会特别方便。当 lambda 由 CloudFormation 模板创建时,我们对指定日志组特别感兴趣。

【问题讨论】:

标签: amazon-web-services aws-lambda amazon-cloudformation amazon-cloudwatch


【解决方案1】:

好的,所以我必须自己执行此操作,@pat-myron 在答案下方评论了一个链接,指向您执行此操作的方式。

他发布了一个功能请求,其中@benbridts 概述了模板here

以下是我的 cloudformation 模板的要点:

HelloWorldLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: "/aws/lambda/HelloWorld"
      RetentionInDays: 30

HelloWorldFunction:
  Type: AWS::Lambda::Function
  DependsOn: HelloWorldLogGroup
  Properties:
    FunctionName: HelloWorld
    Role:
      Fn::GetAtt:
        - LambdaExecRole
        - Arn

LambdaExecRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole
    Policies:
      - PolicyName: LambdaLogging
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource: !GetAtt HelloWorldLogGroup.Arn

【讨论】:

    【解决方案2】:

    我将 LogGroup 附加到 SAM 模板中的无服务器功能如下:

        MyFuncLogGroup:
            Type: AWS::Logs::LogGroup
            Properties:
                LogGroupName: '/aws/lambda/stackName-env-myFunc-v1'
                RetentionInDays: 30
    
        MyFunc:
            Type: AWS::Serverless::Function
            Properties:
                FunctionName: 'stackName-env-myFunc-v1'
                ...
    

    有些用户提到了DependsOn 属性的要求,但根据我使用SAM 的经验,这不是必需的。唯一的要求是 LogGroupName 必须是 /aws/lambda/<FunctionName>。 SAM 将在 lambda 函数之前创建日志组只要您没有在 LogGroup 中引用函数的逻辑 ID

    此外,如果您要将 LogGroup 添加到现有函数,您只需使用上述 LogGroup 资源更新您的 template.yaml 并将 FunctionName 属性添加到函数资源即可。显然,FunctionName 应该不同于出现在 lambda 的 ARN 中的现有 lambda 函数名称。

    警告:FunctionName 属性需要替换。您现有的 lambda 将被删除并创建新的。

    【讨论】:

    • 这似乎最初可以工作,但是当创建 lambda 函数时,保留时间被重置为 3 天。
    • davegallant,你有 cloudwatch 的全局设置吗?我一直在为多个项目使用此配置,并且所有项目的保留期都是持久的。保留期可能是从控制台修改的。
    • 没有。我通过使用 awscli 命令aws logs put-retention-policy 解决了这个问题,这并不漂亮但有效!
    【解决方案3】:

    我发现@lingrlongr 的回答部分正确。

    首先,要回答原始问题,您不能为要写入的 lambda 函数指定自定义日志组名称。

    lambda 日志组名称始终遵循以下模式:

    /aws/lambda/<function-name>
    

    lambda 函数将首先检查是否存在同名的日志组。

    • 如果它存在,那么它将使用它。
    • 如果不存在,它将使用该模式创建一个日志组。

    因此,如果您要添加设置,例如 RetentionInDaysSubscriptionFilter,请确保您的 CloudFormation 或 SAM 模板在 lambda 函数之前创建 LogGroup。如果你的 lambda 函数是先创建的,那么在创建 LogGroup 时会抛出一个错误,指出 LogGroup 已经存在。所以,lambda 函数应该有DependsOn: LogGroup,而不是相反。

    另外,请确保您没有使用 RefGetAtt 来引用 LogGroup 内的 lambda 函数,因为这会创建对 lambda 函数的隐式依赖,从而导致在 LogGroup 之前创建 lambda 函数。

    【讨论】:

      【解决方案4】:

      创建作为答案之一提到的日志组有效。要在删除堆栈后保留保留策略,只需添加一个 DeletionPolicy。

      "MyLambdaFunctionLogGroup": {
        "Type": "AWS::Logs::LogGroup",
        "DependsOn": "MyLambdaFunction",
        "DeletionPolicy": "Retain",
        "Properties": {
          "LogGroupName": {"Fn::Join": ["", ["/aws/lambda/", {"Ref": "MyLambdaFunction"}]]},
          "RetentionInDays": 14
        }
      }
      

      【讨论】:

      • 这个答案没有解决问题
      • Lambda 应该依赖日志组。必须先创建日志组。
      【解决方案5】:

      实际上,至少在某种程度上可以。我也在寻找答案并尝试了一下。这是两个资源的sn-p; lambda 函数和日志组:

      "MyLambdaFunction": {
          "Type": "AWS::Lambda::Function",
          "DependsOn": "ReadWriteRole",
          "Properties": {
              //snip
          }
      },
      
      "MyLambdaFunctionLogGroup": {
          "Type": "AWS::Logs::LogGroup",
          "DependsOn": "MyLambdaFunction",
          "Properties": {
              "LogGroupName": {"Fn::Join": ["", ["/aws/lambda/", {"Ref": "MyLambdaFunction"}]]},
              "RetentionInDays": 14
          }
      },
      

      我发现创建的日志组具有 14 天的保留期,如图所示。当 lambda 函数运行时,它会在该组中创建日志流。但是,当我删除堆栈时,日志组似乎没有被删除,并且保留现在设置为永不过期。也许这已经足够好,所以流不会太失控......

      【讨论】:

      • 我对这个答案非常乐观,但遇到了 LogGroup 失败的问题,因为 LogGroupName 已经存在
      • 您可以删除 DependsOn,因为我们在组名中使用 lambda 的 ARN,因此它是隐式的。
      • @Purefan 我在更新堆栈时得到了同样的结果。我通过删除整个堆栈并再次创建它来解决它。
      • 这个答案没有解决所提出的问题
      • 必须先创建日志组。 Lambda 函数必须依赖于日志组。
      【解决方案6】:

      我认为这是不可能的。

      即使它可能的,每个 AWS Lambda 实例仍将写入其自己的日志流。虽然 同一个 lambda 的不同调用可以写入同一个日志流(当 lambda 实例被重用时),但对于不同的 lambda 肯定不是这种情况(因为它们必须使用不同的 lambda 实例)。

      因此,您必须拥有一个聚合多个日志流的工具。如果是这样,让它更通用一点有什么问题,以便它可以聚合来自不同日志组的日志流?

      【讨论】:

      • 你是对的。我要求 AWS 支持同样的事情,并被告知这是不可能的,而且可能永远不可能。然而,一个 Lambda 函数的多个实例不记录到同一个日志流的原因是因为存在 a limit of 5 requests/second/log-stream。因此,即使您尝试从多个 Lambda 实例手动写入单个日志流,您很快就会遇到该限制。
      • 遗憾的是,无法为单个 Lambda 函数指定日志组。像这样的工具 (github.com/TylerBrock/saw),它可以从特定日志组中流式传输聚合的多个日志流,但无法利用它。
      • 这个答案没有解决所提出的问题......对不起,无法抗拒。但严肃地说,如果你看一下最初的问题,这更多地关注最后的用例而不是实际问题,恕我直言
      • @CraigBrett 问题的答案在第一句话中。答案的本质是它不允许任何详细说明(也不能通过链接到文档来提供证据,因为文档中通常缺少不受支持的功能,并且这些事实仅在特殊情况下才明确说明) .答案的其余部分是一些额外的想法,使其符合 SO 答案的标准(否则它宁愿写成评论并且不可能接受)。
      • @CraigBrett 任何为了为其 AWS Lambda 指定日志组而访问此页面的人都会发现,他们所能做的最多就是指定一个与生成的日志组没有区别的日志组默认。因此,其他两个答案,无论从与 OP 问题无关的其他角度来看多么有用,都不能解决所提出的问题。因此我的cmets。我认为发布一个关注日志保留的新问题(并可能链接到这个问题)然后自行回答这个非常不同的问题会更合适。
      猜你喜欢
      • 1970-01-01
      • 2018-02-16
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 2018-09-22
      • 2018-01-24
      • 2016-11-27
      • 1970-01-01
      相关资源
      最近更新 更多