Set custom name for Log4j2 log level in XML configuration file - java

I'd like to force my log4j2 to display log level like "Warning" instead of "WARN" etc.
Is it possible to do so? It can't be done programmatically, it must be done in XML configuration file because I'm using it in an already built image so I don't have access to the source code.
I tried something like this but it did nothing.
<CustomLevels>
<CustomLevel name="Warning" intLevel="300" />
<CustomLevel name="Information" intLevel="400" />
</CustomLevels>
I'd like to replace default log levels with my custom names.
Edit:
I need something like this, but for JsonTemplateLayout:
<PatternLayout>
<Pattern>"%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, INFO=Info}"</Pattern>
</PatternLayout>
It must be in JSON format using JsonTemplateLayout (no PatternLayout)

I found the solution! :)
<JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json">
<EventTemplateAdditionalField
key="#l"
format="JSON"
value='{"$resolver": "pattern", "pattern": "%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, INFO=Information}"}'/>
</JsonTemplateLayout>
It's not very elegant, but it works :)
Edit:
I'm not sure why, but for ERROR level it didn't work correctly.
It changed ERROR to Error, but my #l contained also exception message.
I needed to add %ex{none} to my pattern like this:
{"$resolver": "pattern", "pattern": "%level{FATAL=Fatal, ERROR=Error}%ex{none}"}

Related

Providing a method name in the log4j2 GelfLayout

I'm trying to include a calling method name as a separate field in the Gelf:
<Socket name="Graylog" protocol="udp" host="127.0.0.1" port="12201">
<GelfLayout>
<KeyValuePair key="method" value="%M"/>
</GelfLayout>
</Socket>
But in the Graylog this field's value appears just as %M, no value substitution is happening.
I read the manual, but couldn't find anything about resolving message pattern placeholders in the custom fields.
I know that logstash-gelf can do this, but is it possible to do this without using an extra plugin, using the standard log4j2?
I wanted to show what ID the thread had, but just as you, I noticed that the text was treated as static text. I looked into this and acording to the documentation it should be possible to use patterns, but not in <KeyValuePair>
<GelfLayout includeThreadContext="true" threadContextIncludes="loginId,requestId">
%d %5p [%t] %c{1} %X{loginId, requestId} - %m%n
<KeyValuePair key="additionalField1" value="constant value"/>
<KeyValuePair key="additionalField2" value="$${ctx:key}"/>
</GelfLayout>
Look at the second row, above. It looks as if it would be possible to use pattern placeholders as a general message. I have, however, not been able to get this to work, maybe the version I use is to old.
I have found out that Log4j2 does not currently support what we want. But it will do in the next version (2.15.0). I have no idea, how ever, when the next version will be released, se issue LOG4J2-3041 for details.
References:
https://logging.apache.org/log4j/2.x/manual/layouts.html#GELFLayout
https://issues.apache.org/jira/browse/LOG4J2-3041

How do I include a UNIX timestamp in a rolled log filename with log4j2?

