Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.quarkiverse.googlecloudservices.logging.runtime.ecs.EscJsonFormat Maven / Gradle / Ivy
package io.quarkiverse.googlecloudservices.logging.runtime.ecs;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.ErrorManager;
import java.util.logging.Level;
import org.jboss.logmanager.ExtLogRecord;
import com.google.common.base.Strings;
import io.quarkiverse.googlecloudservices.logging.runtime.LoggingConfiguration;
import io.quarkiverse.googlecloudservices.logging.runtime.TraceInfo;
import io.quarkiverse.googlecloudservices.logging.runtime.util.SimpleFormatter;
/**
* This is the ESC json formatter.
*/
public class EscJsonFormat {
private static final SimpleFormatter MSG_FORMAT = new SimpleFormatter();
protected LoggingConfiguration config;
protected ErrorManager errorManager;
public Map format(ExtLogRecord record, TraceInfo tracing) {
return toEsc(record, tracing);
}
public void init(LoggingConfiguration config, ErrorManager errorManager) {
this.setLoggingConfiguration(config);
this.setErrorManager(errorManager);
}
public void setLoggingConfiguration(LoggingConfiguration config) {
this.config = config;
}
public void setErrorManager(ErrorManager errorManager) {
this.errorManager = errorManager;
}
public Map toEsc(ExtLogRecord record, TraceInfo tracing) {
if (this.config == null) {
return null; // sanity check
} else {
Map m = new HashMap<>();
putEcsVersion(m);
putTimestamp(m, record.getInstant());
putLoggerName(m, record.getLoggerName(), record.getLoggerClassName());
putThreadName(m, record.getThreadName());
putThreadId(m, record.getThreadID());
putFormattedMessage(m, record);
putLogLevel(m, record.getLevel());
putSource(m, record.getSourceClassName(), record.getSourceLineNumber(), record.getSourceMethodName());
putThrown(m, record.getThrown());
putHost(m, record.getHostName());
putMdcIfEnabled(m, record.getMdcCopy());
putParametersIfEnabled(m, record.getParameters());
if (tracing != null) {
putTracing(m, tracing);
}
return m;
}
}
protected void putTracing(Map m, TraceInfo tracing) {
if (!Strings.isNullOrEmpty(tracing.getTraceId())) {
getOrCreateObject(m, "trace").put("id", tracing.getTraceId());
}
if (!Strings.isNullOrEmpty(tracing.getSpanId())) {
getOrCreateObject(m, "span").put("id", tracing.getSpanId());
}
}
@SuppressWarnings("unchecked")
protected void putParametersIfEnabled(Map m, Object[] parameters) {
if (parameters != null && parameters.length > 0 && this.config.structured().parameters().included()) {
List list = (List) m.computeIfAbsent(this.config.structured().parameters().fieldName(),
(k) -> new ArrayList(parameters.length));
for (Object o : parameters) {
if (shouldIncludeParameter(o)) {
list.add(String.valueOf(o));
}
}
}
}
protected boolean shouldIncludeParameter(Object p) {
return true;
}
protected void putHost(Map m, String hostName) {
if (!Strings.isNullOrEmpty(hostName)) {
getOrCreateObject(m, "host").put("name", hostName);
}
}
protected void putThrown(Map m, Throwable thrown) {
if (thrown != null) {
Map error = getOrCreateObject(m, "error");
error.put("type", thrown.getClass().getName());
String msg = thrown.getMessage();
if (!Strings.isNullOrEmpty(msg)) {
error.put("message", msg);
}
if (this.config.structured().stackTrace().included()) {
// render as a standard out string
StringWriter sw = new StringWriter(1024);
PrintWriter pw = new PrintWriter(sw);
thrown.printStackTrace(pw);
pw.flush();
error.put("stack_trace", sw.toString());
}
}
}
protected void putMdcIfEnabled(Map m, Map mdcCopy) {
if (mdcCopy != null && !mdcCopy.isEmpty() && this.config.structured().mdc().included()) {
Map mdc = getOrCreateObject(m, this.config.structured().mdc().fieldName());
mdcCopy.forEach((k, v) -> mdc.put(k, v));
}
}
protected void putSource(Map m, String sourceClassName, int sourceLineNumber, String sourceMethodName) {
if (!Strings.isNullOrEmpty(sourceClassName)) {
Map log = getOrCreateObject(m, "log");
Map origin = getOrCreateObject(log, "origin");
Map clazz = getOrCreateObject(origin, "class");
clazz.put("name", sourceClassName);
clazz.put("line", Integer.valueOf(sourceLineNumber));
if (!Strings.isNullOrEmpty(sourceMethodName)) {
origin.put("function", sourceMethodName);
}
}
}
protected void putLogLevel(Map m, Level level) {
getOrCreateObject(m, "log").put("level", level.getName());
}
protected void putFormattedMessage(Map m, ExtLogRecord record) {
m.put("message", MSG_FORMAT.format(record));
}
protected void putThreadId(Map m, long longThreadID) {
// default value is zero, so check for that
if (longThreadID != 0) {
getOrCreateObject(getOrCreateObject(m, "process"), "thread").put("id", Long.valueOf(longThreadID));
}
}
protected void putThreadName(Map m, String threadName) {
if (!Strings.isNullOrEmpty(threadName)) {
getOrCreateObject(getOrCreateObject(m, "process"), "thread").put("name", threadName);
}
}
protected void putLoggerName(Map m, String loggerName, String loggerClassName) {
// logger class name takes precedence
if (!Strings.isNullOrEmpty(loggerClassName)) {
getOrCreateObject(m, "log").put("logger", loggerClassName);
} else if (!Strings.isNullOrEmpty(loggerName)) {
getOrCreateObject(m, "log").put("logger", loggerName);
}
}
@SuppressWarnings("unchecked")
protected Map getOrCreateObject(Map m, String name) {
return (Map) m.computeIfAbsent(name, (k) -> new HashMap(3));
}
protected void putEcsVersion(Map m) {
getOrCreateObject(m, "ecs").put("version", "1.2.0");
}
protected void putTimestamp(Map m, Instant instant) {
m.put("@timestamp", instant.atOffset(ZoneOffset.UTC).toString());
}
}