Log4J2 Framework¶
Similar to Logstash, you can get access to Log4J specific features by casting to the underlying Log4JCoreLogger
class.
import com.tersesystems.echopraxia.log4j.*;
import com.tersesystems.echopraxia.api.*;
Log4JCoreLogger core = (Log4JCoreLogger) CoreLoggerFactory.getLogger();
Marker Access¶
The Log4JCoreLogger
has a withMarker
method that takes a Log4J marker:
final Marker securityMarker = MarkerManager.getMarker("SECURITY");
Logger<FieldBuilder> logger = LoggerFactory.getLogger(
core.withMarker(securityMarker), FieldBuilder.instance);
If you have a marker set as context, you can evaluate it in a condition through casting to Log4JLoggingContext
:
Condition hasAnyMarkers = (level, context) -> {
Log4JLoggingContext c = (Log4JLoggingContext) context;
Marker m = c.getMarker();
return securityMarker.equals(m);
};
If you need to get the Log4j logger from a core logger, you can cast and call core.logger()
:
Logger<PresentationFieldBuilder> baseLogger = LoggerFactory.getLogger();
Log4JCoreLogger core = (Log4JCoreLogger) baseLogger.core();
org.apache.logging.log4j.Logger log4jLogger = core.logger();
Direct Log4J API¶
In the event that the Log4J2 API must be used directly, an EchopraxiaFieldsMessage
can be sent in for JSON rendering.
import com.tersesystems.echopraxia.api.FieldBuilder;
import com.tersesystems.echopraxia.api.FieldBuilderResult;
import com.tersesystems.echopraxia.log4j.layout.EchopraxiaFieldsMessage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
FieldBuilder fb = FieldBuilder.instance();
Logger logger = LogManager.getLogger();
EchopraxiaFieldsMessage message = structured("echopraxia message {}", fb.string("foo", "bar"));
logger.info(message);
EchopraxiaFieldsMessage structured(String message, FieldBuilderResult args) {
List<FIeld> loggerFields = Collections.emptyList();
return new EchopraxiaFieldsMessage(message, loggerFields, result.fields());
}
Note that exceptions must also be passed outside the message to be fully processed by Log4J:
Exception e = new RuntimeException();
EchopraxiaFieldsMessage message = structured("exception {}", fb.exception(e));
logger.info(message, e);
Unfortunately, I don't understand Log4J internals well enough to make conditions work using the Log4J API. One option could be to write a Log4J Filter to work on a message.