一、日志概述
- 日志的原理
通过一个标志位debug控制输出。
这时的输出便是可控的,但只有两个级别:输出与不输出。
debug为false时不输出,debug为true时输出。
Log4j等日志工具也都是这个原理,但增加了很多的输出级别。输出级别、输出样式、
输出目的地都可以在配置文件中配置,而不是写在程序中,增加了灵活性。 - JDK1.4的Logging
JDK Logging把日志分为几个级别:ALL、FINEST、FINER、FINE、
CONFIG、INFO、WARNING、SEVERE、OFF等,级别依次升高。
如果将级别设为INFO,则INFO之前的低级别信息将不会输出,
只有INFO级别之后的信息会输出,通过控制级别达到控制输出的目的。
Logger log = Logger.getLogger(classString); // JDK日志
Handler console = new ConsoleHandler(); // 添加一个控制台输出
console.setLevel(Level.INFO); // 设置控制台级别为INFO
log.addHandler(console); // 添加到log中
log.setLevel(Level.INFO); // 设置log级别为INFO
log.info("info") // info输出 - Log4J控件
Log4J是目前应用最广泛的日志控件,它把日志分为ALL、TRACE(跟踪)、DEBUG(调试)、
INFO(信息)、WARNING(警告)、ERROR(错误)、FITAL(致命)、OFF等几个级别,
级别依次升高。级别高的Level会屏蔽级别低的信息。
如果设置为WARNING,则TRACE、DEBUG、INFO都不会输出。
注意添加Log4J的类库。
日志的配置例如输出级别、输出到哪儿、输出什么附加信息、输出格式(包括时间、
类名、输出级别以及日志信息)等,一般都写在配置文件log4j.properties中。
Log4J的使用十分灵活,功能也很强大。可以在配置文件中配置输出样式,
可以把日志输出到屏幕、控制台、各种样式的文件、数据库、FTP服务器、HTTP服务器、
远程实时监控程序、Windows NT系统日志、发送邮件到指定邮箱、甚至发送短信等。 - commons-logging控件
commons-logging是Apache commons类库中的一员。
commons-logging能够选择使用Log4J还是JDK Logging,
但不依赖于Log4J、JDK Logging的API。
如果项目的classpath中包含log4j的类库,则使用log4j,否则使用JDK Logging。
使用commons-logging能够灵活的选择使用哪种日志方式,而不需要修改源代码。
commons-logging的使用类似于Log4J,它们的级别及使用规则是完全一样的。
默认地,commons-logging会自动检查是否使用log4j。也可以使用配置文件显示地启用log4j。
配置文件为commons-logging.properties,放到程序的classpath下即可。
二、Log4J控件
- Log4j概述
- Log4j的执行效率
Log4j内部做了大量的优化、缓存工作,
使输出时对服务器的压力、消耗的时间、资源等都达到最小。
Log4j只在初始化的时候打开文件,并保持对文件的写控制,直到系统
结束的时候才关闭文件。这样就使I/O次数达到最小,提高了运行效率。
而当输出级别设为ERROR时,log.debug()、log.warning()方法
会因为输出级别小于ERROR而直接返回,因此不会消耗太多的资源。 - 优化日志代码
- Log4j.properties配置文件
Log4j默认的配置文件为log4j.properties。启动时,
会加载classpath下的log4j.properties初始化Log4j。 - 使用其他配置文件
如果不使用默认的文件名log4j.properties,
可以使用PropertyConfigurator指定配置文件路径。
PropertyConfigurator.configure("src/Log4jConfigTest.properties"); - Log4j.xml配置文件
Lot4j也可以使用XML文件配置
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{HH:mm:ss} %5p %c{1} %m%n" />
</layout>
</appender>
XML配置需要遵循Log4j的格式。
三、日志记录器Logger
- Log4j配置中有3个重要的概念:
日志记录器(Logger)、输出地(Appender)以及日志格式化器(Layout)。
其中,Logger负责记录日志,Appender负责输出到什么地方,Layout负责
以什么格式输出、输出哪些附加信息(例如时间、类名、方法名、所在行数等)。 - 日志记录器Logger
Logger就是Java代码中的Logger。
public Logger log = Logger.getLogger(Log4jConfigTest.class);
Logger是有名字的,它的名字便是Logger.getLogger()方法的参数。
如果参数为所在的类,Log4j会取类名作为Logger的名称。
Logger为单态模式:相同名字的Logger只会有一个实例。
如果在构建一个同名的Logger,Log4j会返回先前的Logger实例。
命名规则:一般都以类名作为Logger的名称。Logger的名字类似于
Java中的Package名字,大小写敏感、用点分开且具有继承关系。
Log4j中有一个根记录器rootLogger,它是所有Logger的父亲。 - Logger的配置
在log.properties配置中,log4j.logger后面配置的是Logger,
log4j.appender后面配置的是Appender。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, A1 - rootLogger配置
根记录器rootLogger直接用log4j.rootLogger配置。
rootLogger是所有记录器的父亲。任何记录其都可继承rootLogger的配置。
log4j.rootLogger=ERROR, A1 - 类别category配置
Logger还有个类别(Category)的概念,通过设置类别来设置类别下所有的Logger:
log4j.category.com.xxx=DEBUG
四、输出地Appender
- Appender表示日志输出到什么地方,常用的输出地有控制台、文件、数据库、远程服务器等。
Log4j中内置了常用的输出地,一般情况下配置一下即可使用。
所有的Appender都实现自org.apache.log4j.Appender接口。
在log4j.properties中,Appender都使用log4j.appender.*配置。 - 输出到控制台
控制台是最常用的输出地。控制台输出实现类为org.apache.log4j.ConsoleAppender。
log4j.rootLogger=ERROR, A1
log4j.category.com.xxx=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.Encoding=UTF-8
log4j.appender.A1.ImmediateFlush=true
log4j.appender.A1.Target=System.err
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
控制台输出需要配置layout属性,最常用的是正则表达式格式。
Encoding设置编码方式,ImmediateFlush设置是否缓存,
Target设置输出到System.out还是System.err。
Threhold用来设置该Appender的级别,只对本Appender生效。 - 输出到文件
文件输出(FileAppender)把日志输出到指定的文件。
文件输出的实现类为org.apache.log4j.FileAppender,
配置时需要用File指定文件名称。可以使用相对路径,也可以使用绝对路径。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\tomcat.log
log4j.appender.f.Appender=true
log4j.appender.f.layout=org.apache.log4j.PatternLayout
log4j.appender.f.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
可选参数Append配置是否在源文件内容的基础上追加日志。
如果为false,Logger初始化时会先清掉文件内容,也就是说每次重启程序,
原来的日志会丢失。如果为true,日志文件会越来越大。默认为true。 - 输出到按大小滚动的文件
按大小滚动文件输出(RollingFileAppender)把日志输出到指定的文件,
文件达到指定的大小时,会自动更名。按尺寸滚动文件输出类为
org.apache.log4j.RollingFileAppender,需配置文件名称、文件的最大尺寸。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, f, rolling_file
log4j.appender.rolling_file=org.apache.log4j.RollingFileAppender
log4j.appender.rolling_file.Threshold=DEBUG
log4j.appender.rolling_file.File=C:\\rolling.log
log4j.appender.rolling_file.Appender=true
log4j.appender.rolling_file.MaxFileSize=10KB
log4j.appender.rolling_file.MaxBackupIndex=100
log4j.appender.rolling_file.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling_file.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
配置的滚动文件名为rolling.log,文件最大为10K。当rolling.log达到10K时,
会自动更名为rolling.log.1、rolling.log.2...直到rolling.log.100。
Logger支持多个Appender,用逗号将多个Appender名字隔开即可。 - 输出到按日期滚动文件
按日期滚动文件输出(DailyRollingFileAppender)将日志输出到指定的文件,
当日期发生变化时,会将文件按指定的日期格式自动改名。
日期滚动文件输出类为org.apache.log4j.DailyRollingFileAppender。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, dailly_rolling
log4j.appender.dailly_rolling=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailly_rolling.File=C:\\daily_rolling.log
log4j.appender.dailly_rolling.DatePattern=.yyyy-MM-dd
log4j.appender.dailly_rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.dailly_rolling.layout.ConversionPattern=
%-d{yyyy-MM-dd HH:mm:ss,SSS}[%C]-[%P] %m%n
日志文件名称为daily_rolling.log,日期格式为yyyy-MM-dd。进入新的一天后,
文件会被自动更名,格式为daily_rolling.log.yyyy-MM-dd。 - 输出到JDBC数据库
数据库输出(JDBCAppender)通过JDBC连接把日志输出到数据库中。
配置时需要配置JDBC驱动、连接字符串、用户名、密码以及SQL语句。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, DATABASE
log4j.appender.DATABASE=org.apache.log4j.JDBCAppender
log4j.appender.DATABASE.Threshold=ERROR
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/log4j
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=admin
log4j.appender.DATABASE.sql=INSERT INTO tb_log(
data, priority, message, classname) VALUES('%d', '%p', '%m', '%c')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=%m
配置的关键是SQL语句。Log4j能够取到各种环境数据,
包括时间、级别、类名、文件名、方法名、所在行数等。 - 输出到SOCKET套接字
套接字输出(SocketAppender)将日志通过网络TCP协议发送给远程的服务器。
SocketAppender会与远程服务器建立Socket连接,将日志信息封装为
LoggingEvent对象,串行化(Serialize)后发送给对方。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, SOCKET
log4j.appender.SOCKET=org.apache.log4j.SocketAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=2008
log4j.appender.SOCKET.ReconnectionDelay=30000
log4j.appender.SOCKET.LocationInfo=true
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCKET.layout.ConversionPattern=%m
可选参数LocationInfo配置是否发送本地信息给服务器。
ReconectionDelay配置如果连接失败,多少毫秒后重新连接。
用户可以使用SocketServer自己编写一个服务器端,
在某个特定的端口监听,接收Log4j发送的日志并实时显示。
Log4j自带一个简单的服务器,用来接收SocketAppender发送的数据。
该程序只是简单的将接受到的数据输出到文件。
import org.apache.log4j.net.SimpleSocketServer;
public class RunSimpleSocketServer {
public static void main(String[] args) {
String port = "2008";
String file = "C:\\socket.log";
SimpleSocketServer.main(new String[] {port, file});
// 启动SimpleSocketServer
}
}
SimpleSocketServer启动后便在2008端口等待。
如果有Log4j连接,则接收日志,并记录到C:\\socket.log中。 - 输出到SMTP邮件
邮件输出(SMTPAppender)将日志以邮件的形式发送出去,配置时需要配置
邮件服务器地址、用户名、密码、发件人邮箱、收件人邮箱等。
发送邮件需要Java Mail的支持。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, MAIL
log4j.appender.MAIL=org.apache.log4j.SMTPAppender
log4j.appender.MAIL.BufferSize=512
log4j.appender.MAIL.SMTPHost=smtp.163.com
log4j.appender.MAIL.Subject=Log4j Error Message
log4j.appender.MAIL.SMTPUsername=your_username
log4j.appender.MAIL.SMTPPassword=your_password
[email protected]
[email protected]
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=%m
SMTPappender默认的输出级别为ERROR。 - 自定义输出
Log4j支持自定义的输出。所有的输出都实现自Appender接口。一般来说,
自定义输出值需要继承AppenderSkeleton类,并实现几个方法就可以了。
log4j.logger.com.xxx.logging.Log4jConfigTest=DEBUG, COUNTING
log4j.appender.COUNTING=org.apache.log4j.CountingConsoleAppender
log4j.appender.COUNTING.limit=10
log4j.appender.COUNTING.layout=org.apache.log4j.PatternLayout
log4j.appender.COUNTING.layout.ConversionPattern=%m
设定输出次数为10。当输出次数超过10后,
该自定义Appender会输出信息后并停止输出。
五、日志格式化器Layout
- 日志格式化器Layout负责格式化日志信息。方法log.error()的参数值包含日志信息,
利用Layout可以附加其他信息,以输出更多的信息或者布局显示。 - PatternLayout
PatternLayout是最常用的格式化器,用户可以自定义输出信息,例如日期、
时间、所在的线程、类名、文件名、方法名、信息级别、文件行数等。
Log4j的常用参数
c 输出Logger所在的类别(即Logger的名字)。
允许使用%c{数字}输出部分的名称(从右边往左边数)。
C 输出Logger所在类的名称。
有时候Logger的名称不同于类名。
d 输出日期。允许使用%d{yyyy-MM-dd HH:mm:ss}格式化日期。
%d不仅支持JDK SimpleDateFormat的日期格式,
还支持自己的日期格式。
F 输出所在的类文件名称
l 输出语句所在的行数,包括类名、方法名、文件名、行数等。
L 输出语句所在的行数,只输出数字。
m 输出日志
M 输出方法名
n 换行。Windows下输出\r\n,Linux下输出\n。
p 输出日志级别
r 输出从程序启动到输出该日志之间的时间间隔,单位毫秒。
t 输出当前的线程名称
% %%用来输出百分号
Log4j允许设置输出内容的长度等,不够长会用空格补齐,使输出内容变得整齐。
设置方法是在%与参数符号间添加数字,例如%20p、%-20p等。
正数表示右对齐,负数表示左对齐,数字表示最小宽度,不足时用空格补齐。
还可以设置最大宽度,如果超出,则截取,方法是用小数点+数字设置,例如%.30p。 - HTMLLayout布局
HTMLLayout将日志格式化为HTML代码,输出到文件后,可以直接用浏览器浏览。
使用HTMLLayout时,日志文件后缀一般为.html。
log4j.rootLogger=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\log.html
log4j.appender.f.Appender=false
log4j.appender.f.layout=org.apache.log4j.HTMLLayout - XMLLayout布局
XMLLayout把日志内容格式化为XML文件。XML文件的好处是解析比较容易,
有现成的DOM技术与SAX技术。XMLLayout的配置如下:
log4j.rootLogger=DEBUG, f
log4j.appender.f=org.apache.log4j.FileAppender
log4j.appender.f.File=C:\\abc.log
log4j.appender.f.Encoding=UTF-8
log4j.appender.f.Appender=false
log4j.appender.f.layout=org.apache.log4j.XMLLayout
XMLLayout生成的并不是完整的XML文件,而只是XML文件的一部分,
因此是无法直接打开、解析的。其中包含一系列的<log4j:event>标签。
可以在XML文档中引入文档类型名称为log4j:eventSet的外部DTD文件,
并设置实体标签引入[<!ENTITY data SYSTEM "abc.log"]xml文件,
然后data置于<log4j:eventSet>标签里面:
<log4j:eventSet>&data;</log4j:eventSet>。