- 浏览: 466247 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
ty1972873004:
sunwang810812 写道我运行了这个例子,怎么结果是这 ...
Java并发编程: 使用Semaphore限制资源并发访问的线程数 -
lgh1992314:
<div class="quote_title ...
Java内置Logger详解 -
sunwang810812:
我运行了这个例子,怎么结果是这样的:2号车泊车6号车泊车5号车 ...
Java并发编程: 使用Semaphore限制资源并发访问的线程数 -
jp260715007:
nanjiwubing123 写道参考你的用法,用如下方式实现 ...
面试题--三个线程循环打印ABC10次的几种解决方法 -
cb_0312:
SurnameDictionary文章我没看完,现在懂了
中文排序
平时使用Log4j记录日志信息,对JDK内置的Logger还真没有去关注和使用过,只知道这个是在JDK 1.4引入的。这次,抽空去看了一下JDK内置Logger(java.util.logging)。在这篇博文中将记录如下几个方面的信息:
1. JDK内置Logger的类结构
2. JDK内置Logger支持的Level
3. JDK内置Logger支持的Formatter
4. JDK内置Logger支持的Handler
5. JDK内置Logger 默认配置文件
6. 如何使用JDK内置logger
(一) JDK内置Logger的类结构
展开java.util.logging包,我们可以看到JDK内置Logger的类,包括Formatter, Handler等。
JDK内置Logger大致的类图关系如下:(方法和关系没有全部标记出来)
(二) JDK内置Logger支持的Level
JDK内置 Logger提供了如下七种Logger级别,从高到低依次是:
SEVERE->WARNING->INFO->CONFIG->FINE->FINER->FINESET。
另外,可以使用OFF关闭日志记录,使用 ALL 启用所有消息的日志记录。
(三) JDK内置Logger支持的Formatter
JDK Logger支持2种Formatter,包括SimpleFormatter 和 XMLFormatter。其中,
SimpleFormatter以文本的形式记录日志信息;XMLFormatter 以XML格式的形式记录日志信息。
(四) JDK内置Logger支持的Handler
Handler,实现将日志写入指定目的地,JDK Logger主要支持MemoryHandler和StreamHandler两个大类Handler,另外ConsoleHanler, FileHandler以及SocketHandler都是继承自StreamHandler,分别添加了一些自己的功能,分别将日志写入控制台、文件、Socket端口。
ConsoleHandler只是将OutputStream设置为System.err,其他实现和StreamHandler类似。
而SocketHandler将OutputStream绑定到对应的端口号中,其他也和StreamHandler类似。另外它还增加了两个配置:java.util.logging.SocketHandler.port和java.util.logging.SocketHandler.host分别对应端口号和主机。
FileHandler支持指定文件名模板(java.util.logging.FileHandler.pattern),文件最大支持大小(java.util.logging.FileHandler.limit,字节为单位,0为没有限制),循环日志文件数(java.util.logging.FileHandler.count)、对已存在的日志文件是否往后添加(java.util.logging.FileHandler.append)。
FileHandler支持的文件模板参数有:
/ 目录分隔符
%t 系统临时目录
%h 系统当前用户目录
%g 生成的以区别循环日志文件名
%u 一个唯一的数字以处理冲突问题
%% 一个%
SocketHanlder的例子如下:
第一种情况:开启一个Tomcat服务,端口是8080.执行SocketHandlerTest程序,控制输出成功的信息。
第二种情况:关闭Tomcat服务.执行SocketHandlerTest程序,控制输出出错的信息。
再来一个MemoryHanlder的例子:
(五) JDK内置Logger 默认配置文件
JDK内置Logger默认读取的配置文件是jre\lib\logging.properties
这个可以从LogManager的readConfiguration方法中看出:
logging.properties文件截图如下:
从上述默认配置截图的内容可以看出:
1. handlers默认配置了一个ConsoleHandler, 这个就是为什么我们每次记录信息时,控制台会输出信息的原因,去掉ConsoleHandler,那么在控制台将不会有日志信息输出了。
2. FileHandler默认以XML形式输出。
3. ConsoleHandler默认采用文本形式输出。
4. 默认level为INFO.
5. 如果想指定其它的文件作为logger的配置文件,默认配置文件中提供了如下的信息:
############################################################
# Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.
# For example java -Djava.util.logging.config.file=myfile############################################################
另外LogManager中有个public的方法readConfiguration(InputStream ins).
相信这个方法也会是一个实现自定义配置文件的方法。
(六)如何使用JDK内置logger
使用JDK内置Logger可以分成三个步骤来完成:
1. 创建Logger
2. 创建Handler,为handler指定Formmater, 然后将Handler添加到logger中去。
3. 设定Level级别
我们可以自己写一个简单的JDK内置Logger使用的实用类:
使用起来也是很方便的。
package my.logger;
这样,日志信息就会输出到指定的文件中去,查看一下文件内容如下:
这样,JDK Logger就可以方便的使用起来了。使用时,首先创建一个logger,比如:
private static Logger logger = MyLoggerUtil.setLoggerHanlder(Logger.getLogger("my.logger"));
然后在需要记录日志信息的地方调用logger相应的方法来完成日志信息记录即可。
非全局,Logger.setLevel()控制的是logging.properties的ConsoleHandler
1. JDK内置Logger的类结构
2. JDK内置Logger支持的Level
3. JDK内置Logger支持的Formatter
4. JDK内置Logger支持的Handler
5. JDK内置Logger 默认配置文件
6. 如何使用JDK内置logger
(一) JDK内置Logger的类结构
展开java.util.logging包,我们可以看到JDK内置Logger的类,包括Formatter, Handler等。
JDK内置Logger大致的类图关系如下:(方法和关系没有全部标记出来)
(二) JDK内置Logger支持的Level
JDK内置 Logger提供了如下七种Logger级别,从高到低依次是:
SEVERE->WARNING->INFO->CONFIG->FINE->FINER->FINESET。
另外,可以使用OFF关闭日志记录,使用 ALL 启用所有消息的日志记录。
(三) JDK内置Logger支持的Formatter
JDK Logger支持2种Formatter,包括SimpleFormatter 和 XMLFormatter。其中,
SimpleFormatter以文本的形式记录日志信息;XMLFormatter 以XML格式的形式记录日志信息。
(四) JDK内置Logger支持的Handler
Handler,实现将日志写入指定目的地,JDK Logger主要支持MemoryHandler和StreamHandler两个大类Handler,另外ConsoleHanler, FileHandler以及SocketHandler都是继承自StreamHandler,分别添加了一些自己的功能,分别将日志写入控制台、文件、Socket端口。
ConsoleHandler只是将OutputStream设置为System.err,其他实现和StreamHandler类似。
而SocketHandler将OutputStream绑定到对应的端口号中,其他也和StreamHandler类似。另外它还增加了两个配置:java.util.logging.SocketHandler.port和java.util.logging.SocketHandler.host分别对应端口号和主机。
FileHandler支持指定文件名模板(java.util.logging.FileHandler.pattern),文件最大支持大小(java.util.logging.FileHandler.limit,字节为单位,0为没有限制),循环日志文件数(java.util.logging.FileHandler.count)、对已存在的日志文件是否往后添加(java.util.logging.FileHandler.append)。
FileHandler支持的文件模板参数有:
/ 目录分隔符
%t 系统临时目录
%h 系统当前用户目录
%g 生成的以区别循环日志文件名
%u 一个唯一的数字以处理冲突问题
%% 一个%
SocketHanlder的例子如下:
package my.logger; import java.io.IOException; import java.util.logging.Logger; import java.util.logging.SocketHandler; public class SocketHandlerTest { private SocketHandler handler = null; private static Logger logger = Logger .getLogger("my.logger.SocketHandlerTest"); public SocketHandlerTest(String host, int port) { try { handler = new SocketHandler(host, port); logger.addHandler(handler); logger.info("SocketHandler运行成功......"); } catch (IOException e) { logger.severe("请检查地址和端口是否正确......"); StringBuilder sb = new StringBuilder(); sb.append(e.toString()).append("\n"); for(StackTraceElement elem : e.getStackTrace()) { sb.append("\tat ").append(elem).append("\n"); } logger.severe(sb.toString()); } } public static void main(String args[]) { new SocketHandlerTest("localhost", 8080); } }
第一种情况:开启一个Tomcat服务,端口是8080.执行SocketHandlerTest程序,控制输出成功的信息。
第二种情况:关闭Tomcat服务.执行SocketHandlerTest程序,控制输出出错的信息。
再来一个MemoryHanlder的例子:
package my.logger; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.MemoryHandler; public class MemoryHandlerTest { public static void main(String[] args) { Logger logger = Logger.getLogger("my.logger.MemoryHandlerTest"); ConsoleHandler handler = new ConsoleHandler(); MemoryHandler mHandler = new MemoryHandler(handler, 10, Level.ALL); logger.addHandler(mHandler); logger.setUseParentHandlers(false); LogRecord record1 = new LogRecord(Level.SEVERE, "This is SEVERE level message"); LogRecord record2 = new LogRecord(Level.WARNING, "This is WARNING level message"); logger.log(record1); logger.log(record2); } }
(五) JDK内置Logger 默认配置文件
JDK内置Logger默认读取的配置文件是jre\lib\logging.properties
这个可以从LogManager的readConfiguration方法中看出:
logging.properties文件截图如下:
从上述默认配置截图的内容可以看出:
1. handlers默认配置了一个ConsoleHandler, 这个就是为什么我们每次记录信息时,控制台会输出信息的原因,去掉ConsoleHandler,那么在控制台将不会有日志信息输出了。
2. FileHandler默认以XML形式输出。
3. ConsoleHandler默认采用文本形式输出。
4. 默认level为INFO.
5. 如果想指定其它的文件作为logger的配置文件,默认配置文件中提供了如下的信息:
############################################################
# Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.
# For example java -Djava.util.logging.config.file=myfile############################################################
另外LogManager中有个public的方法readConfiguration(InputStream ins).
/** * Reinitialize the logging properties and reread the logging configuration * from the given stream, which should be in java.util.Properties format. * A PropertyChangeEvent will be fired after the properties are read. * <p> * Any log level definitions in the new configuration file will be * applied using Logger.setLevel(), if the target Logger exists. * * @param ins stream to read properties from * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). * @exception IOException if there are problems reading from the stream. */ public void readConfiguration(InputStream ins) throws IOException, SecurityException { checkAccess(); reset(); // Load the properties props.load(ins); // Instantiate new configuration objects. String names[] = parseClassNames("config"); for (int i = 0; i < names.length; i++) { String word = names[i]; try { Class clz = ClassLoader.getSystemClassLoader().loadClass(word); clz.newInstance(); } catch (Exception ex) { System.err.println("Can't load config class \"" + word + "\""); System.err.println("" + ex); // ex.printStackTrace(); } } // Set levels on any pre-existing loggers, based on the new properties. setLevelsOnExistingLoggers(); // Notify any interested parties that our properties have changed. changes.firePropertyChange(null, null, null); // Note that we need to reinitialize global handles when // they are first referenced. synchronized (this) { initializedGlobalHandlers = false; } }
相信这个方法也会是一个实现自定义配置文件的方法。
(六)如何使用JDK内置logger
使用JDK内置Logger可以分成三个步骤来完成:
1. 创建Logger
2. 创建Handler,为handler指定Formmater, 然后将Handler添加到logger中去。
3. 设定Level级别
我们可以自己写一个简单的JDK内置Logger使用的实用类:
package my.logger; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class MyLoggerUtil { private static final SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd"); private static final String LOG_FOLDER_NAME = "MyLoggerFile"; private static final String LOG_FILE_SUFFIX = ".log"; private synchronized static String getLogFilePath() { StringBuffer logFilePath = new StringBuffer(); logFilePath.append(System.getProperty("user.home")); logFilePath.append(File.separatorChar); logFilePath.append(LOG_FOLDER_NAME); File file = new File(logFilePath.toString()); if (!file.exists()) file.mkdir(); logFilePath.append(File.separatorChar); logFilePath.append(sdf.format(new Date())); logFilePath.append(LOG_FILE_SUFFIX); return logFilePath.toString(); } public synchronized static Logger setLoggerHanlder(Logger logger) { return setLoggerHanlder(logger, Level.ALL); } public synchronized static Logger setLoggerHanlder(Logger logger, Level level) { FileHandler fileHandler = null; try { //文件日志内容标记为可追加 fileHandler = new FileHandler(getLogFilePath(), true); //以文本的形式输出 fileHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); logger.setLevel(level); } catch (SecurityException e) { logger.severe(populateExceptionStackTrace(e)); } catch (IOException e) { logger.severe(populateExceptionStackTrace(e)); } return logger; } private synchronized static String populateExceptionStackTrace(Exception e) { StringBuilder sb = new StringBuilder(); sb.append(e.toString()).append("\n"); for (StackTraceElement elem : e.getStackTrace()) { sb.append("\tat ").append(elem).append("\n"); } return sb.toString(); } }
使用起来也是很方便的。
package my.logger;
import java.util.logging.Logger; public class JDKLoggerExample { private static Logger logger = MyLoggerUtil.setLoggerHanlder(Logger.getLogger("my.logger")); public static void main(String[] args) { logger.info("JDK Logger is logging information at INFO Level"); } }
这样,日志信息就会输出到指定的文件中去,查看一下文件内容如下:
这样,JDK Logger就可以方便的使用起来了。使用时,首先创建一个logger,比如:
private static Logger logger = MyLoggerUtil.setLoggerHanlder(Logger.getLogger("my.logger"));
然后在需要记录日志信息的地方调用logger相应的方法来完成日志信息记录即可。
评论
2 楼
lgh1992314
2017-04-24
simpleDean 写道
请问,Logger.setLevel()这个方法就是设置全局的level吗?还有,如果控制这个默认的consolehandler的level?
非全局,Logger.setLevel()控制的是logging.properties的ConsoleHandler
1 楼
simpleDean
2014-03-03
请问,Logger.setLevel()这个方法就是设置全局的level吗?还有,如果控制这个默认的consolehandler的level?
发表评论
-
工厂类中移除if/else语句
2016-07-10 19:52 903面向对象语言的一个强大的特性是多态,它可以用来在代码中移除 ... -
Java编程练手100题
2014-12-11 17:13 6730本文给出100道Java编程练手的程序。 列表如下: 面 ... -
数组复制的三种方法
2014-11-30 12:57 2214本文将给出三种实现数组复制的方法 (以复制整数数组为例)。 ... -
数组复制的三种方法
2014-11-30 12:54 0本文将给出三种实现数组复制的方法 (以复制整数数组为例)。 ... -
四种复制文件的方法
2014-11-29 13:21 1741尽管Java提供了一个类ava.io.File用于文件的操 ... -
判断一个字符串中的字符是否都只出现一次
2014-11-25 12:58 2724本篇博文将给大家带来几个判断一个字符串中的字符是否都只出现一 ... -
使用正则表达式判断一个数是否为素数
2014-11-23 13:35 2168正则表达式能够用于判断一个数是否为素数,这个以前完全没有想过 ... -
几个可以用英文单词表达的正则表达式
2014-11-21 13:12 3751本文,我们将来看一下几个可以用英文单词表达的正则表达式。这些 ... -
(广度优先搜索)打印所有可能的括号组合
2014-11-20 11:58 1954问题:给定一个正整n,作为括号的对数,输出所有括号可能 ... -
随机产生由特殊字符,大小写字母以及数字组成的字符串,且每种字符都至少出现一次
2014-11-19 14:48 3976题目:随机产生字符串,字符串中的字符只能由特殊字符 (! ... -
找出1到n缺失的一个数
2014-11-18 12:57 3176题目:Problem description: You h ... -
EnumSet的几个例子
2014-11-14 16:24 8749EnumSet 是一个与枚举类型一起使用的专用 Set 实现 ... -
给定两个有序数组和一个指定的sum值,从两个数组中各找一个数使得这两个数的和与指定的sum值相差最小
2014-11-12 11:24 3327题目:给定两个有序数组和一个指定的sum值,从两个数组 ... -
Java面试编程题练手
2014-11-04 22:49 6700面试编程 写一个程序,去除有序数组中的重复数字 编 ... -
Collections用法整理
2014-10-22 20:55 9846Collections (java.util.Collect ... -
The Code Sample 代码实例 个人博客开通
2014-09-04 18:48 1418个人博客小站开通 http://thecodesample. ... -
Collections.emptyXXX方法
2014-06-08 13:37 2145从JDK 1.5开始, Collections集合工具类中预先 ... -
这代码怎么就打印出"hello world"了呢?
2014-06-08 00:37 7398for (long l = 4946144450195624L ... -
最短时间过桥
2014-04-21 22:03 4145本文用代码实现最短时间过桥,并且打印如下两个例子的最小过桥时间 ... -
将数组分割成差值最小的子集
2014-04-20 22:34 2903本文使用位掩码实现一个功能 ==》将数组分割成差值最小的子集 ...
相关推荐
4.9 内置的模板规则 114 4.10 对空白的处理 115 4.11 xpath语言 116 4.11.1 xpath上下文 116 4.11.2 位置路径 117 4.11.3 表达式 121 4.11.4 核心函数库 123 4.12 创建结果树 126 4.12.1 创建元素和属性 127...
4.9 内置的模板规则 114 4.10 对空白的处理 115 4.11 xpath语言 116 4.11.1 xpath上下文 116 4.11.2 位置路径 117 4.11.3 表达式 121 4.11.4 核心函数库 123 4.12 创建结果树 126 4.12.1 创建元素和属性 127...
4.9 内置的模板规则 114 4.10 对空白的处理 115 4.11 xpath语言 116 4.11.1 xpath上下文 116 4.11.2 位置路径 117 4.11.3 表达式 121 4.11.4 核心函数库 123 4.12 创建结果树 126 4.12.1 创建元素和属性 127...
4.9 内置的模板规则 114 4.10 对空白的处理 115 4.11 xpath语言 116 4.11.1 xpath上下文 116 4.11.2 位置路径 117 4.11.3 表达式 121 4.11.4 核心函数库 123 4.12 创建结果树 126 4.12.1 创建元素和属性 127...
### Java Log4j 使用详解 #### 一、Java 日志管理概述 在Java应用程序中,良好的日志管理对于系统的维护和故障排查至关重要。本篇文章旨在详细介绍如何在Java中使用Log4j来管理日志,包括其配置方法以及与其他日志...
### Python 实现 Logger 打印功能的方法详解 #### 前言 在开发过程中,日志记录是一项重要的工作,它不仅有助于我们理解程序运行时的行为,还能帮助我们追踪错误、调试问题。Python 提供了内置的 `logging` 模块来...
它可以适配多种日志实现,如log4j或Java内置的日志系统。虽然其自身包含一个简单的logger,但推荐使用性能更优、功能更全的log4j。 除了以上这些核心库,还有一些可选的jar包。比如`ant.jar`和`optional.jar`,它们...
8. commons-logging.jar: Apache Commons Logging是一个日志抽象层,使得应用程序可以在运行时选择不同的日志实现,如log4j或Java内置的日志框架。尽管其自身包含一个简单的logger,但推荐使用功能更强大、性能更好...
- 与Java内置的日志框架java.util.logging相比,Log4j提供了更丰富的功能和更好的可配置性。 - SLF4J(Simple Logging Facade for Java)是一个抽象层,可以用来替换不同的日志实现,包括Log4j。 在实际项目中,...
在Java开发中,常见的日志框架有Log4j、Logback和Java内置的java.util.logging。这些框架提供了丰富的功能,包括不同级别的日志记录、定制化日志格式、过滤策略等。Logger.rar可能使用了其中之一,或者自定义实现。 ...
【Java 日志操作详解】 日志在软件开发中扮演着至关重要的角色,它能帮助开发者追踪和诊断程序运行时的问题。在Java世界里,有多种日志框架可供选择,其中包括Jakarta Commons Logging(JCL)、JDK 1.4自带的Logger...
《log4j使用详解》 在Java开发中,日志记录是不可或缺的一部分,它帮助开发者追踪程序运行状态、定位问题和优化性能。Log4j作为Apache的一个开源项目,是Java领域广泛使用的日志框架,其灵活性和高效性使得它成为...
它的查找逻辑包括检查`commons-logging.properties`配置文件,系统环境变量,或者查找特定日志框架(如log4j)的存在,最后如果都没有找到,它会回退到使用JDK自带的日志实现,或者是其内置的SimpleLog类。...
**日志框架Log4j详解** 日志框架在软件开发中扮演着至关重要的角色,它提供了记录应用程序运行过程中的各种信息的功能,便于调试、监控和问题排查。Log4j是Apache组织开发的一个开源日志记录工具,广泛应用于Java...
### Java自定义异常详解 #### 一、Java异常机制简介 在Java中,异常处理是一种用来可靠地处理程序运行时错误的重要机制。它允许程序员通过`try`、`catch`和`finally`等关键字来组织代码,从而有效地处理程序执行...
1. **基于接口的Java内置动态代理**:使用`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。这种方式要求被代理的对象必须实现至少一个接口。以下是一个简单的例子: - 定义业务接口`...
### IT Java面试题库知识点详解 #### 一、面向对象语言特性 1. **描述一下“Java中面向对象几个典型的面向对象特性”?** - **封装**: 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息...
### Java日志操作之Log4j详解 #### Log4j简介 Log4j是一个非常流行的开源日志框架,由Apache基金会维护。它最初是作为Jakarta项目的一部分出现的,随着时间的发展,Log4j逐渐成为了一个独立且功能强大的日志解决...