Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log FATAL (or any custom log level) with SLF4J and Log4j2

Tags:

java

slf4j

log4j2

I have those specific requirements :

  • Need to be able to log in FATAL level
  • Need to use SLF4J
  • Need to use Log4j2

Right now, here's my implementation:

final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
final Marker marker = MarkerFactory.getMarker("FATAL");
logger.error(marker, "!!! Fatal World !!!");

Here's my PatternLayout (in yaml):

PatternLayout:
  Pattern: "%d{ISO8601_BASIC} %-5level %marker [%t] %logger{3.} - %msg%n"

Here's my log output :

20150506T155705,158 ERROR FATAL [main] - !!! Fatal World !!!

Do you have any idea about how to efficiently to remove the "ERROR" from the log output?

Thank you very much

like image 303
Daniel Marcotte Avatar asked May 06 '15 20:05

Daniel Marcotte


3 Answers

Marker is not really what you want here. Marker is for "enriching" log messages, making them more easily searchable. You are trying to change the log level/priority, which is a little different.

You're using logger.error() which will log the message as an ERROR level.

If there is no FATAL level pre-defined (usually there is, such as logger.fatal()), then use the generic logger.log() which allows you to specify the log level.

logger.fatal(yourMessage);

OR

logger.log(priorityLevel, yourMessage);

UPDATE:

From the SLF4J website:

The Marker interface, part of the org.slf4j package, renders the FATAL level largely redundant. If a given error requires attention beyond that allocated for ordinary errors, simply mark the logging statement with a specially designated marker which can be named "FATAL" or any other name to your liking.

http://www.slf4j.org/faq.html#fatal

So, with SLF4J, it is not possible to have a FATAL log level. I strongly disagree with the rationale behind this decision, but it is what it is.

like image 110
SnakeDoc Avatar answered Nov 11 '22 10:11

SnakeDoc


Here's the closest working solution I came with some colleagues :

  1. Create a Fatal Marker class using SLF4J Markers.
  2. Using a RoutingAppender, use the Marker as the routing pattern: "$${marker:}"
  3. Configure a Fatal-specific appender that has its own PatternLayout that doesn't include the LogLevel but a hardcoded FATAL level.

Here's the Java sample :

Marker fatal = MarkerFactory.getMarker("FATAL");
// Usage example
final Logger logger = LoggerFactory.getLogger(FatalLogger.class);
logger.log(fatal, "this is a fatal message");

// Log sample : 
20150514T115144,279  FATAL [main] FatalLogger - this is a fatal message

Here's the YAML sample :

Configuration:
  status: debug

  Appenders:
    RandomAccessFile:
      - name: APPLICATION_APPENDER
        fileName: logs/application.log
        PatternLayout:
          Pattern: "%d{ISO8601_BASIC} %-5level %msg%n"
      - name: FATAL_APPENDER
        fileName: logs/application.log
        PatternLayout:
          Pattern: "%d{ISO8601_BASIC} FATAL %msg%n"

    Routing:
      name: ROUTING_APPENDER
      Routes:
        pattern: "$${marker:}"
        Route:
        - key: FATAL
          ref: FATAL_APPENDER
        - ref: APPLICATION_APPENDER #DefaultRoute

  Loggers:
    Root:
      level: trace
      AppenderRef:
        - ref: ROUTING_APPENDER
like image 8
Daniel Marcotte Avatar answered Nov 11 '22 10:11

Daniel Marcotte


I know the question is for log4j. I found this page when looking in relation to logback. Here's what sl4j recommends: https://www.slf4j.org/faq.html#fatal.

like image 3
thebiggestlebowski Avatar answered Nov 11 '22 10:11

thebiggestlebowski