in aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/EventHandlerLoader.java [528:606]
private static LambdaRequestHandler wrapRequestStreamHandler(final RequestStreamHandler handler) {
return new LambdaRequestHandler() {
private final ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
private Functions.V2<String, String> log4jContextPutMethod = null;
private void safeAddRequestIdToLog4j(String log4jContextClassName,
InvocationRequest request, Class contextMapValueClass) {
try {
Class<?> log4jContextClass = ReflectUtil.loadClass(AWSLambda.customerClassLoader, log4jContextClassName);
log4jContextPutMethod = ReflectUtil.loadStaticV2(log4jContextClass, "put", false, String.class, contextMapValueClass);
log4jContextPutMethod.call("AWSRequestId", request.getId());
} catch (Exception e) {
// nothing to do here
}
}
/**
* Passes the LambdaContext to the logger so that the JSON formatter can include the requestId.
*
* We do casting here because both the LambdaRuntime and the LambdaLogger is in the core package,
* and the setLambdaContext(context) is a method we don't want to publish for customers. That method is
* only implemented on the internal LambdaContextLogger, so we check and cast to be able to call it.
* @param context the LambdaContext
*/
private void safeAddContextToLambdaLogger(LambdaContext context) {
LambdaLogger logger = com.amazonaws.services.lambda.runtime.LambdaRuntime.getLogger();
if (logger instanceof LambdaContextLogger) {
LambdaContextLogger contextLogger = (LambdaContextLogger) logger;
contextLogger.setLambdaContext(context);
}
}
public ByteArrayOutputStream call(InvocationRequest request) throws Error, Exception {
output.reset();
LambdaCognitoIdentity cognitoIdentity = null;
if (request.getCognitoIdentity() != null && !request.getCognitoIdentity().isEmpty()) {
cognitoIdentity = getCognitoSerializer().fromJson(request.getCognitoIdentity());
}
LambdaClientContext clientContext = null;
if (request.getClientContext() != null && !request.getClientContext().isEmpty()) {
//Use GSON here because it handles immutable types without requiring annotations
clientContext = getContextSerializer().fromJson(request.getClientContext());
}
LambdaContext context = new LambdaContext(
LambdaEnvironment.MEMORY_LIMIT,
request.getDeadlineTimeInMs(),
request.getId(),
LambdaEnvironment.LOG_GROUP_NAME,
LambdaEnvironment.LOG_STREAM_NAME,
LambdaEnvironment.FUNCTION_NAME,
cognitoIdentity,
LambdaEnvironment.FUNCTION_VERSION,
request.getInvokedFunctionArn(),
request.getTenantId(),
clientContext
);
safeAddContextToLambdaLogger(context);
if (LambdaRuntimeInternal.getUseLog4jAppender()) {
safeAddRequestIdToLog4j("org.apache.log4j.MDC", request, Object.class);
safeAddRequestIdToLog4j("org.apache.logging.log4j.ThreadContext", request, String.class);
// if put method not assigned in either call to safeAddRequestIdtoLog4j then log4jContextPutMethod = null
if (log4jContextPutMethod == null) {
System.err.println("Customer using log4j appender but unable to load either "
+ "org.apache.log4j.MDC or org.apache.logging.log4j.ThreadContext. "
+ "Customer cannot see RequestId in log4j log lines.");
}
}
ByteArrayInputStream bais = new ByteArrayInputStream(request.getContent());
handler.handleRequest(bais, output, context);
return output;
}
};
}