1. JUL
JUL,java.util.logging
,JDK自带的日志框架。
使用样例,
// 1. 获取日志记录器对象
Logger logger = Logger.getLogger("org.example.jul.JulTest");
// 2. 日志记录输出
logger.info("hello jul");
// 通用方法日志记录
logger.log(Level.INFO, "info msg");
// 通过占位符方式输出变量值
String name = "nlh";
Integer age = 13;
logger.log(Level.INFO, "用户信息:{0}, {1}", new Object[]{name, age});
执行过程,
- 初始化LogManager
- LogManager加载logging.properties配置
- 添加Logger到LogManager
- 从单例LogManager获取Logger
- 设置级别Level,并指定日志记录LogRecord
- Filter提供了日志级别之外更细粒度的控制
- Handler是用来处理日志输出位置
- Formatter格式化LogRecord
默认的日志输出级别是INFO
,日志级别可以在类Level
下查看。
自定义输出级别,
// 1. 获取日志记录器对象
Logger logger = Logger.getLogger("org.example.jul.JulTest");
// 关闭系统默认配置
logger.setUseParentHandlers(false);
// 自定义日志级别
// 创建handler
Handler handler = new ConsoleHandler();
// 创建简单格式转换对象
Formatter formatter = new SimpleFormatter();
// 进行关联
handler.setFormatter(formatter);
logger.addHandler(handler);
// 配置日志具体级别
logger.setLevel(Level.ALL);
handler.setLevel(Level.ALL);
// 创建日志文件输出
Handler fileHandler = new FileHandler("logs/jul.log");
fileHandler.setFormatter(formatter);
logger.addHandler(fileHandler);
// 2. 日志记录输出
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
JUL中的Logger存在父子关系。默认的顶层Logger是RootLogger,Logger之间的关系通过树路径关联。
Logger是用name作为标志的,子Logger默认使用父Logger的Handler,因此,在自定义Logger时,需要设置setUseParentHandlers
为false。
除了在类中定义Logger外,还可以在配置文件logging.properties
中配置
handlers= java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level= ALL
# 自定义Logger
com.example.handlers = java.util.logging.ConsoleHandler
com.example.level = INFO
com.example.useParentHandlers = false
java.util.logging.FileHandler.pattern = logs/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append = true
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n
在类中加载配置文件,
// 读取配置文件,通过类加载器
InputStream ins = JulTest.class.getClassLoader().getResourceAsStream("logging.properties");
// 创建LogManager
LogManager logManager = LogManager.getLogManager();
// 通过LogManager加载配置文件
logManager.readConfiguration(ins);
// 创建日志记录器
Logger logger = Logger.getLogger("com.example");
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
Logger logger2 = Logger.getLogger("test");
logger2.severe("severe test");
logger2.warning("warning test");
logger2.info("info test");
logger2.config("config tests");
logger2.fine("fine test");
2. Log4j
Maven仓库地址,
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Log4j主要有Loggers、Appenders和Layout三部分组成。其中,Loggers控制日志的输出级别和日志是否输出;Appenders指定日志的输出方式;Layout控制日志的输出格式。
常用Appenders有,
- ConsoleAppender
- FileAppender
- DailyRollingFileAppender
- RollingFileAppender
- JDBCAppender
快速开始,
// 初始化配置信息,使用代码配置
BasicConfigurator.configure();
// 获取日志记录器对象
Logger logger = Logger.getLogger(Log4jTest.class);
// 日志记录输出
logger.info("Hello Log4j");
// 日志级别
logger.fatal("fatal");
logger.error("error");
logger.warn("warn");
logger.info("info");
logger.debug("debug");
logger.trace("trace");
其中,BasicConfigurator
类采用了默认配置,观察它的源码,验证了log4j由三部分组成。
同时,log4j也支持配置文件设置,默认log4j.properties
,样例如下,
log4j.rootLogger = trace,console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n
支持自定义logger
,将来源不同的日志,输出到不同的指定位置。例如,下列配置,
log4j.rootLogger = trace,console
log4j.logger.org.example = info,file
log4j.logger.org.apache = error
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n
log4j.appender.file = org.apache.log4j.FileAppender
log4j.appender.file.file = logs/log4j.log
log4j.appender.file.encoding = UTF-8
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern = %r [%t] %p %c %x - %m%n
自定义了两个Logger
,分别控制org.example
和org.apache
包下的日志输出。org.example
的输出级别是info
,采用名为file
的appender;而org.apache
的输出级别是error
,没有定义appender,默认采用rootLogger
的appender。在上述配置下,运行下列代码,
Logger logger = Logger.getLogger(Log4jTest.class);
logger.info("Hello Log4j");
logger.fatal("fatal");
logger.error("error");
logger.warn("warn");
logger.info("info");
logger.debug("debug");
logger.trace("trace");
Logger logger1 = Logger.getLogger(Logger.class);
logger1.fatal("fatal logger1");
logger1.error("error logger1");
logger1.warn("warn logger1");
在console中输出结果为,
0 [main] INFO org.example.log4j.Log4jTest - Hello Log4j
1 [main] FATAL org.example.log4j.Log4jTest - fatal
2 [main] ERROR org.example.log4j.Log4jTest - error
2 [main] WARN org.example.log4j.Log4jTest - warn
2 [main] INFO org.example.log4j.Log4jTest - info
2 [main] FATAL org.apache.log4j.Logger - fatal logger1
2 [main] ERROR org.apache.log4j.Logger - error logger1
文件中的输出结果为,
0 [main] INFO org.example.log4j.Log4jTest - Hello Log4j
1 [main] FATAL org.example.log4j.Log4jTest - fatal
2 [main] ERROR org.example.log4j.Log4jTest - error
2 [main] WARN org.example.log4j.Log4jTest - warn
2 [main] INFO org.example.log4j.Log4jTest - info
达到了将不同来源的日志,输出到不同位置的效果。