在java应用中,经常需要将结果打印出来。平时写些小程序只需要使用System.out.println()方法将内容打印到标准输出。
而在成熟的java产品中一般使用log4j等第三方库进行日志的记录,它的功能更加强大:
- 可以输出到文件
- 可以自定义输出级别,样式
- 可以定义日志文件大小,回滚,打包
- 可以有针对性地对包进行日志输出
首先新建一个java类TestA.java,该类在包com.fudy.bar下
package com.fudy.bar;
import org.apache.log4j.Logger;
public class TestA {
private static Logger log = Logger.getLogger(TestA.class);
public static void execute(int n) {
log.info("in TestA, n is: " + n);
}
}
使用log4j进行日志管理,只需要在类中调用Logger.getLogger()方法就好,参数本类的class。在方法execute中调用了Logger类的info()方法。
log4j主要有如下几个日志级别:
级别顺序(低到高): DEBUG < INFO < WARN < ERROR < FATAL
一般在程序抛出异常的时候使用ERROR级别,给程序员自己看的日志使用DEBUG级别,正常的需要在日志中记录的用INFO级别。
log4j有一个配置文件log4j.properties,在该文件中,如果定义的输出级别为INFO,那么DEBUG的信息就不会被输出。
首先看下文件的简单配置(放在classpath下):
# Root logger option
log4j.rootLogger=INFO, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %-5p %c{1}:%L - %m%n
文件中#为注释,log4j主要由3个部分组成:
- Logger:定义日志的输出级别,目标等信息。
- appender:定义日志输出的目的地。
- Layouts:定义日志以什么样的格式输出。
log4j.properties文件中log4j.rootLogger=INFO,stdout用来定义一个主的Logger,输出级别是INFO。
也就是说,在代码中所有log.debug()的信息不会被打印出来,调用info(),warn(),error(),fatal()的方法会被打印出来。
stdout是输出的目的地,这个名称可以自定义,代表一个appender的名字,后面几行的配置会用到它。
log4j.appender用于定义一个appender,log4j.appender.stdout中的stdout就是上面一行中定义的appender名称。
org.apache.log4j.ConsoleAppender指出将日志输出到标准控制台上。
最后定义一个layout,这里为PatternLayout。ConversionPattern定义了这个Layout改以怎样的样式输出%d{ABSOLUTE} %-5p %c{1}:%L - %m%n
- %d{ABSOLUTE}:输出日期,时分秒毫秒,和%{HH:mm:ss,SSS}的效果一样
- %-5p :-表示左对齐,%p为输出的级别,如INFO,DEBUG,这行的意思就是将日志的级别打印出来,最多5个字符并且左对齐
- %c{1} : 就是打印出类,其中,数字1代表了只打印出类如TestA,数字2代表了打印出类及上层包如bar.TestA,数字3代表了打印类,上2层包如fudy.bar.TestA
- - : 原样输出,没特别意义
- %m : 指的就是输出程序中日志的内容了
- %n:换行
其他详细信息请参考log4j的API中,关于
PatternLayout 的说明
写个主类测试下:
package com.fudy;
import com.fudy.bar.TestA;
public class Main {
public static void main(String args[]) {
TestA.execute(1);
}
}
输出如下:
22:00:38,969 INFO com.fudy.bar.TestA:8 - in TestA, n is: 1
我们可以将日志输出到文件中,log4j.properties的配置文件如下:
# Root logger option
log4j.rootLogger=INFO, file
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\\loging.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
其中rootLogger中file为自定义的appender的名称;使用org.apache.log4j.RollingFileAppender指定输出到文件;
log4j.appender.file.File=C:\\loging.log ,指定文件名为C:\\loging.log
log4j.appender.file.MaxFileSize=1MB ,指定文件大小为1MB,超过1MB时文件会回滚
log4j.appender.file.MaxBackupIndex=1, 指定文件备份的数量
也可以同时输出到文件和标准控制台:
# Root logger option
log4j.rootLogger=INFO, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\\loging.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# 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{ABSOLUTE} %5p %c{1}:%L - %m%n
可以将日志文件每天进行备份:
log4j.rootCategory=INFO, LOGFILE
log4j.logger.org.apache.axis.enterprise=FATAL, LOGFILE
# LOGFILE is set to be a DailyRollingFileAppender appender using a PatternLayout.
log4j.appender.LOGFILE = org.apache.log4j.DailyRollingFileAppender
log4j.appender.LOGFILE.File=/log/logFileName.log
log4j.appender.LOGFILE.Append = true
log4j.appender.LOGFILE.Threshold=DEBUG
log4j.appender.LOGFILE.DatePattern = '.'yyy-MM-dd
log4j.appender.LOGFILE.layout = org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n
通过log4j.appender.LOGFILE = org.apache.log4j.DailyRollingFileAppender指定每天备份日志文件
每天会备份成/log/logFileName.log.年月日
我们还可以为某个package自定义级别,比如给com.fudy.bar设置debug级别,其他的用info级别
log4j.logger.com.fudy.bar=debug,stdout指出,com.fudy.bar下的java 及其子包下的java的log的级别都是debug
log4j.logger.com.fudy.bar=debug,stdout指出,com.fudy.bar下的java 及其子包下的java的log的级别都是debug
# 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{ABSOLUTE} %-5p %c{4}:%L - %m%n
#define package level log
log4j.logger.com.fudy.bar=debug, stdout
#不要继承祖先的appender
log4j.additivity.com.fudy.bar=false
这里要注意的是additivity, 这个属性指定com.fudy.bar不继承父的appender, 如果少了这句, Log会被打印两次。