How to make isInfoEnabled disabled in Log4J XML configuration - java

I have various log files (debug, error) and different configurations (e.g. dev, prod). In dev I'd like to have everything logged into my debug.log and errors written to error.log. However in production I'd like to switch the debug logging off. Right now I'm using this config:
<appender name="FileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/logs/debug.log" />
<param name="Append" value="true" />
<param name="Threshold" value="OFF" />
...
So it will decide whether to write or not itself. But I'd like to check in the code sometimes, if the logger writes to log:
if(logger.isInfoEnabled()) {};
Even the threshold is set to 'OFF' it does says, that info is enabled.
What I'm trying to do is to configure the XML, so it would not only skip writing to the debug.log in the production, but also it would set the infoEnabled value to false, so I could use it in my code. Is there are any possibilities to do that?
Thanks in advance!

Configure your ROOT logger to 'WARN' level. In Log4J 1.x:
<root>
<level value="WARN" />
</root>
In Log4J 2.x:
<root level="WARN">
</root>

Related

How to set size and amount of log files (stdout, stderr) in tomcat?

I recently deployed a java app on my production server. In which I have installed Tomcat version 8.5 and I have been having problems since the log files stderr and stdout grow in size exaggeratedly and therefore I lower the performance of the server or sometimes it is necessary to restart it since it does not respond. I would like to know how to configure these files so that they create only a certain amount with a specific size. I have tried configuring it through log4j it has given me error when integrating this same a tomcat. I have also configured certain parameters (for example: java.util.logging.FileHandler.limit = 1024) for logging in which the size and quantity are assigned but these do not apply to the configuration and therefore I continue to throw the server .
In a production environment, a good practice is to use a process that works with small log files, and that creates a new one if the critical size has gone.
With log4j you can use a RollingFileAppender. See the minimal configuration :
<appender name="rolling.file.appender" class="org.apache.log4j.RollingFileAppender">
<param name="maxFileSize" value="50MB" />
<param name="maxBackupIndex" value="10" />
<param name="file" value="${catalina.base}/logs/myApplication.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<!-- Root Logger -->
<root>
<priority value="INFO" />
<appender-ref ref="rolling.file.appender" />
</root>
Documentation: https://tomcat.apache.org/tomcat-8.0-doc/logging.html

Log4j log append to file name dependent on day - config

I'm fairly new to log4j and I would like to set up automatic logging of anything output to the console, like errors, or info messages for a web app running on my local server.
How would I set up my xml and/or properties file to do this? What I really am looking for is that each day a new log file be created in a directory (Ex: /mylogs/app-log-01-08-2014.log)
I've begun like this:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- general application log -->
<appender name="BarLogFile" class="org.apache.log4j.FileAppender">
<param name="File" value="my-changing-file-name.log" /> ->>> how does this change
<param name="Threshold" value="INFO" /> ->>> should INFO be Console here?
</appender>
<logger name="what-goes-here?">
<appender-ref ref="something-here"/>
</logger>
<root>
<level value="INFO"/>
</root>
Also, where in a web project does the xml file go? WEB-INF?
Any help is appreciated.
You are looking for what is known as "daily rolling log files", configuration is shown here. As for the web project, see this answer.
On a side node, you might want to learn about Logback as alternative.

How to make 2 or more java project write in a single log file

I am using log4j to write all the logs in a file.
i have 2 different java projects say proj1 and proj2, where project1 is required project for proj2. I have added proj1 as a dependency for proj2.
proj1 has log4j setup done and is working fine.
Now my problem is when I am running a method in proj2, it will call proj1 as well.
So I want to have a single logfile for both the projects.
Any input please?
There are several ways to write to a single log file but which way is best depends on a couple of details which you omit.
If proj2 includes proj1 as a library, you can make it use proj1's log4j configuration file. This works because you only have a single VM. The most simple solution here is to either copy the first project's config into the other or not give the second project any log config; it will then read the config from its dependencies.
If proj2 starts proj1 as an external process, you need to configure both projects to use a SocketAppender since only a single Java VM can ever write to a single log file.
Related:
log4j: How to use SocketAppender?
I was also facing the same problem but i got the solution and
have configured my log4j.xml like this:
used a appender:
<appender name="FILE1" class="org.apache.log4j.RollingFileAppender">
<errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler" />
<param name="File" value="E:/OESController.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="20KB" />
<param name="MaxBackupIndex" value="2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %d{dd MMM yyyy HH:mm:ss.SSS} %-5l - %m%n%n" />
</layout>
</appender>
<!-- Root Logger -->
<root>
<priority value="error" />
<appender-ref ref="FILE" />
</root>
Note:*Root logger logs for entire application.*
let me know if you still face the problem.

