InvocationTargetException with RollingFileAppender in Log4J2 - log4j2

I'm trying to use a RollingFileAppender in Log4J2 and apparently I'm missing something. The file is created with 0 bytes, but no logging goes to it. When I turn on the trace I see the following error message logged (to the console) by log4J2:
2014-07-08 19:51:11,354 DEBUG Starting RollingFileManager c:/logs/blah.log
2014-07-08 19:51:11,464 DEBUG Generated plugins in 0.108079890 seconds
2014-07-08 19:51:11,465 ERROR Unable to invoke method createAppender in class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.logging.log4j.core.config.BaseConfiguration.createPluginObject(BaseConfiguration.java:913)
This is my config file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="TRACE" verbose="false">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="Blah" fileName="c:/logs/blah.log" filePattern="c:/logs/blah-%i.log">
<PatternLayout pattern="%d %p %c: %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="INFO">
<appender-ref ref="Blah" level="INFO"/>
</root>
</loggers>
</configuration>
It's probably something basic but I can't find it. Can anyone help?

Could you create a ticket on the Log4j2 issue tracker so the team can take a look at it? It may be a bug in version rc2. (I'm assuming you are using rc2 and have both the api and core jars in the classpath.)
Thanks!
I took a look and the class at the beginning of the stack trace (org.apache.logging.log4j.core.config.BaseConfiguration) no longer exists in log4j-core-2.0-rc2. It was renamed to AbstractConfiguration.
So I think this error is caused by an old log4j-core-2.0-rc1 jar that is still floating around somewhere.

Related

log4j2 environment variable substitution not working for filename attribute

I am trying to configure my daily rolling log file with a filename that contains server port number because this is a multi server application and each server will generate it's own log.
I have the following configuration
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="[%d{ISO8601}:$${env:SERVER_PORT}-L1] [th:%t] [%c] [%level] [%logger{36}] - %n[%d{ISO8601}:$${env:SERVER_PORT}-L2]%msg%n"/>
</Console>
<RollingFile name="dailyLog" immediateFlush="false" append="true">
<FileName>logs/rCOI.${env:SERVER_PORT:8090}.log</FileName>
<FilePattern>logs/rCOI.${env:SERVER_PORT:8090}.%d{yyyy-MM-dd}.log.zip</FilePattern>
<PatternLayout
pattern="[%d{ISO8601}:$${env:SERVER_PORT}-L1] [th:%t] [%c] [%level] [%logger{36}] - %n[%d{ISO8601}:$${env:SERVER_PORT}-L2]%msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
<DefaultRolloverStrategy max="5" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="dailyLog"/>
</Root>
</Loggers>
</Configuration>
This produces a log called
logs/rCOI.${env:SERVER_PORT:8090}.log
so it's not even using the default. I am sure that SERVER_PORT is defined and exported because I use it in the application with no issues.
I have tried $${env:SERVER_PORT:8090} and just ${SERVER_PORT} as well. Nothing is working.
It would be nice to be able to use an environment variable for the logs/ directory as well.

facing issue with log4j2 : java.lang.ExceptionInInitializerError

I'm facing issue with log4j2
below is my log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.opensymphony.xwork2" level="info"/>
<Logger name="org.apache.struts2" level="info"/>
<Root level="info">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
below is the exception
<Jun 21, 2018 7:23:48 PM IST> <Error> <HTTP> <BEA-101165> <Could not load user defined filter in web.xml: org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.
java.lang.ExceptionInInitializerError
at org.apache.logging.log4j.core.impl.Log4jLogEvent.createContextData(Log4jLogEvent.java:472)
at org.apache.logging.log4j.core.impl.Log4jLogEvent.<init>(Log4jLogEvent.java:331)
at org.apache.logging.log4j.core.impl.DefaultLogEventFactory.createEvent(DefaultLogEventFactory.java:54)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:401)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63)
Truncated. see log file for complete stacktrace
Caused By: java.lang.IllegalArgumentException: Initial capacity must be at least one but was 0
at org.apache.logging.log4j.util.SortedArrayStringMap.<init>(SortedArrayStringMap.java:102)
at org.apache.logging.log4j.core.impl.ContextDataFactory.createContextData(ContextDataFactory.java:109)
at org.apache.logging.log4j.core.impl.ContextDataFactory.<clinit>(ContextDataFactory.java:57)
at org.apache.logging.log4j.core.impl.Log4jLogEvent.createContextData(Log4jLogEvent.java:472)
at org.apache.logging.log4j.core.impl.Log4jLogEvent.<init>(Log4jLogEvent.java:331)
Truncated. see log file for complete stacktrace
>
above exception resulting to failure of war file deployment.
below are the jars used
1.commons-fileupload-1.3.3.jar
2.commons-io-2.5.jar
3.commons-lang3-3.6.jar
4.commons-logging-1.1.3.jar
5.freemarker-2.3.26-incubating.jar
6.javassist-3.20.0-GA.jar
7.log4j-1.2-api-2.11.0.jar
8.log4j-api-2.10.0.jar
9.log4j-core-2.11.0.jar
10.ognl-3.1.15.jar
11.struts2-core-2.5.16.jar
what do i need to correct?
Try upgrading log4j-api-2.10.0.jar to 2.11.0.
IllegalArgumentException is thrown from the constructor of org.apache.logging.log4j.util.SortedArrayStringMap:
public SortedArrayStringMap(final int initialCapacity) {
if (initialCapacity < 1) {
throw new IllegalArgumentException("Initial capacity must be at least one but was " + initialCapacity);
}
threshold = ceilingNextPowerOfTwo(initialCapacity);
}
and the given parameter initialCapacity has been changed since 2.11 as follows:
https://github.com/apache/logging-log4j2/blob/log4j-2.10.0/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java#L54
https://github.com/apache/logging-log4j2/blob/log4j-2.11.0/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java#L57
Updating the log4j-api and log4j-core from 2.11.1 to 2.12.0 solved the same problem for me.

