我的 CloudWatch 日志中缺少 AWSRequestId

AWSRequestId is missing from my CloudWatch logs

我正在使用带 Java 8 的 AWS Lambda,我正在使用 Log4j2 Logger 在 CloudWatch 中打印日志,以下是我的 Log4j2 配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.amazonaws.services.lambda.runtime.log4j2">
    <Appenders>
        <Lambda name="Lambda">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n</pattern>
            </PatternLayout>
        </Lambda>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Lambda"/>
        </Root>
    </Loggers>
</Configuration>

但 CloudWatch 未打印 AWSRequestId,如下图所示,如果缺少请求 ID,则所有日志都缺少它该请求,如果请求 ID 出现,它会显示该请求的所有日志 (红色框内)

由于我们使用 Log4j 进行日志记录,因此我们通过在抽象 Lambda 处理程序中的 Log4j ThreadContext 中添加 A​​WSRequestId 来解决此问题 class。因此,每当 lambda 函数被触发时,它都会在 ThreadContext 映射中添加 A​​WSRequestId 并且在打印日志时可用。

这是一个 link 关于 Log4j ThreadContext 映射 -> https://logging.apache.org/log4j/2.x/manual/thread-context.html

/**
 * All the lambda handler class should extend this class.
 */
public abstract class AbstractEventHandler<I, O> implements RequestHandler<I, O> {

    @Override
    public O handleRequest(I input, Context context) {
        // As in our implementation, we have created child threads from our main thread
        // but in child threads, Thread ContextMap might not be available.
        // so we need to pass this by setting Log4j property
        // isThreadContextMapInheritable to true.
        System.setProperty("isThreadContextMapInheritable", "true");

        // Adding AWSRequestId in ThreadContext map.
        ThreadContext.put("AWSRequestId", context.getAwsRequestId());
        return requestHandler(input, context);
    }

    abstract protected O requestHandler(I input, Context context);
}