Skip to content

Commit

Permalink
issue-864 (networknt#865)
Browse files Browse the repository at this point in the history
- now logging the status ans stack trace separately
- now will only log the stack trace when TRACE is enabled.

Co-authored-by: Bolun Wen <bolun.wen@sunlife.com>
  • Loading branch information
BalloonWen and Bolun Wen committed Dec 14, 2020
1 parent 4ef696b commit 5ba000b
Showing 1 changed file with 24 additions and 15 deletions.
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
* @param args arguments for error description
*/
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
*/
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

0 comments on commit 5ba000b

Please sign in to comment.