Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j 2.0 - Padding more conversion specifiers together as one element

I'm wondering if it is possible in Log4j 2.0 library to pad more conversion specifiers concatenated together.

For example, this pattern

%d{HH:mm:ss,SSS} %-5p [%-10t] %-22c - %m%n

produces something like

12.25.34,788 INFO  [SomeThread] my.path.to.Class       - First logged message
12.25.34,789 FATAL [Thread2   ] other.path.SecondClass - Second logged message
12.25.34.790 WARN  [Scheduler ] my.other.path.Class    - Another message

Now imagine I want to pad not only the conversion specifiers, but also whole parts of the pattern. In this case, for example, I want to pad [%-10t] %-22c.

12.25.34,788 INFO  [SomeThread] my.path.to.Class    - First logged message
12.25.34,789 FATAL [Thread2] other.path.SecondClass - Second logged message
12.25.34.790 WARN  [Scheduler] my.other.path.Class  - Another message

The notation could be something like

%d{HH:mm:ss,SSS} %-5p %-32{[%t] %c} - %m%n

(note %-35{...} - I want to pad whole content of this conversion specifier, just as one item)

I found this similar question, but there is no answer how to pad custom parts of the pattern, only answer with sample class extending PatternLayout to generate a string in format Class:method.


Additionally, I want to add padding between the two elements, as follows ([%t] is left-justified, %c is right-justified):

12.25.34,788 INFO  [SomeThread]    my.path.to.Class - First logged message
12.25.34,789 FATAL [Thread2] other.path.SecondClass - Second logged message
12.25.34.790 WARN  [Scheduler]  my.other.path.Class - Another message

It seems like the log4j library does not support it. So my question is: How can I achieve it? Possibly you can write a sample code. I believe it will help someone else, too.

like image 658
jjurm Avatar asked Jul 01 '14 17:07

jjurm


People also ask

What is pattern layout in LOG4J2?

Layout class and overrides the format() method to structure the logging information according to a supplied pattern. PatternLayout is also a simple Layout object that provides the following-Bean Property which can be set using the configuration file: Sr.No.

What is the difference between Log4j and LOG4J2?

Community support: Log4j 1. x is not actively maintained, whereas Log4j 2 has an active community where questions are answered, features are added and bugs are fixed. Automatically reload its configuration upon modification without losing log events while reconfiguring.

How does Log4j Appender work?

In the log4j2 architecture, an appender is basically responsible for sending log messages to a certain output destination. Here are some of the most useful types of appenders that the library provides: ConsoleAppender – logs messages to the System console. FileAppender – writes log messages to a file.

What is Log4j format?

Apache log4j provides various Layout objects, each of which can format logging data according to various layouts. It is also possible to create a Layout object that formats logging data in an application-specific way. All Layout objects receive a LoggingEvent object from the Appender objects.


2 Answers

I created a custom converter that may work for what you are looking to do. It allows you to group patterns within a pattern, and treat the groups as if they are a single entity. For example, the notation

%d{HH:mm:ss,SSS} %-5p %-32grp{[%t] %c} - %m%n

would produce output similar to your first request:

12.25.34,788 INFO  [SomeThread] my.path.to.Class    - First logged message
12.25.34,789 FATAL [Thread2] other.path.SecondClass - Second logged message
12.25.34.790 WARN  [Scheduler] my.other.path.Class  - Another message

Unfortunately there doesn't seem to be any way for the converter to know how "long" it is supposed to be, so it can't inherently handle your second request for the output to be both left and right justified. However, you can modify your pattern to mimic the behavior with something like:

%d{HH:mm:ss,SSS} %-5p %-16grp{[%t]} %16grp{%c} - %m%n

Here is the converter I wrote:

@Plugin(name="GroupingPatternConverter", category="Converter")
@ConverterKeys({"grp"})
public class GroupingPatternConverter extends LogEventPatternConverter {

    private final String pattern;

    public static GroupingPatternConverter newInstance(String[] options) {
        return new GroupingPatternConverter("grp", "grp", options);
    }

    private GroupingPatternConverter(String name, String style, String[] options) {
        super(name, style);
        if (options != null && options.length > 0) {
            this.pattern = options[0];
        } else {
            this.pattern = null;
        }
    }

    @Override
    public void format(LogEvent event, StringBuilder toAppendTo) {
        if (this.pattern == null) {
            return;
        }

        PatternParser parser = new PatternParser(null, "Converter", LogEventPatternConverter.class);
        List<PatternFormatter> formatters = parser.parse(this.pattern);

        StringBuilder groupBuilder = new StringBuilder();
        for (PatternFormatter formatter : formatters) {
            formatter.format(event, groupBuilder);
        }

        toAppendTo.append(groupBuilder.toString());
    }
}
like image 65
littlezz Avatar answered Nov 06 '22 13:11

littlezz


As of RC2, Log4j2 does not support this. You can raise a feature request on the Log4j2 Jira issue tracker. A patch would be great!

Meanwhile, if you want to align the start of the actual message, you could have a config where the minimum (padding) value is equal to the maximum (truncate) value for both the thread name and the logger name. I realize this is not ideal but this can be achieved with just configuration.

like image 27
Remko Popma Avatar answered Nov 06 '22 13:11

Remko Popma