Original address: http://blog.csdn.net/lujinhong2/article/details/47662819
Java Log System slf4j A common example two other examples three considerations two log4j a use Java to send a log to Rsyslog basic usage does not use the configuration file three logging four uses SLF4JLOG4J2 to send log to rsyslog a Rsyslo G configuration 1 new stormconf in Etcrsyslogd 2 modify etcrsyslogconf two Java program output log 1 Add Dependency 2 prepare configuration file 3 output log
Java has a large number of frameworks for log output, common including slf4j, log4j, Logback, logging, and so on. First, slf4j
SLF4J is just a façade (facet), it does not contain the specific implementation, but the implementation of some log4j,java.logging and other implementations packaged into a unified interface.
Commons-logging and slf4j are both log interfaces for users to use without providing implementations.
Log4j,logback and so on is the real realization of the log.
When we call the interface, the factory of the interface automatically looks for the proper implementation and returns an instance of implementation to serve me. These processes are transparent and the user does not need to do anything.
Here's a little story, when Apache persuaded Log4j and other logs to be written according to Commons-logging's standards, but because of commons-logging class loading problems and implementation is not friendly, so log4j author created slf4j , and therefore with commons-logging two points world. It's up to the user to decide which to use.
In this way, SLF4J appears, it through a simple implementation can find the implementation of their own interface classes, if not to meet their own standard log, you can through some intermediate implementation such as the above Slf4j-log4j12.jar to fit.
Well, to be sure, how to use SLF4J. (i) Common examples
1, add the following content in the Pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactid>slf4j-api</artifactid >
<version>1.7.0</version>
</dependency>
<dependency>
<groupid >org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.0 </version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</ Dependency>
2, create Log4j.properties file, detailed configuration see http://www.cnblogs.com/lujinhong2/p/4637219.html
Note that the file must be in the Config directory (for the MAVEN project, Log4j.properties is under Src/main/resources)
### set log levels ### Log4j.rootlogger = Debug, stdout, D, E ### output to console ### Log4j.appender.stdout = Org.apache.log 4j. Consoleappender Log4j.appender.stdout.Target = System.out Log4j.appender.stdout.layout = Org.apache.log4j.PatternLayout Log4j.appender.stdout.layout.ConversionPattern =%d{absolute}%5p%c{1}:%l-%m%n ### output
To log file ### LOG4J.APPENDER.D = Org.apache.log4j.DailyRollingFileAppender Log4j.appender.d.file = Logs/log.log Log4j.appender.d.append = true # # Output debug-level log Log4j.appender.d.threshold = Debug Log4j.appender.d.layout = Org.apache . log4j. Patternlayout Log4j.appender.d.layout.conversionpattern =%-d{yyyy-mm-dd HH:mm:ss} [%t:%r]-[%p]%m%n ### Save exception information to single Single file ### log4j.appender.e = org.apache.log4j.DailyRollingFileAppender # # Exception Log file name Log4j.appender.e.file =./error.log Log4
J.appender.e.append = true # only logs above the error level are exported!!!
Log4j.appender.e.threshold = ERROR Log4j.appender.e.layout = org.apache.log4j.PatternLayout Log4j.appender.e.layout.conversionpattern =%-d{yyyy-mm-dd HH:MM:SS} [%l:%c:%t:%r]-[%p]%m%n
3. Calling in Java file
Package Org.lujinhong.javademo.slf4jdemo;
Import Java.io.File;
Import java.io.IOException;
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;
/** *
@author jinhong-lu
* @date July 9, 2015 afternoon 4:34:49
* @Description: * * Public
class Slf4jdemo { C10/>private static final Logger LOG = Loggerfactory.getlogger (slf4jdemo.class);
public static void Main (string[] args) {
//Use this variable to generate a file success
String fileName = "1.txt";
Using this variable will generate a file failure
//String fileName = "/tt/1.txt";
try {
new File (fileName). CreateNewFile ();
Log.info ("Create file" + FileName + "!");
} catch (IOException e) {
e.printstacktrace ();
Log.error ("Create file" + fileName + "fail!!!!" + e.getmessage ());}}
(b) Other examples
First, you must include Slf4j-api.jar in your project, and you should also include SLF4J adapters (such as Slf4j-log4j12.jar) that are provided for a specific implementation, as well as a jar package for that specific implementation, such as Log4j-1.**.jar.
Let's take the following code as an example:
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;
public class Slf4jdemo {
private static final Logger LOG = Loggerfactory.getlogger (Slf4jdemo.class);
public static void Main (string[] args) {
log.error ("Error message!");
Log.warn ("Warn message!");
Log.info ("info message!");
Log.debug ("Debug message!");
Log.trace ("Trace message!");
}
}
Because of the different implementations used, the log output also has different results. This also reflects the ease with which the journaling system can be replaced by using SLF4J.
1, Slf4j-simple
A simple implementation of the SLF4J, which can be used in small projects, but cannot be configured with log levels.
The description in the official document is: Binding for simple implementation, which outputs all events to System.err. Only messages of the level INFO and higher are printed. This binding may is useful in the context of small applications.
Add Slf4j-1.6.6.jar and Slf4j-simple-1.6.6.jar to the Build_path of the project.
The output results are as follows:
2 [main] ERROR slf4jdemo-error message!
2 [main] WARN Slf4jdemo-warn message!
2 [main] INFO Slf4jdemo-info message!
2, SLF4J-JDK
Using JKD's own log system, add Slf4j-1.6.6.jar and Slf4j-jdk14-1.6.6.jar to the Build_path of the project.
The output results are as follows:
February 16, 2015 11:09:36 pm Slf4jdemo main
serious: Error message!
February 16, 2015 11:09:36 pm Slf4jdemo main
Warning: Warn message!
February 16, 2015 11:09:36 pm Slf4jdemo main
Info: info message!
3, slf4j-log4j
Log4j is currently the most used log system, and it is more suitable for large projects.
Add Slf4j-1.6.6.jar and Slf4j-log4j-1.6.6.jar to the Build_path of the project, as well as log4j specific implementations, such as Log4j-1.2.16.jar.
The output results are as follows:
Log4j:warn No Appenders could is found for logger (Slf4jdemo).
Log4j:warn Please initialize the log4j system properly.
Log4j:warn http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
You can configure the level of output logs through a configuration file. (iii) Some matters for attention
1, note that Build_path can not have more than one log implementation, or it will cause slf4j do not know which implementation to use, resulting in the following error
Slf4j:class path contains multiple slf4j bindings.
Slf4j:found Binding in [Jar:file:/users/liaoliuqing/99_project/1_mycodes/5_javaeedemo/lib/slf4j-log4j12-1.6.6.jar !/org/slf4j/impl/staticloggerbinder.class]
slf4j:found binding in [jar:file:/users/liaoliuqing/99_project/1_ Mycodes/5_javaeedemo/lib/slf4j-jdk14-1.6.6.jar!/org/slf4j/impl/staticloggerbinder.class]
slf4j:see http:// Www.slf4j.org/codes.html#multiple_bindings for a explanation.
Slf4j:actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
Log4j:warn No appenders could being found for logger (Slf4jdemo).
Log4j:warn Please initialize the log4j system properly.
Log4j:warn http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
3, there is a big hole:
Because many projects use log4j as a log frame, log4j profiles in a reference package in one project may overwrite log4j.properties files that you define.
If you find that your log4j configuration file does not take effect, use:
Java-dlog4j.debug Main class
To check which configuration file is currently loaded and then delete it.
In addition, even if you use the
Propertyconfigurator.configure ("Log4j2.properties");
Specifies the configuration file, or it may be overwritten with the same statement by a third-party jar package. Second, log4j
LOG4J has 2 versions, 1.x and 2.x,2.x more perfect, but at present everyone is accustomed to using 1.x, and many open source projects are used 1.x, so the general use of 1.x can be.
For the use of 2.x, please refer to http://www.cnblogs.com/lujinhong2/p/4637295.html
1.x to pay attention to the version of the problem, the general use of 1.2.17 with SLFJ version of the 1.7.12, as long as the difference is not too much is not a problem. (i) using Java to send logs to Rsyslog basic methods of use
1, open rsyslog remote UDP access
Vi/etc/rsyslog.conf
Remove the # number in front of two paragraphs below
# $ModLoad IMUDP
# $UDPServerRun 514
If you don't have a word, add these 2 lines.
2, create the file address of log
Vi/etc/rsyslog.conf
Add the following two paragraphs
Local2.info /var/log/login_info.log
local2.debug /var/log/login_debug.log
3, open the firewall
Opening UDP port 514 to the outside
4, restart Rsyslog
Service Rsyslog Restart
Configuration of 5,log4j
Output logs to syslog and console at the same time
Log4j.rootlogger =all,systemout,syslog
log4j.appender.systemOut = Org.apache.log4j.ConsoleAppender
Log4j.appender.systemOut.layout = Org.apache.log4j.PatternLayout
Log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/mm/dd hh:mm:sss}][%l]%n%m%n
Log4j.appender.systemOut.Threshold = DEBUG
Log4j.appender.systemOut.ImmediateFlush = TRUE
Log4j.appender.systemOut.Target = System.out
log4j.appender.syslog=org.apache.log4j.net.syslogappender
log4j.appender.syslog.sysloghost=192.168.172.114
Log4j.appender.syslog.threshold=debug
Log4j.appender.syslog.layout=org.apache.log4j.patternlayout
log4j.appender.syslog.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n
log4j.appender.syslog.header=true
Log4j.appender.syslog.facility=local2
6, write Java code
Package com.lujinhong.demo.log4j;
Import Org.apache.log4j.Logger;
public class Log4jdemo {
private static Logger LOG = Logger.getlogger (Log4jdemo. Class);
public static void Main (string[] args) {
//system.setproperty ("LogDir", "/users/liaoliuqing/downloads/");
Log.info ("Lujinhong!!") INFO message!! ");
Log.error ("error message!!!!");
Log.debug ("Debug message!");
Log.warn ("Warn message!!");
New Myjavaclass (). Adder (2, 3);
}
}
7, run the application, you can see the different levels of log information under/var/log, such as Login_info.log and Login_debug.log do not use the configuration file
Sometimes, log4j's configuration files will cover each other, which is really annoying, so you can write the configuration to the code
1. Define a single instance class to write the related configuration to:
Package com.lujinhong.demo.log4j;
Import Org.apache.log4j.Level;
Import Org.apache.log4j.Logger;
Import Org.apache.log4j.PatternLayout;
Import Org.apache.log4j.net.SyslogAppender;
public class Mysyslogger {//log level private static levels = Level.info;
private static Logger LOG = null;
public static synchronized Logger getinstance () {if (LOG = = null) {new Mysyslogger ();
} return LOG;
Private Mysyslogger () {LOG = Logger.getrootlogger ();
Log.setlevel (level);
Syslogappender Appender = new Syslogappender ();
Appender.setname ("Ma30");
Appender.setsysloghost ("192.168.172.98");
Appender.setlayout (New Patternlayout ("%r [%t]%-5p%c%x:-%m%n"));
Appender.setheader (TRUE);
Appender.setfacility ("Local7");
Appender.setwriter (New PrintWriter (System.out)); If the file is Rollingfileappender:setwriter (new PrintWriter ("f:/test/_debug.log "));
Log.addappender (Appender);
}
}
2, add the following statement in the class that requires log output
private static Logger LOG = Mysyslogger.getinstance ();
Then you can use log variables to output logs.
Spit a few words, log4j pit ah ....
(1) Classpath can not have more than one version of the log4j, otherwise there are grotesque nosuchmethod, nosuchfiled, Noclassdefinefound and other abnormalities. Obviously too much, and also told you No
(2) with the SLF4J, must be consistent version, such as slf4j-1.7.2 corresponding log4j-1.2.17
(3) configuration file Ah, if you refer to the third party package has log4j.properties, and did not provide you with editing, then congratulations, slowly tune it. Write the log4j configuration to the code, not the configuration file.
(4) If you intend to use only log4j, and do not use SLF4J for packaging, remember that classpath can only have log4j, can not have log4j-over-slf4j-1.7.12.jar this package, otherwise there will be a variety of errors, such as:
Nosuchmethod, nosuchfiled, Noclassdefinefound, Incompatibleclasschangeerror:implementing class III, logging
Directly an example
(1) Add a class to your code, and the code sees the back. In general, you only need to modify the output log file name.
(2) Add a variable in any class that requires an output log, private static Logger log = Mylogger.getinstance ();
You can then use log variables to do the logging output.
Explain:
1, Storm from 0.9.1 after the use of the log architecture is SLF4J+LOGBAKC, replaced the original log4j. We tried to use log4j as a log frame, It was found that log4j.properties was covered by a configuration inside a jar storm, causing the log4j.properties of its definition to not take effect, and then trying to logback a similar problem, defined CLUSTER.xml did not give a log configuration of the worker process.
2, the use of java.util.logging configuration file can also be in the distributed system configuration loading is more complex, and java.util.logging very pit, it is easy to write mistakes, such as the end of each line can not have spaces.
Package com.netease.sytopology.util;
Import java.io.IOException;
Import Java.util.logging.ConsoleHandler;
Import Java.util.logging.FileHandler;
Import Java.util.logging.Level;
Import Java.util.logging.Logger;
Import Java.util.logging.SimpleFormatter;
/**
* @author Lujinhong
* @date July 25, 2015 3:19:56
* @Description:
*/
public class MyLogger {
File path and file name
private static String LogFile = "/home/hadoop/storm/logs/userlog/ma30_filter.log";
Log level
private static level = Level.info;
The size of each log file, in units of M.
private static int logfilesize = 100;
Save data for log files
private static int logfilecount = 10;
Name of Logger
private static String LogName = "Com.lujinhong.demo";
private static Logger LOG = null;
public static synchronized Logger getinstance () {
if (LOG = = null) {
New MyLogger ();
}
return LOG;
}
Private MyLogger () {
LOG = Logger.getlogger (logName);
Filehandler filehandler = null;
try {
Filehandler = new Filehandler (logfile,logfilesize*1024*1024,logfilecount,true);
catch (SecurityException e) {
E.printstacktrace ();
catch (IOException e) {
E.printstacktrace ();
}
Filehandler.setlevel (level);
Filehandler.setformatter (New Simpleformatter ());
Log.removehandler (New Consolehandler ());
Log.addhandler (Filehandler);
}
iv. send log to Rsyslog using Slf4j+log4j2 (i) rsyslog configuration 1, new storm.conf in/ETC/RSYSLOG.D
The contents are as follows:
$WorkDirectory/home/data/log/
$MaxMessageSize 64k
$ModLoad imudp
$UDPServerRun 514
$template Stromtemplate, "/home/data/log/storm_%structured-data:r,ere,1:.*category=\" (. +) \ ". *programname.*--end%_% $YEAR% $MONTH% $DAY%.log "
$template stromformat," [%timestamp:1:10:date-rfc3339%%timestamp:12:19:date-rfc3339%] %syslogseverity-text:::uppercase%%structured-data:r,ere,2:.*category=\ "(. +) \". *programname=\ "(. +) \". *-- end%%msg%\n "
$EscapeControlCharactersOnReceive off
$FileOwner hadoop
$FileGroup Hadoop
$ Filecreatemode 0644
$DirCreateMode 0755
$Umask 0022
local7.* -?stromtemplate;stromformat
local7.* ~
2. Modify/etc/rsyslog.conf
Modify the following 3 lines:
*.*;auth,authpriv.none;cron.none,local7.none-/var/log/syslog
Kern.*,local7.noe -/var/log/kern.log
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none,local7.none -/var/log/messages
Declaring LOCAL7 log is not sent to Syslog, Kern.log,message. Otherwise the log volume is too general to explode.
At this point the Rsyslog is already configured, and it will interpret the log sent to LOCAL7 and put it into/home/data/log. (ii) output log in Java program 1. Add Dependencies
Take maven, for example, to add the following:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactid>log4j-api </artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId> org.apache.logging.log4j</groupid>
<artifactId>log4j-slf4j-impl</artifactId>
< version>2.1</version>
</dependency>
<dependency>
<groupid>org.slf4j </groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.6.6</ Version>
</dependency>
Other compilation methods add the appropriate jar package. 2, prepare the configuration file
Create Log4j2.xml in the resources directory as follows:
<?xml version= "1.0" encoding= "UTF-8"?> <configuration status= "warn" name= "
test" packages= "" >
<Appenders>
<syslog name= "test" format= "RFC5424" host= "192.168.1.100" port= "514" protocol= "
UDP" Appname= "Storm" includemdc= "true" Mdcid= "MDC"
facility= "LOCAL7" enterprisenumber= "18060" newline= "true"
Messageid= "Audit" id= "App" >
<LoggerFields>
<keyvaluepair key= "category" Value= "%c"/>
<keyvaluepair key= "ProgramName" value= "%c"/>
</LoggerFields>
</Syslog>
</ appenders>
<Loggers>
<logger name= "test" level= "INFO" >
<appenderref ref= "test"/ >
</Logger>
<root level= "INFO" >
<appenderref ref= "test"/>
</Root>
</Loggers>
</Configuration>
3. Output Log
(1) Get the Logger object first
public static Logger LOG = Loggerfactory.getlogger ("mytest");
Where the parameter is recommended as the topology name.
(2) Then you can easily output the log
Logger.error ("INFO ljh_test again!");
Logger.info ("Info ljh_test message info");
Logger.debug ("INFO ljh_test message Debug");
Logger.warn ("INFO ljh_test message warn");
The complete code is as follows: Https://github.com/lujinhong/log4j2demo
Package com.lujinhong.demo.log4j2;
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;
public class Log4j2rsyslogdemo {public
static Logger Logger = Loggerfactory.getlogger ("mytest");
public static void Main (string[] args) {
System.out.println ("Hello world2!");
Logger.error ("INFO ljh_test again!");
Logger.info ("Info ljh_test message info");
Logger.debug ("INFO ljh_test message Debug");
Logger.warn ("INFO ljh_test message Warn");
}