How to configure log4j to enable/disable logging to a file?

I've written up a small console utility. Throughout the application, I have used slf4j/log4j to log debug, trace, info statements to the console as I was developing it. Now that I am done development and want to release it, I would like to disable all output to the console except for a couple of specific loggers and send all the remaining loggers to a text file.
In theory, this should be fairly easy. I have created 2 appenders (one ConsoleAppender and one FileAppender). I have assocaited the ConsoleAppender with the specific loggers want on the Console and the FileAppender at the Root level. This works fine.
My issue now, is if I want to completely disable the FileAppender, I cannot figure out how to do it. If I add a DenyAllFilter to the FileAppender, it will prevent anything from being written to the file, but the file is still created. If I remove the FileAppender from the ROOT logger, I get Log4J writting to StdErr:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
If I set the ROOT level to OFF, the individual loggers that I have set custom debug levels to still output.
If I set the LoggerRepository Level to OFF, then all loggers (those I want to go to STDOUT and the File) are all shut off.
Is there any way to do this easily? Ideally, I want to be able to disable the file appender altogether, however provide a command line switch to enable it if desired.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
<!-- <param name="ConversionPattern" value="%m%n" /> -->
</layout>
</appender>
<appender name="LOGTXT" class="org.apache.log4j.FileAppender">
<param name="file" value="lss-client.log" />
<param name="append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n" />
</layout>
<!-- <filter class="org.apache.log4j.varia.DenyAllFilter"/> -->
</appender>
<!-- Spring Loggers -->
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.sent">
<level value="TRACE" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.received">
<level value="TRACE" />
</logger>
<logger name="com.cws.cs.Client" >
<level value="INFO" />
<appender-ref ref="STDOUT" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="LOGTXT" />
</root>
</log4j:configuration>
Thanks!
Eric
Pretty sure Slf4J/Log4J creates the log file immediately when you configure a FileAppender.
I think your best bet here is to have 2 different and complete Log4J configurations and pick which one you load at startup based on your command line parameter.
In PseudoCode:
public static void main(String[] args){
//if log to file arg = true
DOMConfigurator.configure("logToFile.log4j.xml");
//else
DOMConfigurator.configure("logToConsoleOnly.log4j.xml");
}
Edit
Furthermore, if you don't like the idea of maintaining two configuration files. You could create one configuration with the common components (probably the spring stuff and w/e else) and then based on your parameter, programatically configure the FileAppender:
public static void main(String[] args){
DOMConfigurator.configure("log4j.xml");
//if log to file arg = true{
// Define layout
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d{ISO8601} %-5p %c{5} - %X{messageId} - %m%n");
// Create appender
FileAppender appender = new FileAppender();
appender.setFile("lss-client.log");
appender.setLayout(layout);
appender.activateOptions();
// Get root logger and add appender.
log = Logger.getRootLogger();
log.setLevel(Level.INFO);
log.addAppender(appender);
}
}

Using log4j to send email reports via the SMTPAppender

