Log4j有三个主要的组件:Loggers(日志记录器),Appenders (日志的输出源)和Layouts(日志的布局)。可简单理解为日志类别,日志要输出的地方和日志以何种格式输出。配合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。
Loggers组件在系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有优先级的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度,记住这一点很重要!
Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。
Log4j日志系统还提供许多强大的功能,比如允许把日志输出到不同的地方,如控制台(Console)、文件(Files)等,可以根据天数或者文件大小产生新的文件,可以以流的形式发送到其它地方等等。
常使用的类如下:
具体配置方式,参照下方 配置详解 章节。
Log4j日志系统支持根据自己的喜好格式化自己的日志输出,Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。
常使用的类如下:
具体配置方式,参照下方 配置详解 章节。
在实际应用中,要使Log4j日志功能在系统中运行,须事先设定配置文件。配置文件事实上也就是对Logger、Appender及Layout进行相应设定。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是properties属性文件。一般使用properties属性文件居多,下面以properties属性文件为例介绍log4j.properties的配置。
log4j.rootLogger = [ level ] , appenderName1, appenderName2, …
level :设定日志记录的最低级别,可设的值有OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别,Log4j建议只使用中间四个级别。通过在这里设定级别,您可以控制应用程序中相应级别的日志信息的开关,比如在这里设定了INFO级别,则应用程序中所有DEBUG级别的日志信息将不会被打印出来。
appenderName:就是指定日志信息要输出到哪里,名字可以随意取。可以同时指定多个输出目的地,用逗号隔开。以目前为止的介绍,理解appenderName可能比较抽象。后面还会介绍到它的。
log4j.appender.appenderName = className
appenderName:就是上面提到的自定义appderName,在log4j.rootLogger设置中配置;
className:可设值如下:
配置方式(例):
log4j.appender.appenderName = org.apache.log4j.ConsoleAppender
如果选择了ConsoleAppender(控制台)选项,还可以进行更详细配置:
配置方式(例):
log4j.appender.appenderName.Threshold = WARN
如果选择了FileAppender(文件)选项,还可以进行更详细配置:
配置方式(例):
log4j.appender.appenderName.File = D:/logs/mylog.txt
如果选择了DailyRollingFileAppender(每天产生一个日志文件)选项,还可以进行更详细配置:
另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:
如果选择了RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)选项,还可以进行更详细配置:
log4j.appender.appenderName.layout=className
className:可设值如下:
HTMLLayout选项:
PatternLayout选项:
格式化符号说明:
另外,还可以在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:
log4j.rootLogger=DEBUG,myLogFile,myConsoleLog
# myConsoleLog log
log4j.appender.myConsoleLog = org.apache.log4j.ConsoleAppender
log4j.appender.myConsoleLog.layout = org.apache.log4j.PatternLayout
log4j.appender.myConsoleLog.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
# myLogFilelog
log4j.appender.myLogFile = org.apache.log4j.RollingFileAppender
log4j.appender.myLogFile.File =E:\\test.log
log4j.appender.myLogFile.MaxFileSize = 50MB
log4j.appender.myLogFile.MaxBackupIndex = 2
log4j.appender.myLogFile.layout = org.apache.log4j.PatternLayout
log4j.appender.myLogFile.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
单以这个配置文件来看,在输出日志的时候,会分别往控制台和日志文件两个地方写日志。
如果想只在文件中输出日志,不在控制台输出日志可以这样改:
// 更改 rootLogger,去掉在控制台输出的appenderName
log4j.rootLogger=INFO,myLogFile
如果 rootLogger 配置项只配置了优先级,没有配置 appenderName。那么将不会输出日志到任何地方。
了解了这个配置后,就可以在配置文件里面一次性配置很多不同的日志输出源了,比如:输出到控制台、输出到文件、发送日志给邮件、每天创建一个日志文件…等等。然后根据不同的情况,启用不同的日志输出源,也就是在 rootLogger 配置上对应的 appenderName 就行了
示例 LogUtil 类
import org.apache.log4j.Logger;
public class LogUtil{
private static Logger infoLogger = Logger.getLogger("InfoLogger");
private static Logger errorLogger = Logger.getLogger("ErrorLogger");
private static Logger warnLogger = Logger.getLogger("WarnLogger");
private static Logger debugLogger = Logger.getLogger("DebugLogger");
private enum LogType{
INFO,
ERROR,
WARN,
DEBUG,
}
/**
* 获取方法信息
* @return 方法信息字符串
*/
private static String getMethodInfo() {
// 这里取数组的第二项的原因是,获取调用链的倒数第二层。
// 如果写 [1] 的话,那么获取到的方法信息就会是最后调用这个方法的调用者,
// 也就是logInfo、logError、logWarn 和 logDebug这几个方法的信息了
StackTraceElement traceElement = ((new Exception()).getStackTrace())[2];
StringBuffer stringBuffer = new StringBuffer("[").
append(traceElement.getFileName()).
append(" ( ").append(traceElement.getLineNumber()).append(" )| ").
append(traceElement.getMethodName()).
append("]::");
return stringBuffer.toString();
}
public static void logInfo(String logStr, Throwable...ex){
infoLogger.info(getMethodInfo()+logStr);
}
public static void logError(String logStr, Throwable...ex){
errorLogger.error(getMethodInfo()+logStr);
}
public static void logWarn(String logStr, Throwable...ex){
warnLogger.warn(getMethodInfo()+logStr);
}
public static void logDebug(String logStr, Throwable...ex){
// 使用isDebugEnabled(),为了提升性能
if(debugLogger.isDebugEnabled()){
debugLogger.debug(getMethodInfo()+logStr);
}
}
}
测试类
public class Test{
public static void main(String[] args) {
testProLog.logInfo("im info log");
testProLog.logError("im error log");
testProLog.logWarn("im warn log");
testProLog.logDebug("im debug log");
}
}
输出结果样式
2019-04-26 16:01:18 [InfoLogger]-[INFO] [Test.java ( 5 )| main]:im info log
2019-04-26 16:01:18 [ErrorLogger]-[ERROR] [Test.java ( 6 )| main]:im error log
2019-04-26 16:01:18 [WarnLogger]-[WARN] [Test.java ( 7 )| main]:im warn log
2019-04-26 16:01:18 [DebugLogger]-[DEBUG] [Test.java ( 8 )| main]:im debug log
下面附上一个比较全面的Log4j的配置,可以根据自己的需求进行微调
log4j.rootLogger=DEBUG,FILE
log4j.addivity.org.apache=true
# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=GBK
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# 每天新建日志
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=E:\\log
log4j.appender.A1.Encoding=GBK
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L : %m%n
#应用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=E:\\log.txt
log4j.appender.FILE.Append=false
log4j.appender.FILE.Encoding=GBK
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# 应用于文件回滚
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.CONSOLE_FILE.Encoding=GBK
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = [email protected]
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志给邮件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
[email protected]
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
[email protected]
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
技 术 无 他, 唯 有 熟 尔。
知 其 然, 也 知 其 所 以 然。
踏 实 一 些, 不 要 着 急, 你 想 要 的 岁 月 都 会 给 你。