I am playing around with a Struts2 webapp (Struts 2.2.3.1) running on Tomcat 6.
As seen in several tutorials, I have the following bit in my log4j.xml, which is deployed in the webapp's WEB-INF/classes directory:
<logger name="com.opensymphony">
<level value="DEBUG" />
</logger>
<logger name="org.apache.struts2">
<level value="DEBUG" />
</logger>
After setting the property log4j.debug=true in my Tomcat confiuration, I find (as expected) the following output in the Tomcat log:
log4j: DocumentBuilderFactory is: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.opensymphony] additivity to [true].
log4j: Level value for com.opensymphony is [DEBUG].
log4j: com.opensymphony level set to DEBUG
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.apache.struts2] additivity to [true].
log4j: Level value for org.apache.struts2 is [DEBUG].
log4j: org.apache.struts2 level set to DEBUG
log4j: Level value for root is [DEBUG].
log4j: root level set to DEBUG
However, no Struts debugging messages can be found at all in any logfile.
My log4j version is 1.2.14.
How can I properly control Struts' logging?
If i am correct you have to define some sort of Appender in order to redirect the log output to the log file.
in default case struts2 log will be getting displayed on the console.Define something like this in your log4j file
<appender name="FA" class="org.apache.log4j.FileAppender">
<param name="File" value="sample.log"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n" />
</layout>
</appender>
You have to tell log4j where to redirect the logout
Related
Question
How to parse the unstructured Log4J log in Java/Scala.
Background
There are multiple questions on how to parse Log4J logs but mostly they recommend using XML or JSON appender to output structured outputs to parse. However need to parse already generated unstructured log files programmatically, not using tools such as logstash, chainsaws GUI.
Help with LogFilePatternReceiver shows the way but it requires "plugin" support which was supposed to be implemented in Log4J 1.3 but Log4J 1.x discontinued with 1.2.x. It looks Log4J 2 does not have LogFilePatternReceiver.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration >
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout"/>
<filter class="org.apache.log4j.filter.ExpressionFilter">
<param name="Expression" value="msg ~= 'SPECIFY CASE-INSENSITIVE MSG MATCH HERE'" />
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="org.apache.log4j.filter.DenyAllFilter"/>
</appender>
<plugin name="LOGFILE" class="org.apache.log4j.varia.LogFilePatternReceiver">
<param name="fileURL" value="file:///c:/some.log"/>
<param name="timestampFormat" value="yyyy-MM-dd HH:mm:ss,SSS"/>
<param name="logFormat" value="TIMESTAMP LEVEL [LOGGER] MESSAGE"/>
<param name="name" value="my log file"/>
<param name="tailing" value="true"/>
</plugin>
<root>
<level value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>
There is a class LogFileParser in org.apache.log4j.lf5.util.LogFileParse package but not sure how to use it. There is a tool OtrosLogViewer but prefer not having 3rd party dependencies if possible.
Options
Re: Extract log info from each output log line on the console suggests refering to the Chainsaw code. Read the code and implement similar would be the option but if there is already a known way to parse logs, would like to know it first.
References
Parse a log4j log file
Class LogFilePatternReceiver
Found a way by using log4j and extras 1.2 jars, although not work with Log4J 2.
Java
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.receivers.varia.LogFilePatternReceiver;
public class LogParser extends LogFilePatternReceiver {
final static Logger logger = Logger.getLogger(LogParser.class);
public void doPost(LoggingEvent event) {
System.out.println(event.getTimeStamp());
System.out.println(event.getMessage());
}
public static void main(String[] args) {
(new LogParser()).run();
}
private void run(){
LogFilePatternReceiver r = new LogParser();
r.setLogFormat("TIMESTAMP LEVEL [THREAD] CLASS (FILE:LINE) - MESSAGE");
r.setFileURL("file:///tmp/log");
r.setTimestampFormat("yyyy-MM-dd HH:mm:ss,SSS");
r.setTailing(true);
r.setLoggerRepository(logger.getLoggerRepository());
r.activateOptions();
}
}
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Sample log file
2017-12-02 16:53:42,618 DEBUG [main] LogParser (LogParser.java:15) - message 1
2017-12-02 16:53:42,624 DEBUG [main] LogParser (LogParser.java:16) - message 2
Result
2017-12-02 19:21:31,633 INFO [main] spi.Log4JULogger (Log4JULogger.java:104) - activateOptions
2017-12-02 19:21:31,652 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - regexp is (\S+-\S+-\S+ \S+:\S+:\S+,\S+)[ ]+(\S*\s*?)[ ]+\[(.*?)\][ ]+(.*?)[ ]+\((.*?):(.*?)\)[ ]+\-[ ]+(.*)
2017-12-02 19:21:31,652 INFO [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:104) - attempting to load file: file:///tmp/log
1512194022618
message 1
1512194022624
message 2
2017-12-02 19:21:33,656 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - tailing file
2017-12-02 19:21:35,660 DEBUG [LogFilePatternReceiver-plugin] spi.Log4JULogger (Log4JULogger.java:58) - tailing file
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/
I am trying to deploy a grails application on JBoss EAP, the problem is that no output from my application is logged except for stdout and stderr.
I really don't understand how the logging works in this case since jboss uses some internal logging system and grails uses log4j.
This is my logging configuration in standalone.xml:
<subsystem xmlns="urn:jboss:domain:logging:1.1">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE">
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.apache.tomcat.util.modeler">
<level name="WARN"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<logger category="jacorb">
<level name="WARN"/>
</logger>
<logger category="jacorb.config">
<level name="ERROR"/>
</logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
</subsystem>
Which is default.
This log4j configuration is in my Config.groovy:
// log4j configuration
log4j = {
// Example of changing the log pattern for the default console appender:
//
//appenders {
// console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
//}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
all additivity: false, console: [
'grails.app.controllers.com.redhat.theses',
'grails.app.domain.your.com.redhat.theses',
'grails.app.services.com.redhat.theses',
'grails.app.taglib.com.redhat.theses',
'grails.app.conf.com.redhat.theses',
'grails.app.filters.com.redhat.theses'
]
}
I really don't understand this logging stuff, it is so confusing, all I want is to log at least all errors, for starters. One would think that such a crucial feature works by default.
If I set this property when starting JBoss:
./standalone.sh -Dorg.jboss.as.logging.per-deployment=false
it works exactly as I want. But is it all right? Why do I have to set this property in order to get such a crucial function as logging, really?
Thank you so much for any help, I am sorry if I sound a bit arrogant, I have been trying to figure this out for hours and I am still where I was at the beginning.
The org.jboss.as.logging.per-deployment environment variable, AKA host property, AKA environment property tells JBoss which logging config to use. Setting it to true tells JBoss to use the logging config in the application being deployed. I would not know how to set that up in Grails Config.groovy. I do the config in JBoss after setting that host property to false. False means use the logging config in JBoss.
In JBoss set the property to false and then just create a grails.app category and have it log to a file Handler. That works for me in Grails and EAP 6.0 running in domain mode.
I have a simple Netbeans 7.1.2 (NON MAVEN) project that use glassfish 3.1 server for testing.
I created a log4j2.xml file and placed it on the classpath
here it is
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="debug"/>
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} [%t] %-5p %c{1} - %m%n"/>
</layout>
</appender>
<appender name="rolling-file" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="c:\tmp\Program-Name.log"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="4"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %l - %m%n"/>
</layout>
</appender>
<logger name="org.hibernate">
<level value="info" />
</logger>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
<appender-ref ref="rolling-file" />
</root>
</log4j:configuration>
the project uses hibernate to store data from a web service to a database.
However I am not able to log anything. I can see the logs of hibernate into the Netbeans IDE but I cannot see the created on the filesystem file.
I have this error when calling the web service
SEVERE: ERROR StatusLogger Unknown object "logger" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored
SEVERE: ERROR StatusLogger root contains an invalid element or attribute "priority"
SEVERE: ERROR StatusLogger Unknown object "root" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored
could someone pls help or give some advice I googled and stackoverflowed but without chance.
Paolo
I think that your log4j2.xml file is mixed with the old log4j style xml.
I'm having the same trouble as you when it comes to appending hibernate log to my application's log file. But I think that I can help with the logger error.
Try this file instead (and note the changes that I made):
<?xml version="1.0" encoding="UTF-8" ?>
<configuration name="SOME_PROJ_NAME" status="OFF">
<appenders>
<RollingFile name="rolling-file" fileName="c:/tmp/Program-Name.log" filePattern="c:/tmp/$${date:yyyy-MM}/Program-Name-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%d{ABSOLUTE} [%t] %-5p %c{1} - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="info"
<appender-ref ref="rolling-file"/>
</root>
<logger name="org.hibernate level="info">
<appender-ref ref="rolling-file"/>
</logger>
</loggers>
</configuration>
It is quite similar to the one that I'm using. Note that this file should be on classpath for log4j2 auto configuration to kick in.
The most important thing you should do when using the net to configure log4j2 is that you're looking at log4j2 and not log4j style configuration.
I suggest that you look in http://logging.apache.org/log4j/2.x/ for further info. They have a good downloadable pdf that you can check out.
In addition, check out my question about a similar problem.
Is there a way to get individual ant tasks to run quietly? I know of the -q switch, but that applies globally.
You could try implementing your own Ant logger.
One idea, using the existing listeners, would be to pipe all output to log4j and then implement a logging message filter that suppresses certain log messages
ant -listener org.apache.tools.ant.listener.Log4jListener
The log4j appender configuration would look something like:
<appender name=".." class="..">
..
..
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="ANT output to suppress" />
<param name="AcceptOnMatch" value="false" />
</filter>
</appender>