In my project I use Log4j 2.17.1.
I would like to format the output so that the class names have different colors.
public class MyClass {
Logger LOGGER = LogManager.getLogger(MyClass.class.getSimpleName());
//...
LOGGER.debug("Some Information");
}
public class MySecondClass {
Logger LOGGER = LogManager.getLogger(MySecondClass.class.getSimpleName());
//...
LOGGER.debug("Another Output");
}
In my example, I want the two classes to appear in different (perhaps random) colors (instead of yellow as in the example).
My current pattern layout:
%highlight{${LOG_LEVEL_PATTERN:-%5p}}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=green, DEBUG=green bold, TRACE=blue} : %style{%logger{36}:}{blue} %msg%n
Is this possible with Log4j?
Per defeault log4j writes simple text files with no fancy formatting applied (FileAppender, ConsoleAppender).
I have never done this, but I believe you can add ANSI escape sequences using a suitable formatting pattern, then enjoy the colours when the log output is sent to a terminal capable of understanding these sequences.
Related
i recently had the necessity to migrate from log4j 1.x to log4j 2.x.
In my code, i dynamically instantiate different Syslog appenders which may use two different layout types.
I'm using a getSysLogAppender method to generate a SyslogAppender object whenever i need in my code. Unfortunately, if i set the layout using the setLayout() function, my logs do not get sent one-at-a-time as i've expected. If i remove the setLayout() function from the builder and just leave the setFormat("RFC5424"), logs are sent correctly.
Due to application needs, i cannot just take the RFC5424 as it is implemented in log4j2, i need to customize the layout of the logs.
Looking at log4j2 SyslogAppender source code, if the format is RFC5424 and a layout is given, format RFC5424 is not taken into consideration: https://github.com/apache/logging-log4j2/blob/release-2.x/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java (line 114).
What's the correct way to customize the SyslogAppender layout?
Thanks in advance.
// Class variables
private static final String pattern1 = "%d %-1p - %m";
private static final String pattern2 = "%d %-5p [%t] %-4c{2} (%13F:%L) %3x - %m";
private static final String hostname = "localhost";
private static final String port = "2601";
private void createAppender() {
Appender appender = getSyslogAppender("TESTID", Facility.USER, pattern1); //third parameter may be also pattern2 var
appender.start();
}
// Method that generates my appender
private SyslogAppender getSyslogAppender(String id, Facility facility, String pattern) {
return SyslogAppender.newSyslogAppenderBuilder().withProtocol(myprotocol).withHost(hostname).withPort(port).setFacility(facility).setId(id).withBufferedIo(false)
.setLayout(org.apache.logging.log4j.core.layout.PatternLayout.newBuilder().withPattern(pattern).build())
.setName("log4jAppender").withImmediateFlush(true).setNewLine(true).setFormat("RFC5424").build();
}
Usually logging looks like this:
Duration duration = ...;
log.info("Duration: {}", duration);
But what do if you need custom formatting?
if (log.isInfoEnabled()) {
String value = duration.toSeconds() + "." + duration.toMillis();
log.info("Duration: {}", value);
}
In this case code is complicated. I'm looking for a way to do simple logging as in first sample but to be able to customize value formatting using some mechanism, e.g, define a format function for given type:
LogSystem.install(Duration.class, duration -> {
return String.format("%d.%d", duration.toSeconds(), duration.toMillis();
});
Questions:
does log4j 2.x have such or similar feature?
may be it exists in other logging libraries?
if no, can if (log.isInfoEnabled()) { ... } be simplified somehow?
does log4j 2.x have such or similar feature?
Yes, you can use
log.info("Duration: {}.{}", duration.toSeconds(), duration.toMillis());
You can pass as many parameters as you like. If you use parameterized logging, you don't need to check log.isInfoEnabled().
may be it exists in other logging libraries?
SLF4j also supports parameterized logging.
Yes, you can do it using the properties file.Set policies pattern in your log4j2.properties file like:
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ABClog/ABCapplication.log
appender.rolling.filePattern = ABClog/ABCapplication.%d{dd-MMM}.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = { [%-5level %d{dd-MM-yyyy hh:mm:ss.SSS } ] [%msg] }%n
After setting the above configuration in your log4j2.proerties file, you will get your desired output, even using properties file concept you can add extra info too e.g. Correlation-ID
log.info("hello")
Log4j2 document for more pattern style: https://logging.apache.org/log4j/2.x/manual/layouts.html
Is there any possibility to print event levels to log in lower case in log4j 2?
Like %level{lowerCase=true} in pattern in Log4j 2.
Can I process result string somehow, or use custom renderer?
You have to set a pattern to the appropriate appender in the log4j.properties file.
For instance, with ConsoleAppender:
log4j.appender.ConsoleAppender.layout.ConversionPattern=%d [%p{lowerCase=true}] %c{1} - %m%n
You can check the output here.
I need to create logs with key value pairs as below. Is there any support in PatternLayout to do this for the static fields in a thread like log_level, class_name, event_id etc with the log4j2.xml.
Sample log:
2014-06-18 11:57:46,719 log_level="INFO"
class_name="com.abc.dgl.App:main(158)" name="Application start event" event_id="b88f7ea0-4cb1-438f-a728-ac7c2bdac578" app="Test App" severity="info" action="loaded sfor file processing" desc="props was read and loaded" result="success" reason="abc" transaction_id="b88f7ea0-4cb1-438f-a728-ac7c2bdac578"
Yes, this is possible.
You can either use a MapMessage, which is supported by the map (or K) conversion pattern of PatternLayout: an example layout pattern would be "%-5p [%t]: %m %map%n".
Logging a MapMessage looks like this: Map<String,String> myMap = getMyMap(); Logger.debug(new MapMessage(myMap));
Another way to do this is to use the ThreadContext map. This is supported by the mdc (or X) conversion pattern of PatternLayout. Example pattern: "%-5p [%t]: %m %mdc%n".
A common usage is putting a user ID in the Thread Context Map when a user logs in, and having this user ID shown in all log messages emitted by that thread until the user logs out.
Instead of logging the whole map you can also log specific keys only by specifying the key in the layout pattern: e.g. "%-5p [%t]: %m %mdc{userID}%n".
I am looking for help with translating Validation messeges in Play framework 2.2
I have fields that are required:
f.e.
#Required(message = "To pole jest wymagane")
public String miesiac;
#Required
public String miejsce;
#Required
public String oddzial;
But I would to have this message: "To pole jest wymagane" globally.
How can I achive it?
Should I use conf/messagess.pl file for translation To polish language.
Please give me some help
Yes, you should use the conf/messages file for your default/primary language text and then one or more of the conf/messages.xx files for your translations.
The built-in validators are already setup to use the messages files. For example, the Required validator will look for the key error.required in your messages and display that text. So just define that key in your message files with the text you want to use.
If you wanted to use something other than the default then just specify the key with the message attribute (instead of the full text like in your example).
Model class
#Required(message = "my.required.message")
public String miesiac;
conf/messages
my.required.message=Hey, you have to type something here.
Take a look at the documentation for more info:
Externalising messages and internationalization
All what I found out. Here are my current custom messages in
conf/messages
error.required=This field is required
error.invalid=You need to enter a number
constraint.required=Required*