Log4j2 Different appender for different level

I have a little problem and canĀ“t find a solution. I want to set pattern layout for level info another than for level warn. If I have a log in level INFO everything is OK, but if the log is levelWARN it is written out into console two times (as level info and as level warn). Simply all logs at a specific level is written out us log at that level and the level below.
I want to logs in level INFO write out to console like: "%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n" and level WARN like "%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n".
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
<Console name="ConsoleWarning" target="SYSTEM_OUT">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</Console>
<File name="File" fileName="logs/cli.log">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="ConsoleInfo"/>
<AppenderRef ref="ConsoleWarning"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
As I understand it you want to have log events with a level of WARN or higher (WARN,ERROR,FATAL) go to the "ConsoleWarning" appender only rather than going to both "ConsoleWarning" and "ConsoleInfo".
The simplest way to do this would be to modify your filter configuration in your "ConsoleInfo" appender to basically do the opposite approach like this:
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
This works because as the log4j2 manual states:
This filter returns the onMatch result if the level in the LogEvent is the same or more specific than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will be returned since ERROR events are more specific than DEBUG.
This will cause the appender to accept only events that have a level less than WARN.
Another possible solution would be to use a RoutingAppender to specify the destination for each level. If you do it this way then you don't need the ThresholdFilters at all. Also note that you can ignore events of specific levels by not providing a default route and not providing a route for that level. For example, if you remove <Route ref="ConsoleInfo" key="DEBUG" /> from the configuration below then all DEBUG events will be ignored by the routing appender and will not be printed to console. Here is the configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
<Console name="ConsoleWarning" target="SYSTEM_OUT">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</Console>
<File name="File" fileName="logs/cli.log">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</File>
<Routing name="Routing">
<Routes>
<Script name="RoutingInit" language="JavaScript"><![CDATA[
logEvent.getLevel();]]>
</Script>
<Route ref="ConsoleInfo" key="TRACE" />
<Route ref="ConsoleInfo" key="DEBUG" />
<Route ref="ConsoleInfo" key="INFO" />
<Route ref="ConsoleWarning" key="WARN" />
<Route ref="ConsoleWarning" key="ERROR" />
<Route ref="ConsoleWarning" key="FATAL" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="Routing"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
Hope this helps!

log4j2 Logs not writing to file when running as jar

I have configured log4j2.xml within eclipse and all logs write correctly to a file.
When I export maven project as a jar and run from command promt the logs are displayed on the console instead of writing to a file.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="file_all" fileName="C:/log/logsALL.log" immediateFlush="true" append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="file_all"/>
</Root>
<Logger name="com.api.main" level="INFO">
<AppenderRef ref="file_all"/>
</Logger>
</Loggers>
</Configuration>
When log4j starts up, it shows internal logging on the console (because status=trace in the configuration).
This internal log should show the location of the config file that is being used. Double-check that this is the correct location: I suspect that an old config file is being loaded that logs to the console...

How to configure port in Apache Chainsaw with Log4j2

I got log4j2.xml that generates log files. Here is the config:
<Configuration status="INFO" advertiser="multicastdns">
<Properties>
<Property name="layout">%d | %-5p | [%t] | %c{2} | %M | %m%n
</Property>
</Properties>
<Appenders>
<RollingFile name="LogFile" fileName="${sys:user.home}/logs/webapp.log"
filePattern="${sys:user.home}/logs/webapp-%d{yyyy-MM-dd}-%i.log"
bufferedIO="false" advertiseURI="file:///C://users/bilguuna/logs/webapp.log"
advertise="true">
<PatternLayout pattern="${layout}" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="LogFile" level="INFO" />
</Root>
</Loggers>
</Configuration>
I'm able to see a log file using
file:///C://users/bilguuna/logs/webapp.log
on the browser.
A problem is that on the ZeroConf tab, my appender "LogFile" is appeared with Connection status "Connected". But when I double click on that row, it's just changed to disconnected/connected. When I check Chainsaw-log. It said that Connection refused as image below:
I guess it's because of that Chainsaw chooses 4555 as a default port which is not open on my machine. So what port should choose and how to set it in my log4j2.xml file?
Thanks
UPDATE: After I used the developer snapshot version as #Scott suggested, it seems like "connection refused" problem went away. But still I can't see the logs. When I click on entry at ZeroConf tab, it still changes the Connection Status to Connected/Not Connected. Here is the log from chainsaw-log tab:
Again, was I supposed to see the actual logs when I double click on entry at ZeroConf tab?
Update: I got following exception on my console:
WARNING: SocketListener(WS00943.local.).run() exception
java.io.IOException: DNSIncoming corrupted message
at javax.jmdns.impl.DNSIncoming.<init>(DNSIncoming.java:239)
at javax.jmdns.impl.SocketListener.run(SocketListener.java:50)
Caused by: java.lang.IllegalStateException: Can't overwrite cause with java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [javax.jmdns.impl.constants.DNSResultCode]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
at java.lang.Throwable.initCause(Unknown Source)
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1344)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1206)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167)
at javax.jmdns.impl.DNSIncoming.readAnswer(DNSIncoming.java:342)
at javax.jmdns.impl.DNSIncoming.<init>(DNSIncoming.java:229)
... 1 more
Caused by: java.lang.ClassNotFoundException
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1343)
... 5 more
The problem is you need to use the latest developer snapshot of Chainsaw to work with log4j2. The webstart-runnable version works only with log4j1.
Developer snapshot is available at: http://home.apache.org/~sdeboy/

Resources