'Math operations inside log4j2.xml
I want to add a custom pattern inside log4j2.xml.
In there I need to do some math operations like multiplication (*), modulo(%) of the log output.
For an example, assume I'm getting the Unix time in seconds as the log output. If I need to multiply it by 1000, how should I do it?
I tried out different ways of doing that. But it outputs the math operations as plain text.
Here is the example pattern I used in log4j2.xml. I tried out different ways of multiplications in there.
<Console name="stdout" target="SYSTEM_OUT">
<PatternLayout>
<pattern>%d{UNIX} %{1000*%d{UNIX}} (%d{UNIX})*1000 1000*(%d{UNIX}) %n</pattern>
</PatternLayout>
</Console>
It outputs the plain text value. Not the values after multiplication.
1645687086 %{1000*1645687086} (1645687086)*1000 1000*(1645687086)
So is there a way that I can do math operations like muliplication(*) and modulo(%) inside the xml tag itself?
Solution 1:[1]
Your question is probably a classical XY problem.
If you want to print the timestamp in milliseconds from the Epoch use %d{UNIX_MILLIS}.
If, on the other hand, you are looking for PatternConverter that performs arithmetic substitution, there isn't one. The list of the available patterns can be found in the documentation.
However Log4j 2.x is very extensible and you can write and register your own pattern converter.
Edit: To create a new PatternConverter you can start from something like this:
@Plugin(name = "math", category = "Converter")
@ConverterKeys({ "math" })
public class MathPatternConverter extends LogEventPatternConverter {
private final List<PatternFormatter> patterns;
public static MathPatternConverter newInstance(Configuration config, String[] options) {
if (options.length < 1) {
LOGGER.error("Incorrect number of options. Expected at least 1, received " + options.length);
return null;
}
if (options[0] == null) {
LOGGER.error("No pattern supplied.");
return null;
}
final PatternParser parser = PatternLayout.createPatternParser(config);
return new MathPatternConverter(parser.parse(options[0]));
}
protected MathPatternConverter(List<PatternFormatter> patterns) {
super("math", "math");
this.patterns = patterns;
}
@Override
public void format(LogEvent event, StringBuilder toAppendTo) {
final StringBuilder sb = new StringBuilder();
patterns.stream().forEach(f -> f.format(event, sb));
// sb contains a mathematical expression. You need to evaluate it.
... put your code here ...
}
}
and use it as %math{10 + 20}. In order to register this plugin with Log4j 2.x proceed as described in the plugins documentation.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
