I am trying to stream some logging messages from an application that is a bit of a black box to me. It is packaged with commons-logging-1.0.4.jar and is using log4j underneath it. I am trying to stream one of the loggers so I can view it in chainsaw. I can direct the log messages to a file without a problem, but when I configure a socket appender I never see the connection accepted in the chainsaw log. I can telnet to port 4560 on the host running chain saw and will then see that connection accepted. I can't figure out what is mis-configured and am starting to wonder if this feature does not work with commons-logging. Here is the configuration snippet from the log4j.xml configuration. Is there something mis-configured that I don't understand?
<appender name="SOCKET" class="org.apache.logging.log4j.core.appender.SocketAppender">
<param name="RemoteHost" value="ljgaer"/>
<param name="Port" value="4560"/>
</appender>
<appender name="FILE2" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="/tmp/test.log" />
<param name="MaxFileSize" value="50MB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="###########MSG%n%m%n" />
</layout>
</appender>
<!-- Change level to ALL to turn on xml logging. -->
<logger name="XMLLogger" additivity="false">
<level value="ALL" />
<appender-ref ref="SOCKET" />
<appender-ref ref="FILE2" />
</logger>
Turns out the package name for the socket appender was wrong.
should have been
org.apache.log4j.net.SocketAppender
Related
My simple question is : If I have two statements like logger.info() and logger.error() in Java (using log4j), I want the results of these two lines to be printed in two separate files. That is, logger.info(...) should print to a file say myLog.info and logger.error(...) should print to myLog.error file. I am using rolling file appender for this task. Also I want just one logger object to do the task. Someone might suggest two or more different loggers one for each file, but that's not the case.
I tried searching a solution for the problem. One of the links Creating multiple log files of different content with log4j says about "threshold" and I even tried to add threshold in my xml configuration file. But what it actually is doing that : info log is being printed in myLog.info file but error log gets printed in both the files. Can it be done through xml configuration file alone or a separate properties file is needed? If xml file is sufficient, then what needs to be done?
I am preferring xml file over properties file. If there is a working solution using only xml configuration file, that would be sufficient. Thanks in advance.
You could use filters to deny any messages except those of the level you want. Here is an example of how to do this:
First a class to test our efforts:
package test;
import org.apache.log4j.Logger;
public class Main {
private static final Logger logger = Logger.getLogger(Main.class);
public static void main(String[] args) {
logger.debug("here's some debug");
logger.info("here's some info");
logger.warn("here's some warn");
logger.error("here's some error");
logger.fatal("here's some fatal");
}
}
Next a log4j.xml config file to set up the appenders and loggers:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<appender name="debugLog" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/debug.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5000KB" />
<param name="maxBackupIndex" value="5" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="DEBUG" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter" />
</appender>
<appender name="infoLog" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/info.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5000KB" />
<param name="maxBackupIndex" value="5" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter" />
</appender>
<logger name="test" additivity="false">
<level value="DEBUG" />
<appender-ref ref="consoleAppender" />
<appender-ref ref="debugLog" />
<appender-ref ref="infoLog" />
</logger>
</log4j:configuration>
This pattern will allow you to generate a separate log for each log level, just repeat the configuration that I have provided for either debug or info logging. Note that the console appender will accept all levels.
I was able to gain some insight from this post so I thought I should give credit.
I don't have a much knowledge in log4j and slf4j. But I want to understand how the actual logger is working in the below case.
I have a Web module,Service module and a Dao module.Web module has a dependency to Service and Service has a dependency to Dao .
In my web module there are 3 jars. slf4j jar, log4j jar and slf4j-log4j12 jar and log4j.xml is as below.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="C:\\temp\\web.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%t] %d{HH:mm:ss,SSS} %-5p %l - %m%n" />
</layout>
</appender>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<!--
Set the root logger priority via a system property. Note this is parsed by log4j
-->
<level value="trace" />
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.mywork">
<level value="DEBUG" />
<appender-ref ref="FILE" />
</logger>
<logger name="org.hibernate">
<level value="ERROR" />
<appender-ref ref="FILE" />
</logger>
<logger name="org">
<level value="ERROR" />
<appender-ref ref="FILE" />
</logger>
</log4j:configuration>
And In my service module and dao module contain only slf4j jar. And logging details are in file.(logging details of all modules)
Should the loggers of hibernate and Spring also available in my file ?
How the exception occur are available in logger file?
Thank you
You explicitly constrain org.* with ERROR level.
This effectively eliminates almost all output of hibernate and spring loggers.
But exceptions logged with error level should still get to file log.
Module dependencies configured in IDE are irrelevant. Logging happens in JBoss container and depends only on actual application's runtime classpath.
BTW, I highly recommend against trace level on root category.
See Production settings file for log4j? for the explanation.
My log4j logger does not want to use the log4j.xml file to be configured. This file is located in the src folder and looks like that:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="ROLLING" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="C:\debug\myproject\logfile.log" />
<param name="MaxFileSize" value="10024KB" />
<param name="MaxBackupIndex" value="5" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ROLLING" />
</root>
</log4j:configuration>
But logfile.log is still empty and there is no DEBUG line in the console.
NB: it is a Java EE project on JBoss 7.1.0 and using Struts2.
The following answer is not entirely mine. It was posted in the question itself by the OP, so I'm moving it into this community wiki answer.
I resolved it by explicitely configuring the logging configuration.
Note that you won't be able to change the configuration at runtime if you configure it using a file.
For more information, see: https://docs.jboss.org/author/display/AS71/How+To#HowTo-HowdoIuselog4j.propertiesorlog4j.xmlinsteadofusingtheloggingsubsystemconfiguration%3F
Make sure the log4j.xml file is located in the /WEB-INF/classes directory of your web application.
The problem was with the log file. If you use the absolute file name make sure to replace backslashes with slash. For example
<param name="File" value="C:/debug/myproject/logfile.log" />
Right now i use log4j in its plain vanilla/out-of-the-box form. I've a log4j.properties file in the class path and various logger messages littered across the web application. Now i'm interested in redirecting log messages from a method "abc" in package "xyz" to go to a specific log file "pqr". I dont want all the logger messages from package xyz to go to "pqr" but just from that one method ("abc") in the package.
How do i achieve this?
TIA
Bo
Here's the config file I'm using. This will send some specific messages to a file and others to the console. This may help you a little bit hopefully.
This is used in a standalone aplication.
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<!-- ============================== -->
<!-- Append SQL messages to a file. -->
<!-- ============================== -->
<appender name="SQL" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="TRACE" />
<param name="File" value="sql-statement.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5000KB" />
<param name="MaxBackupIndex" value="100" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<param name="Threshold" value="DEBUG" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %m%n" />
</layout>
</appender>
<!-- =============================== -->
<!-- Application specific categories -->
<!-- =============================== -->
<category name="com.edusoft.crashtest.qsbi">
<priority value="DEBUG" />
<appender-ref ref="CONSOLE" />
</category>
<category name="com.edusoft.crashtest.qsbi.printer" additivity="true">
<priority value="TRACE" />
<appender-ref ref="SQL" />
</category>
<!-- Setup the Root category -->
<root>
<priority value="ERROR" />
</root>
I don't think it can be that granular. Why not pull that method out to a separate class?
I am having problem that even though I specify the level to ERROR in the root tag, the specified appender logs all levels (debug, info, warn) to the file regardless the settings. I am not a Log4j expert so any help is appreciated.
I have checked the classpath for log4j.properties (there is none) except the log4j.xml.
Here is the log4j.xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="[AC - %5p] [%d{ISO8601}] [%t] [%c{1} - %L] %m%n" />
</layout>
</appender>
<appender name="logfile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/server.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="payloadAppender" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/payload.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="errorLog" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/error.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="traceLog"
class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/trace.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="20" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[AccessControl - %-5p] {%t: %d{dd.MM.yyyy - HH.mm.ss,SSS}} %m%n" />
</layout>
</appender>
<appender name="traceSocketAppender" class="org.apache.log4j.net.SocketAppender">
<param name="remoteHost" value="localhost" />
<param name="port" value="4445" />
<param name="locationInfo" value="true" />
</appender>
<logger name="TraceLogger">
<level value="trace" /> <!-- Set level to trace to activate tracing -->
<appender-ref ref="traceLog" />
</logger>
<logger name="org.springframework.ws.server.endpoint.interceptor">
<level value="DEBUG" />
<appender-ref ref="payloadAppender" />
</logger>
<root>
<level value="error" />
<appender-ref ref="errorLog" />
</root>
</log4j:configuration>
If I replace the root with another logger, then nothing gets logged at all to the specified appender.
<logger name="com.mydomain.logic">
<level value="error" />
<appender-ref ref="errorLog" />
</logger>
The root logger resides at the top of the logger hierarchy. It is exceptional in three ways:
it always exists,
its level cannot be set to null
it cannot be retrieved by name.
The rootLogger is the father of all appenders. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy (including rootLogger)
For example, if the console appender is added to the root logger, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, say L, then enabled logging requests for L and L's children will print on a file and on the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag to false.
From the log4j manual
To sum up:
If you want not to propagate a logging event to the parents loggers (say rootLogger) then add the additivity flag to false in those loggers. In your case:
<logger name="org.springframework.ws.server.endpoint.interceptor"
additivity="false">
<level value="DEBUG" />
<appender-ref ref="payloadAppender" />
</logger>
In standard log4j config style (which I prefer to XML):
log4j.logger.org.springframework.ws.server.endpoint.interceptor = INFO, payloadAppender
log4j.additivity.org.springframework.ws.server.endpoint.interceptor = false
Hope this helps.
Run your program with -Dlog4j.debug so that standard out gets info about how log4j is configured -- I suspected that it isn't configured the way that you think it is.
To add on to what James A. N. Stauffer and cynicalman said - I would bet that there is another log4j.xml / log4j.properties on your classpath other than the one you wish to be used that is causing log4j to configure itself the way it is.
-Dlog4j.debug is an absolute killer way to troubleshoot any log4j issues.
Two things: Check additivity and decide whether you want log events captured by more detailed levels of logging to propagate to the root logger.
Secondly, check the level for the root logger. In addition you can also add filtering on the appender itself, but this should normally not be necessary.
If you are using a log4j.properties file, this file is typically expected to be in the root of your classpath, so make sure it's there.
This is correct behavior. The root logger is like the default behavior. So if you don't specify any logger it will take root logger level as the default level but this does not mean that root logger level is the level for all your logs.
Any of your code which logs using 'TraceLogger'logger or 'org.springframework.ws.server.endpoint.interceptor' logger will log messages using TRACE and DEBUG level respectively any other code will use root logger to log message using level, which is in your case ERROR.
So if you use logger other than root, root log level will be overridden by that logger's log level. To get the desired output change the other two log level to ERROR.
I hope this is helpful.