I want to NLog to ignore certain messages using filters.
from my log file -
2020-07-15 13:18:53.3291 ERROR MyAppName:MyAppName Some other error
2020-07-15 13:18:53.3291 ERROR MyAppName:MyAppName.BusinessLogic.Notification.ProcessorControl Unknown : Unable to connect for notification control.
2020-07-15 13:18:53.3291 ERROR MyAppName:MyAppName.BusinessLogic.Notification.ProcessorControl Exception Occurred in Unknown : AggregateException One or more errors occurred.
2020-07-15 13:18:53.3291 ERROR MyAppName:MyAppName Some other error
from Nlog.config file -
<target xsi:type="File"
name="file"
fileName="${var:basedir}/Logs/MyAppName-${shortdate}.log"
layout="${longdate} [${event-context:item=CC} ${event-context:item=Workstation} ${event-context:item=User} ${event-context:item=IL}] ${level:uppercase=true} ${logger} ${message} ${onexception: ${exception:format=shortType,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" >
</target>
...
<logger name="MyAppName:*" minlevel="Error" writeTo="file" >
<filters>
<when condition="contains('${message}','MyAppName.BusinessLogic.Notification')" action="Ignore" />
<!--<when condition="contains('${message}','*MyAppName.BusinessLogic.Notification*')" action="Ignore" />-->
</filters>
</logger>
I added filter to ignore any messages that may contain the string
"MyAppName.BusinessLogic.Notification" but it's not working.
I also tried with *MyAppName.BusinessLogic.Notification* as in the commented line - but my log file is still filled with these messages.
Can anyone please guide how can I fix this?
One more question -
Doesn't $message represents complete error message, like this from log file -
MyAppName:MyAppName.BusinessLogic.Notification.ProcessorControl Unknown : Unable to connect for notification control.
Thank you!
"MyAppName.BusinessLogic.Notification" is probably not in your ${message}, but it's your logger name (${logger})
${message}
When writing a log event, here are some example of ${message}
logger.Info("My message"); - ${message} yields "My message"
logger.Info("Order {0}", 123); - ${message} yields "Order 123"
logger.Info("Order {OrderId}", 123); - ${message} yields "Order 123". Structured style, read more here. In this case you have also ${event-properties:OrderId} which yields 123.
Note: when using the ASP.NET Core integration , read logger.LogInformation instead of logger.Info
${logger}
The logger name, examples:
LogManager.GetLogger("logger1"); - ${logger} yields "logger1"
LogManager.GetCurrentClassLogger(); - ${logger} yields something like "MyClassNamespace.MyClass"
Injected ILogger<MyClass> - ${logger} yields something like "MyClassNamespace.MyClass" - this in case you're using the ASP.NET Core integration.
Filtering
It's easy to filter on the logger name, it's built into the <logger> rule. The name attribute should be read as "filter on name" - * and ? wildcards are supported.
Example:
<rules>
<logger name="MyAppName.BusinessLogic.*" minlevel="Error" writeTo="ErrorWithBusinessLogicStuffTarget" />
Read more here
Notes
When filtering the final attribute could be handy. For all options, see here
You could also use the <when> to filter with the ${logger}, but that's harder to maintain and less performant.
You are writing a rule so you have to wrap it around the <rules></rules> tag. and also use name="*" in place of name="MyAppName:*".
Try the code below;
<rules>
<logger name="*" minlevel="Error" writeTo="file" >
<filters>
<when condition="contains('${message}','MyAppName.BusinessLogic.Notification')" action="Ignore" />
<!--<when condition="contains('${message}','*MyAppName.BusinessLogic.Notification*')" action="Ignore" />-->
</filters>
</logger>
</rules>
I have searched far and wide for my solution (including relevant stackoverflow questions) but have yet to find an answer that fixes my issue. I have been using log4net successfully in a work project and when I run the program in visual studio I get my log file. If I install the program using the msi installer (wix) then I do NOT get a log file. I'll first list things I've tried, followed by an edited version of my code.
Also, anywhere I say "appname" I did not actually put appname, just keeping project name out of post.
I'm placing the log file in ${USERPROFILE}\AppData\Local[appname] directory, permissions are not an issue.
Since the config file that is present in the installed version is appname.exe.config instead of app.config, I changed the Assemblyinfo.cs assembly statement to appname.exe.config. This however did not solve my issue, it still only works while running through visual studio, an installed version does not.
I have modified product.wxs to deliver log4net.dll and log4net.xml to the install directory. (forgot to do this, app would not start so came back and added it in) still no change.
We have 5 projects within a single solution using log4net. all of the assemblyinfo.cs files have the following:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "appname.exe.config", Watch = true)]
I was using [assembly: log4net.Config.XmlConfigurator(ConfigFile = "app.config", Watch = true)] but changed this to the modified config file name that is placed in the install dir and the bin.
Inside of app.config(excuse any possible typos, my dev machine is airgapped and I cannot copy paste the code):
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="MyAppender"/>
</root>
<appender name="MyAppender" type="log4net.Appender.FileAppender">
<file value="${USERPROFILE}\AppData\Local\appname\appname.log"/>
<appendToFile value="true"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level - %message%newline"/>
</layout>
</appender>
</log4net>
</configuration>
and in my c# code where I use the logger:
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
If your configuration is in your app.config, you can just use:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
When you specify a file, log4net expect the log4net element as xml root element. Which is not true for your app.config.
#erike i'm not sure it was mine. So I do not have an link for you.
My NLog targets is like this:
<targets>
<target xsi:type="Console" name="console"
layout="${longdate}|${level}|${message}" />
<target xsi:type="File" name="ErrorLog" fileName="${basedir}/error.txt"
layout="${longdate}
Trace: ${stacktrace}
${message}" />
<target xsi:type="File" name="AccessLog" fileName="${basedir}/access.txt"
layout="${shortdate} | ${message}" />
</targets>
But this causes problems if the user isn't an admin on their machine, because they will not have write access to "Program Files". How can I get something like %AppData% to NLog instead of BaseDir?
You're looking for the NLog special folders.
Example:
...fileName="${specialfolder:folder=ApplicationData}/Program/file.txt"...
Oren's answer should be the right answer. However, for the life of me I couldn't get it to work with my .NET 4.0 website using nLog 2.0.0.0. I ended up using simply
fileName="${basedir}app_data\logs\${shortdate}.log"
${specialfolder:ApplicationData} also works
The previous answers helped solve the problem I was having, but a couple of years later and the solution is now somewhat different under v4.3. The directory and filename are combined with the path.
#theGecko's link is still current for the syntax, but the page is deficient of an example:
https://github.com/nlog/NLog/wiki/Special-Folder-Layout-Renderer
The following example would write the file myLog.log to the current users application data roaming directory C:\USers\current.user\AppData\Roaming\My\Path\Somewhere:
fileName="${specialfolder:dir=My/Path/Somewhere/:file=myFile.log:folder=ApplicationData}"
For logging to the project directory:
While the previous answers work for the original question, searching for how to log to the project APP_DATA directory leads to this question. And while bkaid's answer works for ASP.NET and for using the APP_DATA folder specifically, for .NET Core and .NET 5 the solution is a bit different, because that motif has been abandoned in favor of defining a wwwroot folder for only those things which should be served, and the remainder being private. The answer for .NET Core/5, then, is to write to the solution root directory:
First, ensure the NLog.Web.AspNetCore assembly is added to nlog.config:
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
Then use one of the layout renderers provided by that extension, in this case ${aspnet-appbasepath} which references the solution root directory:
<targets>
<target name="file"
type="File"
xsi:type="File"
fileName="${aspnet-appbasepath}/log/${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}"/>
</targets>
This will write the file to <solution folder>/log/2021-07-01.log, which will never be served by the public-facing website. Other layout renderers provided by this assembly are listed on the NLog website.
After adding log4j to my application I get the following output every time I execute my application:
log4j:WARN No appenders could be found for logger (slideselector.facedata.FaceDataParser).
log4j:WARN Please initialize the log4j system properly.
It seems this means a configuration file is missing.
Where should this config file be located and what is a good start content?
I'm using plain java for developing a desktop application. So no webserver etc...
Log4j by default looks for a file called log4j.properties or log4j.xml on the classpath.
You can control which file it uses to initialize itself by setting system properties as described here (Look for the "Default Initialization Procedure" section).
For example:
java -Dlog4j.configuration=customName ....
Will cause log4j to look for a file called customName on the classpath.
If you are having problems I find it helpful to turn on the log4j.debug:
-Dlog4j.debug
It will print to System.out lots of helpful information about which file it used to initialize itself, which loggers / appenders got configured and how etc.
The configuration file can be a java properties file or an xml file. Here is a sample of the properties file format taken from the log4j intro documentation page:
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
While setting up log4j properly is great for "real" projects you might want a quick-and-dirty solution, e.g. if you're just testing a new library.
If so a call to the static method
org.apache.log4j.BasicConfigurator.configure();
will setup basic logging to the console, and the error messages will be gone.
If you just get rid of everything (e.g. if you are in tests)
org.apache.log4j.BasicConfigurator.configure(new NullAppender());
As per Apache Log4j FAQ page:
Why do I see a warning about "No appenders found for logger" and "Please configure log4j properly"?
This occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration. log4j uses Thread.getContextClassLoader().getResource() to locate the default configuration files and does not directly check the file system. Knowing the appropriate location to place log4j.properties or log4j.xml requires understanding the search strategy of the class loader in use. log4j does not provide a default configuration since output to the console or to the file system may be prohibited in some environments.
Basically the warning No appenders could be found for logger means that you're using log4j logging system, but you haven't added any Appenders (such as FileAppender, ConsoleAppender, SocketAppender, SyslogAppender, etc.) into your configuration file or the configuration file is missing.
There are three ways to configure log4j: with a properties file (log4j.properties), with an XML file and through Java code (rootLogger.addAppender(new NullAppender());).
log4j.properties
If you've property file present (e.g. when installing Solr), you need to place this file within your classpath directory.
classpath
Here are some command suggestions in Linux how to determine your classpath value:
$ echo $CLASSPATH
$ ps wuax | grep -i classpath
$ grep -Ri classpath /etc/tomcat? /var/lib/tomcat?/conf /usr/share/tomcat?
or from Java: System.getProperty("java.class.path").
Log4j XML
Below is a basic XML configuration file for log4j in XML format:
<?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="%-5p %c{1} - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Tomcat
If you're using Tomcat, you may place your log4j.properties into: /usr/share/tomcat?/lib/ or /var/lib/tomcat?/webapps/*/WEB-INF/lib/ folder.
Solr
For the reference, Solr default log4j.properties file looks like:
# Logging level
solr.log=logs/
log4j.rootLogger=INFO, file, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x \u2013 %m%n
#- size rotation with log cleanup.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.MaxFileSize=4MB
log4j.appender.file.MaxBackupIndex=9
#- File to log to and log format
log4j.appender.file.File=${solr.log}/solr.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; %C; %m\n
log4j.logger.org.apache.zookeeper=WARN
log4j.logger.org.apache.hadoop=WARN
# set to INFO to enable infostream log messages
log4j.logger.org.apache.solr.update.LoggingInfoStream=OFF
Why can't log4j find my properties file in a J2EE or WAR application?
The short answer: the log4j classes and the properties file are not within the scope of the same classloader.
Log4j only uses the default Class.forName() mechanism for loading classes. Resources are handled similarly. See the documentation for java.lang.ClassLoader for more details.
So, if you're having problems, try loading the class or resource yourself. If you can't find it, neither will log4j. ;)
See also:
Short introduction to log4j at Apache site
Apache: Logging Services: FAQ at Apache site
Find a log4j.properties or log4j.xml online that has a root appender, and put it on your classpath.
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.rootLogger=debug, stdout
will log to the console. I prefer logging to a file so you can investigate afterwards.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.maxFileSize=100KB
log4j.appender.file.maxBackupIndex=5
log4j.appender.file.File=test.log
log4j.appender.file.threshold=debug
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=debug,file
although for verbose logging applications 100KB usually needs to be increased to 1MB or 10MB, especially for debug.
Personally I set up multiple loggers, and set the root logger to warn or error level instead of debug.
You can set the location of your log4j.properties from inside your java app by using:
org.apache.log4j.PropertyConfigurator.configure(file/location/log4j.properties)
More information is available here: https://logging.apache.org/log4j/1.2/manual.html
Another way to do it without putting the property file on the classpath, is to set the property from the java code directly. Here is the sample code.
public class Log4JSample {
public static void main(String[] args) {
Properties properties=new Properties();
properties.setProperty("log4j.rootLogger","TRACE,stdout,MyFile");
properties.setProperty("log4j.rootCategory","TRACE");
properties.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender");
properties.setProperty("log4j.appender.stdout.layout", "org.apache.log4j.PatternLayout");
properties.setProperty("log4j.appender.stdout.layout.ConversionPattern","%d{yyyy/MM/dd HH:mm:ss.SSS} [%5p] %t (%F) - %m%n");
properties.setProperty("log4j.appender.MyFile", "org.apache.log4j.RollingFileAppender");
properties.setProperty("log4j.appender.MyFile.File", "my_example.log");
properties.setProperty("log4j.appender.MyFile.MaxFileSize", "100KB");
properties.setProperty("log4j.appender.MyFile.MaxBackupIndex", "1");
properties.setProperty("log4j.appender.MyFile.layout", "org.apache.log4j.PatternLayout");
properties.setProperty("log4j.appender.MyFile.layout.ConversionPattern","%d{yyyy/MM/dd HH:mm:ss.SSS} [%5p] %t (%F) - %m%n");
PropertyConfigurator.configure(properties);
Logger logger = Logger.getLogger("MyFile");
logger.fatal("This is a FATAL message.");
logger.error("This is an ERROR message.");
logger.warn("This is a WARN message.");
logger.info("This is an INFO message.");
logger.debug("This is a DEBUG message.");
logger.trace("This is a TRACE message.");
}
}
import org.apache.log4j.BasicConfigurator;
Call this method
BasicConfigurator.configure();
You can set up the log level by using setLevel().
The levels are useful to easily set the kind of informations you want the program to display.
For example:
Logger.getRootLogger().setLevel(Level.WARN); //will not show debug messages
The set of possible levels are:
TRACE,
DEBUG,
INFO,
WARN,
ERROR and
FATAL
According to Logging Services manual
To enable -Dlog4j.debug, I go to System, Advanced system settings, Environment variables and set system variable _JAVA_OPTIONS to -Dlog4j.debug.
What are you developing in? Are you using Apache Tomcat?
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyyMMdd HH:mm:ss.SSS} [[%5p] %c{1} [%t]] %m%n
I have a properties like this in a Java app of mine.
I've created file log4j.properties in resources folder next to hibernate.cfg.xml file and filled it with text below:
log4j.rootLogger=INFO, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}:%L] %m%n
now I got rid of warnings and errors
Simply, create log4j.properties under src/main/assembly folder. Depending on if you want log messages to be shown in the console or in the file you modify your file. The following is going to show your messages in the console.
# Root logger option
log4j.rootLogger=INFO, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
My log4j got fixed by below property file:
## direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.rootLogger=debug, stdout
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.maxFileSize=100KB
log4j.appender.file.maxBackupIndex=5
log4j.appender.file.File=./logs/test.log
log4j.appender.file.threshold=debug
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=debug,file
As explained earlier there are 2 approaches
First one is to just add this line to your main method:
BasicConfigurator.configure();
Second approach is to add this standard log4j.properties file to your classpath:
While taking second approach you need to make sure you initialize the file properly.
Eg.
Properties props = new Properties();
props.load(new FileInputStream("log4j property file path"));
props.setProperty("log4j.appender.File.File", "Folder where you want to store log files/" + "File Name");
Make sure you create required folder to store log files.
Try to set debug attribut in log4j:configuration node to true.
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
It prints out information as the configuration file is read and used to configure the log4j environment. You may be got more details to resolve your problem.
Logging API - The Java Logging API facilitates software servicing and maintenance at customer sites by producing log reports suitable for analysis by end users, system administrators, field service engineers, and software development teams. The Logging APIs capture information such as security failures, configuration errors, performance bottlenecks, and/or bugs in the application or platform. The core package includes support for delivering plain text or XML formatted log records to memory, output streams, consoles, files, and sockets. In addition, the logging APIs are capable of interacting with logging services that already exist on the host operating system.
Package java.util.logging « Provides the classes and interfaces of the Java platform's core logging facilities.
Log4j 1.x « log4j is a popular Java-based logging utility. Log4j is an open source project based on the work of many authors. It allows the developer to control which log statements are output to a variety of locations by using Appenders [console, files, DB and email]. It is fully configurable at runtime using external configuration files.
Log4j has three main components:
Loggers - [OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE]
Appenders
Apache Commons Logging: ConsoleAppender, FileAppender, RollingFileAppender, DailyRollingFileAppender, JDBCAppender-Driver, SocketAppender
Log4J Appender for MongoDB: MongoDbAppender - Driver
Layouts - [PatternLayout, EnhancedPatternLayout]
Configuration files can be written in XML or in Java properties (key=value) format.
log4j_External.properties « Java properties (key=value) format
The string between an opening "${" and closing "}" is interpreted as a key. The value of the substituted variable can be defined as a system property or in the configuration file itself.
Set appender specific options. « log4j.appender.appenderName.option=value, For each named appender you can configure its Layout.
log4j.rootLogger=INFO, FILE, FILE_PER_SIZE, FILE_PER_DAY, CONSOLE, MySql
#log.path=./
log.path=E:/Logs
# https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html
# {%-5p - [WARN ,INFO ,ERROR], %5p 0- [ WARN, INFO,ERROR]}
log.patternLayout=org.apache.log4j.PatternLayout
log.pattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n
# System.out | System.err
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.err
log4j.appender.CONSOLE.layout=${log.patternLayout}
log4j.appender.CONSOLE.layout.ConversionPattern=${log.pattern}
# File Appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log.path}/logFile.log
#log4j:ERROR setFile(null,false) call failed. - Defaults setFile(null,true)
#log4j.appender.FILE.Append = false
log4j.appender.FILE.layout=${log.patternLayout}
log4j.appender.FILE.layout.ConversionPattern=${log.pattern}
# BackUP files for every Day.
log4j.appender.FILE_PER_DAY=org.apache.log4j.DailyRollingFileAppender
# [[ Current File ] - logRollingDayFile.log ], { [BackUPs] logRollingDayFile.log_2017-12-10, ... }
log4j.appender.FILE_PER_DAY.File=${log.path}/logRollingDayFile.log
log4j.appender.FILE_PER_DAY.DatePattern='_'yyyy-MM-dd
log4j.appender.FILE_PER_DAY.layout=${log.patternLayout}
log4j.appender.FILE_PER_DAY.layout.ConversionPattern=${log.pattern}
# BackUP files for size rotation with log cleanup.
log4j.appender.FILE_PER_SIZE=org.apache.log4j.RollingFileAppender
# [[ Current File ] - logRollingFile.log ], { [BackUPs] logRollingFile.log.1, logRollingFile.log.2}
log4j.appender.FILE_PER_SIZE.File=${log.path}/logRollingFile.log
log4j.appender.FILE_PER_SIZE.MaxFileSize=100KB
log4j.appender.FILE_PER_SIZE.MaxBackupIndex=2
log4j.appender.FILE_PER_SIZE.layout=${log.patternLayout}
log4j.appender.FILE_PER_SIZE.layout.ConversionPattern=${log.pattern}
# MySql Database - JDBCAppender
log4j.appender.MySql=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.MySql.driver=com.mysql.jdbc.Driver
log4j.appender.MySql.URL=jdbc:mysql://localhost:3306/automationlab
log4j.appender.MySql.user=root
log4j.appender.MySql.password=
log4j.appender.MySql.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.MySql.layout.ConversionPattern=INSERT INTO `logdata` VALUES ('%p', '%d{yyyy-MM-dd HH:mm:ss}', '%C', '%M', '%L', '%m');
#log4j.appender.MySql.sql=INSERT INTO `logdata` VALUES ('%p', '%d{yyyy-MM-dd HH:mm:ss}', '%C', '%M', '%L', '%m');
# Direct log events[Messages] to MongoDB Collection - MongoDbAppender
log.mongoDB.hostname=loalhost
log.mongoDB.userName=Yash777
log.mongoDB.password=Yash#123
log.mongoDB.DB=MyLogDB
log.mongoDB.Collection=Logs
log4j.appender.MongoDB=org.log4mongo.MongoDbAppender
log4j.appender.MongoDB.hostname=${log.mongoDB.hostname}
log4j.appender.MongoDB.userName=${log.mongoDB.userName}
log4j.appender.MongoDB.password=${log.mongoDB.password}
log4j.appender.MongoDB.port=27017
log4j.appender.MongoDB.databaseName=${log.mongoDB.DB}
log4j.appender.MongoDB.collectionName=${log.mongoDB.Collection}
log4j.appender.MongoDB.writeConcern=FSYNCED
MySQL Table structure for table logdata
CREATE TABLE IF NOT EXISTS `logdata` (
`Logger_Level` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`DataTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`ClassName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
`MethodName` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`LineNumber` int(10) NOT NULL,
`Message` text COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
log4j_External.xml « XML log4j:configuration with public DTD file
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE log4j:configuration PUBLIC
"-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration debug="false">
<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="%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n" />
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.FileAppender">
<param name="file" value="E:/Logs/logFile.log" />
<param name="append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n" />
</layout>
</appender>
<appender name="FILE_PER_SIZE" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="E:/Logs/logRollingFile.log" />
<param name="immediateFlush" value="true"/>
<param name="maxFileSize" value="100KB" />
<param name="maxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n" />
</layout>
</appender>
<appender name="FILE_PER_DAY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="E:/Logs/logRollingDayFile.log" />
<param name="datePattern" value="'_'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n"/>
</layout>
</appender>
<root>
<priority value="info" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
<appender-ref ref="FILE_PER_SIZE" />
<appender-ref ref="FILE_PER_DAY" />
</root>
</log4j:configuration>
Log4j Configuration from the URL in Java program:
In order to specify a custom configuration with an external file, the used class must implement the Configurator interface.
when default configuration files "log4j.properties", "log4j.xml" are not available
For "log4j.properties" you can fed to the PropertyConfigurator.configure(java.net.URL) method.
For "log4j.xml" DOMConfigurator will be used.
public class LogFiles {
// Define a static logger variable so that it references the Logger instance named "LogFiles".
static final Logger log = Logger.getLogger( LogFiles.class );
#SuppressWarnings("deprecation")
public static void main(String[] args) {
System.out.println("CONFIGURATION_FILE « "+LogManager.DEFAULT_CONFIGURATION_FILE);
System.out.println("DEFAULT_XML_CONFIGURATION_FILE = 'log4j.xml' « Default access modifier");
String fileName = //"";
//"log4j_External.xml";
"log4j_External.properties";
String configurationFile = System.getProperty("user.dir")+"/src/" + fileName;
if( fileName.contains(".xml") ) {
DOMConfigurator.configure( configurationFile );
log.info("Extension *.xml");
} else if ( fileName.contains(".properties") ) {
PropertyConfigurator.configure( configurationFile );
log.info("Extension *.properties");
} else {
DailyRollingFileAppender dailyRollingAppender = new DailyRollingFileAppender();
dailyRollingAppender.setFile("E:/Logs/logRollingDayFile.log");
dailyRollingAppender.setDatePattern("'_'yyyy-MM-dd");
PatternLayout layout = new PatternLayout();
layout.setConversionPattern( "%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS} %C{1}:%12.20M:%L - %m %n" );
dailyRollingAppender.setLayout(layout);
dailyRollingAppender.activateOptions();
Logger rootLogger = Logger.getRootLogger();
rootLogger.setLevel(Level.DEBUG);
rootLogger.addAppender(dailyRollingAppender);
log.info("Configuring from Java Class.");
}
log.info("Console.Message.");
method2();
methodException(0);
}
static void method2() {
log.info("method2 - Console.Message.");
}
static void methodException(int b) {
try {
int a = 10/b;
System.out.println("Result : "+ a);
log.info("Result : "+ a);
} catch (Exception ex) { // ArithmeticException: / by zero
log.error(String.format("\n\tException occurred: %s", stackTraceToString(ex)));
}
}
public static String stackTraceToString(Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
return sw.toString();
}
}
For testing, a quick-dirty way including setting log level:
org.apache.log4j.BasicConfigurator.configure();
org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.WARN);
// set to Level.DEBUG for full, or Level.OFF..
The fix for me was to put "log4j.properties" into the "src" folder.
If we are using apache commons logging wrapper on top of log4j, then we need to have both the jars available in classpath. Also, commons-logging.properties and log4j.properties/xml should be available in classpath.
We can also pass implementation class and log4j.properties name as JAVA_OPTS either using -Dorg.apache.commons.logging.Log=<logging implementation class name> -Dlog4j.configuration=<file:location of log4j.properties/xml file>. Same can be done via setting JAVA_OPTS in case of app/web server.
It will help to externalize properties which can be changed in deployment.
This is an alternative way using .yaml
Logic Structure:
Configuration:
Properties:
Appenders:
Loggers:
Sample:
Configutation:
name: Default
Properties:
Property:
name: log-path
value: "logs"
Appenders:
Console:
name: Console_Appender
target: SYSTEM_OUT
PatternLayout:
pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
File:
name: File_Appender
fileName: ${log-path}/logfile.log
PatternLayout:
pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
Loggers:
Root:
level: debug
AppenderRef:
- ref: Console_Appender
Logger:
- name: <package>.<subpackage>.<subsubpackage>.<...>
level: debug
AppenderRef:
- ref: File_Appender
level: error
Ref: LOG4J 2 CONFIGURATION: USING YAML
Maven solution:
I came across all the same issues as above, and for a maven solution I used 2 dependencies. This configuration is only meant for quick testing if you want a simple project to be using a logger, with a standard configuration. I can imagine you want to make a configuration file later on if you need more information and or finetune your own logging levels.
<properties>
<slf4jVersion>1.7.28</slf4jVersion>
</properties>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4jVersion}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>${slf4jVersion}</version>
</dependency>
I just did this and the issue was fixed.
Followed the below blog
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206875685-How-to-fix-log4j-WARN-console-messages-when-running-an-Application-inside-IntelliJ-Idea
But here he says like below
To fix that just enter the following log4j.resources file into main/resources folder of your project
instead of creating log4j.resources, create log4j.properties. Right Click on Resource in IntelliJ -> New -> Resource Bundle - Just name it as log4j
If you are having this error on Intellij IDEA even after adding the log4j.properties or log4j.xml file on your resources test folder, maybe the Intellij IDEA is not aware yet about the existence of the file.
So, after add the file, right click on the file and choose Recompile log4j.xml.