Skip to content

Bug: Provisioned concurrency not considered in Logging and Metrics #2113

@phipag

Description

@phipag

Expected Behaviour

When I use provisioned concurrency in my Lambda function, cold starts do not happen unless the provisioned concurrency is exceeded.

Therefore, I expect that all function executions which have AWS_LAMBDA_INITIALIZATION_TYPE="provisioned-concurrency" to not emit a cold start metric if enabled and not set the cold_start: true field on emitted JSON logs.

Current Behaviour

  • Cold start metric is emitted
  • JSON logs have cold_start: true field

Code snippet

public class TriageHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    private static final Logger logger = LoggerFactory.getLogger(TriageHandler.class);
    private static final Metrics metrics = MetricsFactory.getMetricsInstance();

    @Logging(logEvent = true)
    @Tracing
    @FlushMetrics(namespace = "TriagingTemplate", service = "triage", captureColdStart = true)
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
        logger.info("Processing triage request");

        // Add custom metric
        metrics.addMetric("TriageRequests", 1, MetricUnit.COUNT);

        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");

        String responseBody = """
                {
                    "message": "Hello from Powertools Triaging Template!",
                    "service": "triage",
                    "version": "1.0.0"
                }
                """;

        logger.info("Triage request processed successfully");

        return new APIGatewayProxyResponseEvent()
                .withStatusCode(200)
                .withHeaders(headers)
                .withBody(responseBody);
    }
}

Possible Solution

Use AWS_LAMBDA_INITIALIZATION_TYPE environment variable within the utilities to suppress cold start behavior if the init type is provisioned-concurrency.

Steps to Reproduce

Deploy a lambda function and enable provisioned concurrency. You can use the powertools triaging template: https://github.com/phipag/powertools-triaging-template-java/tree/main

Example SAM Template:

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  Powertools for AWS Lambda (Java) - Triaging Template

Globals:
  Function:
    Timeout: 20
    Runtime: java21
    MemorySize: 512
    Tracing: Active
    Environment:
      Variables:
        # Powertools for AWS Lambda (Java) env vars
        POWERTOOLS_LOG_LEVEL: INFO
        POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1
        POWERTOOLS_LOGGER_LOG_EVENT: true
        POWERTOOLS_METRICS_NAMESPACE: TriagingTemplate

Resources:
  TriageFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Handler: triage.TriageHandler::handleRequest
      AutoPublishAlias: live
      ProvisionedConcurrencyConfig:
        ProvisionedConcurrentExecutions: 1
      Environment:
        Variables:
          POWERTOOLS_SERVICE_NAME: triage
      Events:
        TriageApi:
          Type: Api
          Properties:
            Path: /triage
            Method: get

Outputs:
  TriageApi:
    Description: "API Gateway endpoint URL for Prod stage for Triage function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/triage/"
  TriageFunction:
    Description: "Triage Lambda Function ARN"
    Value: !GetAtt TriageFunction.Arn
  TriageFunctionIamRole:
    Description: "Implicit IAM Role created for Triage function"
    Value: !GetAtt TriageFunctionRole.Arn

Powertools for AWS Lambda (Java) version

latest

AWS Lambda function runtime

Java 21

Debugging logs

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions