Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue-864 seprate logging error status and stack trace #865

Merged
merged 1 commit into from
Dec 14, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions handler/src/main/java/com/networknt/handler/LightHttpHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -43,24 +44,24 @@ public interface LightHttpHandler extends HttpHandler {
String ERROR_NOT_DEFINED = "ERR10042";

// Handler can save errors and stack traces for auditing. Default: false
String CONFIG_NAME = "handler";
String AUDIT_ON_ERROR = "auditOnError";
String AUDIT_STACK_TRACE = "auditStackTrace";
String CONFIG_NAME = "handler";
String AUDIT_ON_ERROR = "auditOnError";
String AUDIT_STACK_TRACE = "auditStackTrace";

HandlerConfig config = (HandlerConfig) Config.getInstance().getJsonObjectConfig(CONFIG_NAME, HandlerConfig.class);
boolean auditOnError = config != null ? config.getAuditOnError() : false;
boolean auditStackTrace = config != null ? config.getAuditStackTrace() : false;

HandlerConfig config = (HandlerConfig) Config.getInstance().getJsonObjectConfig(CONFIG_NAME, HandlerConfig.class);
boolean auditOnError = config != null ? config.getAuditOnError() : false;
boolean auditStackTrace = config != null ? config.getAuditStackTrace() : false;

/**
* This method is used to construct a standard error status in JSON format from an error code.
*
* @param exchange HttpServerExchange
* @param code error code
* @param args arguments for error description
* @param code error code
BalloonWen marked this conversation as resolved.
Show resolved Hide resolved
* @param args arguments for error description
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for tab here as per javadoc standard

*/
default void setExchangeStatus(HttpServerExchange exchange, String code, final Object... args) {
Status status = new Status(code, args);
if(status.getStatusCode() == 0) {
if (status.getStatusCode() == 0) {
// There is no entry in status.yml for this particular error code.
status = new Status(ERROR_NOT_DEFINED, code);
}
Expand All @@ -72,27 +73,35 @@ default void setExchangeStatus(HttpServerExchange exchange, String code, final O
* want to bubble up to the caller and eventually to the original caller.
*
* @param exchange HttpServerExchange
* @param status error status
* @param status error status
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for tab here as per javadoc standard

*/
default void setExchangeStatus(HttpServerExchange exchange, Status status) {
exchange.setStatusCode(status.getStatusCode());
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
status.setDescription(status.getDescription().replaceAll("\\\\", "\\\\\\\\"));
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
logger.error(status.toString() + " at " + elements[2].getClassName() + "." + elements[2].getMethodName() + "(" + elements[2].getFileName() + ":" + elements[2].getLineNumber() + ")");

logger.error(status.toString());
// in case to trace where the status is created, enable the trace level logging to diagnose.
if (logger.isTraceEnabled()) {
String stackTrace = Arrays.stream(elements)
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
logger.trace(stackTrace);
}
// In normal case, the auditInfo shouldn't be null as it is created by OpenApiHandler with
// endpoint and openapiOperation available. This handler will enrich the auditInfo.
@SuppressWarnings("unchecked")
Map<String, Object> auditInfo = exchange.getAttachment(AttachmentConstants.AUDIT_INFO);
if(auditInfo == null) {
if (auditInfo == null) {
auditInfo = new HashMap<>();
exchange.putAttachment(AttachmentConstants.AUDIT_INFO, auditInfo);
}

// save info for auditing purposes in case of an error
if(auditOnError)
if (auditOnError)
auditInfo.put(Constants.STATUS, status);
if(auditStackTrace) {
if (auditStackTrace) {
auditInfo.put(Constants.STACK_TRACE, Arrays.toString(elements));
}
exchange.getResponseSender().send(status.toString());
Expand Down