What I have now in my config file
{
"type":"RollingFile",
"name": "machineLog",
"ThresholdFilter": { "level": "debug" },
"JsonLayout":{"complete":"true"},
"Policies":
{
"SizeBasedTriggeringPolicy": {"size":"100M"}
},
"fileName": "${sys:my.logging.directory}/machine.json",
"filePattern":"${sys:my.logging.directory}/RolledLogs/$${date:yyyy}/$${date:MM}/%d{yyyy-MM-dd-HH}-machine.json.gz"
}
I want the rolled file (filePattern entry) to contain a UNIX timestamp. Since this is legal I tried changing that line to be
"filePattern":"${sys:my.logging.directory}/RolledLogs/$${date:yyyy}/$${date:MM}/%d{UNIX}-machine.json.gz"
Figuring that since %d{UNIX} was mentioned in the Layout documentation page for log4j2 it would work.
The result is that it creates the unrolled machine.json file but seems to not be able to append to it. It remains at zero bytes even when I flood the system with things that normally generates a ton of logs with the original config.
What's going on here? How can I achieve the effect I want?
I'm not sure you can use all options of the PatternLayout %d date converter in the RollingFile filePattern.
However, if the ${sys:someKey... system properties lookup works, then a custom lookup will also work. So one idea is to write a custom lookup plugin that generates the unix timestamp, and configure the RollingFile filePattern like this:
"filePattern":"${sys:my.logging.directory}/RolledLogs/$${date:yyyy}/$${date:MM}/$${mylookup:UNIX}-machine.json.gz"
Here is an example of how to write a custom Log4j 2 lookup plugin: https://stackoverflow.com/a/27418802/1446916

log4j Appender additivity for custom log level

I have a scenario where I have a separate custom level defined XYZLogLevel for logging and I have 2 rolling file appenders where 2nd appender is specifically reserved to log log messages from XYZLogLevel. However the logs are going in both the files which is undesirable.
Note:-
Logs are not package specific, so adding additivity for package wont
work.
Everything has to be done through log4j.properties file.
Adding LevelRangeFilter to first appender partially resolves it, but
when I add 3rd appender for another custom level, then I again see
duplication in 2nd and 3rd appender.
log4j.rootCategory=ERROR, F, XYZLOG, LMNLOG
log4j.appender.F=org.apache.log4j.RollingFileAppender
log4j.appender.F.File=f_log.log
log4j.appender.F.MaxFileSize=5MB
log4j.appender.F.MaxBackupIndex=10
log4j.appender.F.layout = org.apache.log4j.PatternLayout
log4j.appender.F.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %c{1} [%p] %m%n
log4j.appender.XYZLOG=org.apache.log4j.RollingFileAppender
log4j.appender.XYZLOG.File=xyz_reporting.log
log4j.appender.XYZLOG.threshold=XYZLOG#com.services.domain.xyzlogs.XYZLogLevel
log4j.appender.XYZLOG.filter.a=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.XYZLOG.filter.a.LevelToMatch=XYZLOG#com.services.domain.xyzlogs.XYZLogLevel
log4j.appender.XYZLOG.filter.a.AcceptOnMatch=true
log4j.appender.XYZLOG.MaxFileSize=100KB
log4j.appender.XYZLOG.MaxBackupIndex=10
log4j.appender.XYZLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.XYZLOG.layout.ConversionPattern=%m%n
log4j.appender.LMNLOG=org.apache.log4j.RollingFileAppender
log4j.appender.LMNLOG.File=lmn_reporting.log
log4j.appender.LMNLOG.threshold=LMNLOG#com.services.domain.lmnlogs.LMNLogLevel
log4j.appender.LMNLOG.filter.a=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.LMNLOG.filter.a.LevelToMatch=LMNLOG#com.services.domain.lmnlogs.LMNLogLevel
log4j.appender.LMNLOG.filter.a.AcceptOnMatch=true
log4j.appender.LMNLOG.MaxFileSize=100KB
log4j.appender.LMNLOG.MaxBackupIndex=10
log4j.appender.LMNLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.LMNLOG.layout.ConversionPattern=%m%n
Maybe this can be solved through org.apache.log4j.varia.DenyAllFilter but somehow I was not able to configure that for properties file. I believe that functionality is only for XML configuration.
Its a very tricky sitution as I dont have the liberty to switch to XML configuration, any help on this would be appreciated guys.
Link and examples would be great as I understand them quickly.
I am answering my own question.
First you need to create a logger and set additivity as FALSE.
log4j.logger.XZYLOG=XZYLOG#XYZLOG#com.services.domain.xyzlogs.XYZLogLevel, XYZAPPENDER
log4j.additivity.XZYLOG=false
log4j.logger.LMNLOG=LMNLOG#XYZLOG#com.services.domain.lmnlogs.LMNLogLevel, LMNAPPENDER
log4j.additivity.LMNLOG=false
Then configure the appenders in following way.
log4j.appender.XYZLOGAPPENDER=org.apache.log4j.RollingFileAppender
log4j.appender.XYZLOGAPPENDER.File=xyz_reporting.log
log4j.appender.XYZLOGAPPENDER.threshold=XYZLOG#com.services.domain.xyzlogs.XYZLogLevel
log4j.appender.XYZLOGAPPENDER.MaxFileSize=100KB
log4j.appender.XYZLOGAPPENDER.MaxBackupIndex=10
log4j.appender.XYZLOGAPPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.XYZLOGAPPENDER.layout.ConversionPattern=%m%n
log4j.appender.LMNLOGAPPENDER=org.apache.log4j.RollingFileAppender
log4j.appender.LMNLOGAPPENDER.File=lmn_reporting.log
log4j.appender.LMNLOGAPPENDER.threshold=LMNLOG#com.services.domain.lmnlogs.LMNLogLevel
log4j.appender.LMNLOGAPPENDER.MaxFileSize=100KB
log4j.appender.LMNLOGAPPENDER.MaxBackupIndex=10
log4j.appender.LMNLOGAPPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.LMNLOGAPPENDER.layout.ConversionPattern=%m%n
You may or may not need the filter in this case.
Note: I cannot post company code here thats why I modified the solution.
This is to give you general idea how I have solved this problem.

Setting rollover strategy in log4j2.properties

Can anybody help me with setting the rolloverstrategy in log4j2.properties ?
I have set it up as -
#Appender
appender.test.type=RollingFile
appender.test.name=test
appender.test.fileName=${logPath}/test.log
appender.test.filePattern = ${logPath}/test-%i.log
appender.test.layout.type=PatternLayout
appender.test.layout.pattern=%d{ISO8601} %-5p [%t] %m%n
appender.test.policies.type=Policies
appender.test.policies.size.type=SizeBasedTriggeringPolicy
appender.test.policies.size.size=1MB
appender.test.strategies.type=Strategies
appender.test.strategies.rollover.type=DefaultRolloverStrategy
appender.test.strategies.rollover.max=5
I wrote this consulting https://logging.apache.org/log4j/2.x/manual/configuration.html#ConfigurationSyntax
I didn't find anything for implementing rollover strategy and what you see above is what I thought would work.But unfortunately and obviously it does not.
Here is the error:
2015-11-09 13:30:42,175 localhost-startStop-1 ERROR Unable to locate plugin for Strategies
There is another section on that page that may be useful:
http://logging.apache.org/log4j/2.x/manual/configuration.html#Properties
It contains an example properties configuration with rollover. Furthermore you can find the supported RollingFileAppender Parameters on its manual page: http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender
Try this:
appender.test.strategy.type=DefaultRolloverStrategy
appender.test.strategy.max=5
Let me know if it works and I'll add it to the manual page.

Log4j2 Rolling appender - fileName "sliding" according to pattern

I am looking for rollover strategy where current log (active output target in manual's terminology) file name is not fixed but specified by a pattern, or - more precisely - same pattern as in filePattern attribute.
I want to achieve daily rollover where today's log is, say, log-2015-05-05.log and on midnight framework just stops writing it and starts writing into log-2015-05-06.log. However, AFAIK, current configuration allows only
<RollingFile name="ROLFILE"
fileName="log.log"
filePattern="log-%d{yyyy-MM-dd}.log"
>
Specifying same value into fileName attribute doesn't work (leads to file with sensitive characters literally interpreted). I noticed no example or SO question with such a dynamic value of fileName. Note the fileName="log-${date:yyyy-MM-dd}.log" doesn't solve problem since expression is evaluated only at startup and events are still sent into file even if their timestamp doesn't match the expression.
I am migrating from Log4j 1.2 to Log4j 2.2. In old version, required behavior was possible using
<appender name="ROLFILE" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern" value="log-%d{yyyy-MM-dd}.log" />
</rollingPolicy>
...
I prefer to preserve current way since some log analyzing tools rely on it.
Is it possible in Log4j2?
Thanks.
Note sure if this works, but you can try using a double $$ in the date lookup. This allows the variable to be resolved at runtime.
<RollingFile name="ROLFILE"
fileName="log-$${date:yyyy-MM-dd}.log"
filePattern="oldlog-%d{yyyy-MM-dd}.log"
>
You may need to be careful to ensure that the active output target file name is different from the after-rollover file name. (I used 'oldlog' in the snippet above.)
Finally, I wrote my own rollover strategy which generates different set of rollover actions. Instead renaming active file the active file name is simply replaced inside RollingFileManager. Yes, it's ugly reflection hack and also appender must be initialized with fileName constant corresponding with current date and having same pattern, e.g.
<RollingFile name="ROLFILE"
fileName="log-${date:yyyy-MM-dd}.log"
filePattern="log-%d{yyyy-MM-dd}.log"
>
<SlidingFilenameRolloverStrategy />
...
yet for me this solution is worth doing it despite these small drawbacks.
(Initial fileName stays forever as a key in AbstractManager registry MAP even if in manager itself it has been changed - seems it doesn't mind, I also tried replacing manager in registry for new one but it's impossible to collect all parameters necessary for its construction.)
I hope this hack shouldn't have been so ugly if RollingFileManager API made it possible normal way. I got some hope seeing this javadoc but framework AFAIK never utilizes this field, let alone for mutating RollingFileAppender.
I think it would work just fine using:
fileName="log-${date:yyyy-MM-dd}.log"
filePattern="log-%d{yyyy-MM-dd}.log"
I use it with log4j2 version 2.5
This has been implemented in Log4j 2.8 (see issue LOG4J2-1101).
Currently it only works with a RollingFile appender by omitting the filename parameter and using a DirectWriteRolloverStrategy.
Also, this feature seems to have some issues with the TimeBasedTriggeringPolicy (the first rollover doesn't happen so every logfile is offset by one interval); CronTriggeringPolicy works properly.
Example config:
<RollingRandomAccessFile name="MyLogger"
filePattern="logs/application.%d{yyyy-MM-dd}.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<CronTriggeringPolicy schedule="0 * * * * ?" evaluateOnStartup="true"/>
</Policies>
<DirectWriteRolloverStrategy/>
</RollingRandomAccessFile>
Support for RollingRandomAccessFile appender is requested in issue LOG4J2-1878.
Edit: Changed to CronTriggeringPolicy policy after finding TimeBasedTriggeringPolicy had issues.

Categories