I'm trying to use log4j to send emailable reports that contain the logging statements from a background process. I want one email sent for each process run, not one email for each logging statement. I've looked at the SMTPAppender, but don't see a way to manually send the report when the process completes. I believe the TriggeringEventEvaluator may be the key, but one issue I'm running into is how to get a handle to the TriggeringEventEvaluator instance. I'm stuck using log4j 1.2.14 and the SMTPAppender.getEvaluator() method was introduced in 1.2.15. Any thoughts? Am I even on the right track? Does the SMTPAppender.close() method come into play here?
I want to be able to do this:
log.info(message1);
log.info(message2);
log.info(message3);
log.sendMail();
After thinking about this some more, I think I need to clarify what I'm hoping to accomplish. I'm trying to capture the logging from running a quartz job and send the resulting log as an email. The quartz job makes a bunch of service method calls into various services. I want the to include any logging those service methods perform as well as the logging of the quartz jobs itself. I was thinking I could do something like the following for capturing all the logging, but it isn't working.
// at the beginning of quartz job
Logger logger = Logger.getRootLogger();
StringWriter sw = new StringWriter();
WriterAppender wa = new WriterAppender(new SimpleLayout(), sw);
logger.addAppender(wa);
// at the end of the quartz job
String report = sw.toString();
You shouldn't use any of log4j's methods, you should configure it properly instead.
First of all, define in your log4j.properties file your appender properly:
#CONFIGURE SMTP
log4j.appender.email=org.apache.log4j.net.SMTPAppender
log4j.appender.email.SMTPHost=mail.mydomain.com
log4j.appender.email.SMTPUsername=myuser#mydomain.com
log4j.appender.email.SMTPPassword=mypw
log4j.appender.email.From=myuser#mydomain.com
log4j.appender.email.To=myuser#mydomain.com
log4j.appender.email.Subject=Log of messages
log4j.appender.email.BufferSize=1
log4j.appender.email.EvaluatorClass=TriggerLogEvent
log4j.appender.email.layout=org.apache.log4j.PatternLayout
log4j.appender.email.layout.ConversionPattern=%m
Note: code taken from this post. More information can be obtained in SMTPAppender API.
Next, make a special class that will be used just for sending email. Example:
package com.foo.mailer;
import org.apache.log4j.Logger;
public class Mailer {
private static final Logger logger = Logger.getLogger(Mailer.class);
public void logMail(String mailString) {
logger.info(mailString);
}
}
Next, put in log4j.properties configuration for this class:
# INFO level will be logged
log4j.logger.com.foo.mailer = INFO, email
# turn off additivity
log4j.additivity.com.foo.mailer = false
Now, whenever you want to send an email using log4j, put this in your code:
new Mailer().logMail("This mail should be sent");
Disclaimer: I haven't tested any of this code.
If you are using an XML configuration file, the following should be helpful.
<appender name="ErrorEmailAppender" class="org.apache.log4j.net.SMTPAppender">
<param name="SMTPHost" value="mail.mydomain.com" />
<param name="SMTPUsername" value="myuser#mydomain.com" />
<param name="SMTPPassword" value="password" />
<param name="From" value="myuser#mydomain.com" />
<param name="To" value="myuser#mydomain.com" />
<param name="Subject" value="Log of messages" />
<param name="BufferSize" value="1" />
<param name="EvaluatorClass" value="TriggerLogEvent" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %m%n"/>
</layout>
</appender>
<logger name="com.foo.mailer">
<level value="INFO" />
<appender-ref ref="ErrorEmailAppender"/>
</logger>
Log4j 2.x onwards, the following configuration for log4j.xml can be used. It's pretty straightforward and can be used to send emails.
You need to edit it and enter your smtp host, username, password, port and subject.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<SMTP>
<name>Mail1</name>
<subject>SUBJECT</subject>
<to>TO_EMAIL</to>
<from>FROM_EMAIL</from>
<smtpHost>smtp.gmail.com</smtpHost>
<smtpPort>487</smtpPort>
<ignoreExceptions>false</ignoreExceptions>
<smtpUsername>username</smtpUsername>
<smtpPassword>password</smtpPassword>
<smtpProtocol>smtps</smtpProtocol>
<HtmlLayout charset="UTF-8" locationInfo="true" />
<ThresholdFilter level="ERROR"/>
</SMTP>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Mail1"/>
</Root>
</Loggers>
</Configuration>
Reference: Log4j SMTP Appender

Categories

Resources