Skip to content

Commit

Permalink
Merge pull request #24919 from emattheis/lambda-expected-exceptions
Browse files Browse the repository at this point in the history
Suppress logging for configured exceptions thrown by Amazon Lambda handlers
  • Loading branch information
patriot1burke authored Apr 18, 2022
2 parents b0d5f54 + dba6e8c commit a8d5279
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public AbstractLambdaPollLoop(ObjectMapper objectMapper, ObjectReader cognitoIdR
this.launchMode = launchMode;
}

protected boolean shouldLog(Exception e) {
return true;
}

protected abstract boolean isStream();

protected HttpURLConnection requestConnection = null;
Expand Down Expand Up @@ -131,7 +135,9 @@ public void run() {
if (abortGracefully(e)) {
return;
}
log.error("Failed to run lambda (" + launchMode + ")", e);
if (shouldLog(e)) {
log.error("Failed to run lambda (" + launchMode + ")", e);
}

postError(AmazonLambdaApi.invocationError(baseUrl, requestId),
new FunctionError(e.getClass().getName(), e.getMessage()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import javax.inject.Named;

Expand All @@ -24,6 +25,7 @@

import io.quarkus.amazon.lambda.runtime.AmazonLambdaRecorder;
import io.quarkus.amazon.lambda.runtime.FunctionError;
import io.quarkus.amazon.lambda.runtime.LambdaBuildTimeConfig;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.builder.BuildException;
Expand Down Expand Up @@ -258,4 +260,15 @@ void startPoolLoopDevOrTest(AmazonLambdaRecorder recorder,
}
}

@BuildStep
@Record(value = ExecutionTime.RUNTIME_INIT)
void recordExpectedExceptions(LambdaBuildTimeConfig config,
BuildProducer<ReflectiveClassBuildItem> registerForReflection,
AmazonLambdaRecorder recorder) {
Set<Class<?>> classes = config.expectedExceptions.map(Set::copyOf).orElseGet(Set::of);
classes.stream().map(clazz -> new ReflectiveClassBuildItem(false, false, false, clazz))
.forEach(registerForReflection::produce);
recorder.setExpectedExceptionClasses(classes);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.logging.Logger;

Expand Down Expand Up @@ -35,6 +36,7 @@ public class AmazonLambdaRecorder {
private static BeanContainer beanContainer;
private static LambdaInputReader objectReader;
private static LambdaOutputWriter objectWriter;
private static Set<Class<?>> expectedExceptionClasses;

private final LambdaConfig config;

Expand All @@ -47,6 +49,10 @@ public void setStreamHandlerClass(Class<? extends RequestStreamHandler> handler,
beanContainer = container;
}

public void setExpectedExceptionClasses(Set<Class<?>> classes) {
expectedExceptionClasses = classes;
}

public void setHandlerClass(Class<? extends RequestHandler<?, ?>> handler, BeanContainer container) {
handlerClass = handler;
beanContainer = container;
Expand Down Expand Up @@ -186,6 +192,11 @@ protected void processRequest(InputStream input, OutputStream output, AmazonLamb
handler.handleRequest(input, output, context);

}

@Override
protected boolean shouldLog(Exception e) {
return expectedExceptionClasses.stream().noneMatch(clazz -> clazz.isAssignableFrom(e.getClass()));
}
};
loop.startPollLoop(context);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.amazon.lambda.runtime;

import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(name = "lambda", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public class LambdaBuildTimeConfig {

/**
* The exception classes expected to be thrown by the handler.
*
* Any exception thrown by the handler that is an instance of a class in this list will not be logged,
* but will otherwise be handled normally by the lambda runtime. This is useful for avoiding unnecessary
* stack traces while preserving the ability to log unexpected exceptions.
*/
@ConfigItem
public Optional<List<Class<?>>> expectedExceptions;
}

0 comments on commit a8d5279

Please sign in to comment.