Skip to content

Commit

Permalink
allow enabling/disabling of output fields in JsonEncoder
Browse files Browse the repository at this point in the history
Signed-off-by: Ceki Gulcu <[email protected]>
  • Loading branch information
ceki committed Feb 2, 2024
1 parent 5782d29 commit 9078f68
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
import static ch.qos.logback.core.model.ModelConstants.NULL_STR;

/**
* http://ndjson.org/
* https://datatracker.ietf.org/doc/html/rfc8259
*
*
* http://ndjson.org/ https://datatracker.ietf.org/doc/html/rfc8259
*/
public class JsonEncoder extends EncoderBase<ILoggingEvent> {
static final boolean DO_NOT_ADD_QUOTE_KEY = false;
Expand All @@ -51,7 +52,6 @@ public class JsonEncoder extends EncoderBase<ILoggingEvent> {
public static final String BIRTHDATE_ATTR_NAME = "birthdate";
public static final String CONTEXT_PROPERTIES_ATTR_NAME = "properties";


public static final String TIMESTAMP_ATTR_NAME = "timestamp";

public static final String NANOSECONDS_ATTR_NAME = "nanoseconds";
Expand All @@ -66,6 +66,8 @@ public class JsonEncoder extends EncoderBase<ILoggingEvent> {

public static final String MESSAGE_ATTR_NAME = "message";

public static final String FORMATTED_MESSAGE_ATTR_NAME = "formattedMessage";

public static final String ARGUMENT_ARRAY_ATTR_NAME = "arguments";
public static final String KEY_VALUE_PAIRS_ATTR_NAME = "kvpList";

Expand All @@ -77,7 +79,6 @@ public class JsonEncoder extends EncoderBase<ILoggingEvent> {

public static final String SUPPRESSED_ATTR_NAME = "suppressed";


public static final String COMMON_FRAMES_COUNT_ATTR_NAME = "commonFramesCount";

public static final String CLASS_NAME_ATTR_NAME = "className";
Expand All @@ -100,9 +101,27 @@ public class JsonEncoder extends EncoderBase<ILoggingEvent> {

private static final String QUOTE_COL = "\":";


private static final char VALUE_SEPARATOR = COMMA_CHAR;

private boolean withSequenceNumber = true;

private boolean withTimestamp = true;
private boolean withNanoseconds = true;


private boolean withLevel = true;
private boolean withThreadName = true;
private boolean withLoggerName = true;
private boolean withContext = true;
private boolean withMarkers = true;
private boolean withMDC = true;
private boolean withKVPList = true;
private boolean withMessage = true;
private boolean withArguments = true;
private boolean withThrowable = true;
private boolean withFormattedMessage = false;


@Override
public byte[] headerBytes() {
return EMPTY_BYTES;
Expand All @@ -114,49 +133,73 @@ public byte[] encode(ILoggingEvent event) {
StringBuilder sb = new StringBuilder(initialCapacity);
sb.append(OPEN_OBJ);

appenderMemberWithLongValue(sb, SEQUENCE_NUMBER_ATTR_NAME, event.getSequenceNumber());
sb.append(VALUE_SEPARATOR);
if (withSequenceNumber) {
appenderMemberWithLongValue(sb, SEQUENCE_NUMBER_ATTR_NAME, event.getSequenceNumber());
sb.append(VALUE_SEPARATOR);
}

appenderMemberWithLongValue(sb, TIMESTAMP_ATTR_NAME, event.getTimeStamp());
sb.append(VALUE_SEPARATOR);
if (withTimestamp) {
appenderMemberWithLongValue(sb, TIMESTAMP_ATTR_NAME, event.getTimeStamp());
sb.append(VALUE_SEPARATOR);
}

appenderMemberWithLongValue(sb, NANOSECONDS_ATTR_NAME, event.getNanoseconds());
sb.append(VALUE_SEPARATOR);
if (withNanoseconds) {
appenderMemberWithLongValue(sb, NANOSECONDS_ATTR_NAME, event.getNanoseconds());
sb.append(VALUE_SEPARATOR);
}

if (withLevel) {
String levelStr = event.getLevel() != null ? event.getLevel().levelStr : NULL_STR;
appenderMember(sb, LEVEL_ATTR_NAME, levelStr);
sb.append(VALUE_SEPARATOR);
}

String levelStr = event.getLevel() != null ? event.getLevel().levelStr : NULL_STR;
appenderMember(sb, LEVEL_ATTR_NAME, levelStr);
sb.append(VALUE_SEPARATOR);
if (withThreadName) {
appenderMember(sb, THREAD_NAME_ATTR_NAME, jsonEscape(event.getThreadName()));
sb.append(VALUE_SEPARATOR);
}

appenderMember(sb, THREAD_NAME_ATTR_NAME, jsonEscape(event.getThreadName()));
sb.append(VALUE_SEPARATOR);
if (withLoggerName) {
appenderMember(sb, LOGGER_ATTR_NAME, event.getLoggerName());
sb.append(VALUE_SEPARATOR);
}

appenderMember(sb, LOGGER_ATTR_NAME, event.getLoggerName());
sb.append(VALUE_SEPARATOR);
if (withContext) {
appendLoggerContext(sb, event.getLoggerContextVO());
sb.append(VALUE_SEPARATOR);
}
if (withMarkers)
appendMarkers(sb, event);

appendLoggerContext(sb, event.getLoggerContextVO());
sb.append(VALUE_SEPARATOR);
if (withMDC)
appendMDC(sb, event);

appendMarkers(sb, event);
if (withKVPList)
appendKeyValuePairs(sb, event);

appendMDC(sb, event);
if (withMessage) {
appenderMember(sb, MESSAGE_ATTR_NAME, jsonEscape(event.getMessage()));
sb.append(VALUE_SEPARATOR);
}

appendKeyValuePairs(sb, event);
if (withFormattedMessage) {
appenderMember(sb, FORMATTED_MESSAGE_ATTR_NAME, jsonEscape(event.getFormattedMessage()));
sb.append(VALUE_SEPARATOR);
}

appenderMember(sb, MESSAGE_ATTR_NAME, jsonEscape(event.getMessage()));
sb.append(VALUE_SEPARATOR);
if (withArguments)
appendArgumentArray(sb, event);

appendArgumentArray(sb, event);
if (withThrowable)
appendThrowableProxy(sb, THROWABLE_ATTR_NAME, event.getThrowableProxy());

appendThrowableProxy(sb, THROWABLE_ATTR_NAME, event.getThrowableProxy());
sb.append(CLOSE_OBJ);
sb.append(CoreConstants.JSON_LINE_SEPARATOR);
return sb.toString().getBytes(UTF_8_CHARSET);
}

private void appendLoggerContext(StringBuilder sb, LoggerContextVO loggerContextVO) {


sb.append(QUOTE).append(CONTEXT_ATTR_NAME).append(QUOTE_COL);
if (loggerContextVO == null) {
sb.append(NULL_STR);
Expand All @@ -176,7 +219,7 @@ private void appendLoggerContext(StringBuilder sb, LoggerContextVO loggerContext

private void appendMap(StringBuilder sb, String attrName, Map<String, String> map) {
sb.append(QUOTE).append(attrName).append(QUOTE_COL);
if(map == null) {
if (map == null) {
sb.append(NULL_STR);
return;
}
Expand All @@ -185,8 +228,8 @@ private void appendMap(StringBuilder sb, String attrName, Map<String, String> ma

boolean addComma = false;
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry: entries) {
if(addComma) {
for (Map.Entry<String, String> entry : entries) {
if (addComma) {
sb.append(VALUE_SEPARATOR);
}
addComma = true;
Expand All @@ -196,13 +239,11 @@ private void appendMap(StringBuilder sb, String attrName, Map<String, String> ma
sb.append(CLOSE_OBJ);
}


private void appendThrowableProxy(StringBuilder sb, String attributeName, IThrowableProxy itp) {


// in the nominal case, attributeName != null. However, attributeName will be null for suppressed
// IThrowableProxy array, in which case no attribute name is needed
if(attributeName != null) {
if (attributeName != null) {
sb.append(QUOTE).append(attributeName).append(QUOTE_COL);
if (itp == null) {
sb.append(NULL_STR);
Expand All @@ -217,34 +258,33 @@ private void appendThrowableProxy(StringBuilder sb, String attributeName, IThrow
sb.append(VALUE_SEPARATOR);
appenderMember(sb, MESSAGE_ATTR_NAME, jsonEscape(itp.getMessage()));


if(itp.isCyclic()) {
if (itp.isCyclic()) {
sb.append(VALUE_SEPARATOR);
appenderMember(sb, CYCLIC_THROWABLE_ATTR_NAME, jsonEscape("true"));
}

sb.append(VALUE_SEPARATOR);
appendSTEPArray(sb, itp.getStackTraceElementProxyArray(), itp.getCommonFrames());

if(itp.getCommonFrames() != 0) {
if (itp.getCommonFrames() != 0) {
sb.append(VALUE_SEPARATOR);
appenderMemberWithIntValue(sb, COMMON_FRAMES_COUNT_ATTR_NAME, itp.getCommonFrames());
}

IThrowableProxy cause = itp.getCause();
if(cause != null) {
if (cause != null) {
sb.append(VALUE_SEPARATOR);
appendThrowableProxy(sb, CAUSE_ATTR_NAME, cause);
}

IThrowableProxy[] suppressedArray = itp.getSuppressed();
if(suppressedArray != null && suppressedArray.length != 0) {
if (suppressedArray != null && suppressedArray.length != 0) {
sb.append(VALUE_SEPARATOR);
sb.append(QUOTE).append(SUPPRESSED_ATTR_NAME).append(QUOTE_COL);
sb.append(OPEN_ARRAY);
boolean first = true;
for(IThrowableProxy suppressedITP: suppressedArray) {
if(first) {
for (IThrowableProxy suppressedITP : suppressedArray) {
if (first) {
first = false;
} else {
sb.append(VALUE_SEPARATOR);
Expand All @@ -254,7 +294,6 @@ private void appendThrowableProxy(StringBuilder sb, String attributeName, IThrow
sb.append(CLOSE_ARRAY);
}


sb.append(CLOSE_OBJ);

}
Expand All @@ -264,7 +303,7 @@ private void appendSTEPArray(StringBuilder sb, StackTraceElementProxy[] stepArra

int len = stepArray != null ? stepArray.length : 0;

if(commonFrames >= len) {
if (commonFrames >= len) {
commonFrames = 0;
}

Expand Down Expand Up @@ -301,6 +340,7 @@ private void appenderMember(StringBuilder sb, String key, String value) {
private void appenderMemberWithIntValue(StringBuilder sb, String key, int value) {
sb.append(QUOTE).append(key).append(QUOTE_COL).append(value);
}

private void appenderMemberWithLongValue(StringBuilder sb, String key, long value) {
sb.append(QUOTE).append(key).append(QUOTE_COL).append(value);
}
Expand Down Expand Up @@ -332,7 +372,7 @@ private void appendArgumentArray(StringBuilder sb, ILoggingEvent event) {
sb.append(QUOTE).append(ARGUMENT_ARRAY_ATTR_NAME).append(QUOTE_COL).append(SP).append(OPEN_ARRAY);
final int len = argumentArray.length;
for (int i = 0; i < len; i++) {
if(i != 0)
if (i != 0)
sb.append(VALUE_SEPARATOR);
sb.append(QUOTE).append(jsonEscapedToString(argumentArray[i])).append(QUOTE);

Expand Down Expand Up @@ -407,4 +447,73 @@ boolean isNotEmptyMap(Map map) {
public byte[] footerBytes() {
return EMPTY_BYTES;
}

/**
* @param withSequenceNumber
* @since 1.5.0
*/
public void setWithSequenceNumber(boolean withSequenceNumber) {
this.withSequenceNumber = withSequenceNumber;
}

/**
* @param withTimestamp
* @since 1.5.0
*/
public void setWithTimestamp(boolean withTimestamp) {
this.withTimestamp = withTimestamp;
}

/**
* @param withNanoseconds
* @since 1.5.0
*/
public void setWithNanoseconds(boolean withNanoseconds) {
this.withNanoseconds = withNanoseconds;
}

public void setWithLevel(boolean withLevel) {
this.withLevel = withLevel;
}

public void setWithThreadName(boolean withThreadName) {
this.withThreadName = withThreadName;
}

public void setWithLoggerName(boolean withLoggerName) {
this.withLoggerName = withLoggerName;
}

public void setWithContext(boolean withContext) {
this.withContext = withContext;
}

public void setWithMarkers(boolean withMarkers) {
this.withMarkers = withMarkers;
}

public void setWithMDC(boolean withMDC) {
this.withMDC = withMDC;
}

public void setWithKVPList(boolean withKVPList) {
this.withKVPList = withKVPList;
}

public void setWithMessage(boolean withMessage) {
this.withMessage = withMessage;
}

public void setWithArguments(boolean withArguments) {
this.withArguments = withArguments;
}

public void setWithThrowable(boolean withThrowable) {
this.withThrowable = withThrowable;
}

public void setWithFormattedMessage(boolean withFormattedMessage) {
this.withFormattedMessage = withFormattedMessage;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.util.EnvUtil;
import ch.qos.logback.core.util.StringUtil;
import org.slf4j.Marker;
import org.slf4j.event.KeyValuePair;
import org.slf4j.helpers.MessageFormatter;
Expand Down Expand Up @@ -225,7 +226,7 @@ private String extractThreadName(Thread aThread) {
return CoreConstants.NA;
}
String threadName = aThread.getName();
if (threadName != null && !threadName.isEmpty())
if (StringUtil.notNullNorEmpty(threadName))
return threadName;
Long virtualThreadId = getVirtualThreadId(aThread);
if (virtualThreadId != null) {
Expand Down
Loading

0 comments on commit 9078f68

Please sign in to comment.