Skip to content

RFC: Canonical Wide Log utility for emitting a single log entry per lambda execution or processed transaction (batch) #3878

@walmsles

Description

@walmsles

Is this related to an existing feature request or issue?

No response

Which Powertools for AWS Lambda (Python) utility does this relate to?

Logger

Summary

The logger is great and offers a heap of functionality. It is very useful for developer logging, debug, info, error logging but I don't think its great for observability logging. Some ideas have been circulating in the observability community around canonical logging and, more recently, about wide events. The idea of a single log entry per Lambda function invocation holding ALL the meta-data for what occurred during that execution is a very useful concept and something I have used for tracking, tracing and observing transactions across a distributed system.

Use case

I want to be able to gather meta-data during transaction processing and store it somewhere so I can write it all out in a single place, representing everything that happened to the transaction as it was being processed by my code. I want to be able to add to this meta-data from shared-libraries and want to enable developers to easily throw meta-data into the bucket for collection when transaction processing is done.

Log attributes does this sto a degree already - but is focused on applying the meta-data to every log output, not just a single oneat the end of processing.

Proposal

Existing capability:

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.typing import LambdaContext

logger = Logger()


@logger.inject_lambda_context
def lambda_handler(event: dict, context: LambdaContext) -> str:
    logger.append_keys(customer=event.customer_id)

    try:
        logger.info({"operation": "collect_payment", "charge_id": event["charge_id"]})

        # do more processing    
    
    finally:
        logger.info("WIDE") # log WIDE log entry along with collected attributes from 'append_keys'
    
    return "hello world"

Using a Wide Logging utility:

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.typing import LambdaContext

logger = Logger()


@logger.inject_lambda_context
@logger.wide_logger()
def lambda_handler(event: dict, context: LambdaContext) -> str:
    logger.wide.add(customer=event.customer_id)

    logger.debug({"operation": "collect_payment", "charge_id": event["charge_id"]})
    logger.wide.add(charge_id=event.get("charge_id"))
    logger.wide.add(operation=collect_payment)

    # do more processing    
    
    
    return "hello world"

Using middleware to emit the wide log means it is a set and forget operation, which adds value for developers who are already overloaded.
Being able to add in meta-data as transaction processing happens, encourages thoughtful use of meta-data attributes.
Collating them in a central object for emitting at the end means the meta-data you are collecting for observability purposes is separate from attributes you collate for debug logging - 2 very distinct purposes and separating the concerns will encourage clearer thinking on Observability vs debug.

Out of scope

Nothing.

Potential challenges

Wide logging needs to be considered at a transaction level - so not always as a per-function execution statement which is not true in the case of functions which process data through a batch mechanism - SQS, SNS, stream (DynamoDB, Kafka, Kinesis, etc). The middleware would need to apply to both batch functions and lambda handlers.

Dependencies and Integrations

This should be a natural extension of the logger utility - a slightly different function to just logging. I liken the idea of this more like the Metrics implementation where meta-data is collated during code execution and output at a singular level.This

Alternative solutions

No response

Acknowledgment

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCneed-customer-feedbackRequires more customers feedback before making or revisiting a decision

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions