Java常用类源码分析及运行机制(一):logging

1. Logging配置

目录:$JAVA_HOME/jre/lib/logging.properties

# 默认配置
handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

com.xyz.foo.level = SEVERE  
sun.rmi.transport.tcp.logLevel = FINE 

第一行:Handler。用逗号分隔每个Handler,包括ConsoleHandler(控制台)、FileHandler(文件)、MemoryHandler(内存缓冲区)、SocketHandler(网络流)、StreamHandler(流,常作为其他Handler的基类)。
举个栗子:

handlers = java.util.logging.ConsoleHandler,java.util.logging.FileHandler,java.util.MemoryHandler,java.util.logging.SocketHandler,java.util.logging.StreamHandler

第二行:.level是root logger的日志级别。
第三行至第八行: .xxx是配置具体某个handler的属性,以FileHandler为例:

  • java.util.logging.FileHandler.level 为 Handler 指定默认的级别(默认为 Level.ALL)。
  • java.util.logging.FileHandler.filter 指定要使用的 Filter 类的名称(默认为无 Filter)。
  • java.util.logging.FileHandler.formatter指定要使用的Formatter类的名称(默认为java.util.logging.XMLFormatter)。
  • java.util.logging.FileHandler.encoding 指定要使用的字符集编码的名称(默认使用默认的平台编码)。
  • java.util.logging.FileHandler.limit 指定要写入到任意文件的近似最大量(以字节为单位)。如果该数为 0,则没有限制(默认为无限制)。
  • java.util.logging.FileHandler.count 指定有多少输出文件参与循环(默认为 1)。
  • java.util.logging.FileHandler.pattern 为生成的输出文件名称指定一个模式。有关细节请参见以下内容(默认为 “%h/java%u.log”)。
  • java.util.logging.FileHandler.append指定是否应该将FileHandler追加到任何现有文件上(默认为 false)。

    • ”/” 本地路径名分隔符
    • “%t” 系统临时目录
    • “%h” “user.home” 系统属性的值
    • “%g” 区分循环日志的生成号
    • “%u” 解决冲突的唯一号码
    • “%%” 转换为单个百分数符号”%”

第九行:logger的配置,所有以[.level]结尾的属性皆被认为是对某个logger的级别的定义。

2.logging的执行过程

Logger的获取###参照

首先是调用Logger的getLogger()方法获得一个logger:

public static synchronized Logger getLogger(String name) {  
    LogManager manager = LogManager.getLogManager();  
    return manager.demandLogger(name);  
} 

上面的调用会触发java.util.logging.LoggerManager的类初始化工作,LoggerManager有一个静态化初始化块(这是会先于LoggerManager的构造函数调用的~_~):

static {  
   AccessController.doPrivileged(new PrivilegedAction<Object>() {  
       public Object run() {  
           String cname = null;  
           try {  
               cname = System.getProperty("java.util.logging.manager");  
               if (cname != null) {  
                  try {  
                       Class clz = ClassLoader.getSystemClassLoader().loadClass(cname);  
                       manager = (LogManager) clz.newInstance();  
                   } catch(ClassNotFoundException ex) {  
                       Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname);  
                       manager = (LogManager) clz.newInstance();  
                   }  
               }  
           } catch (Exceptionex) {  
              System.err.println("Could not load Logmanager \"" + cname+ "\"");  
              ex.printStackTrace();  
           }  
           if (manager == null) {  
               manager = newLogManager();  
           }  

           manager.rootLogger = manager.newRootLogger();  
           manager.addLogger(manager.rootLogger);  

           Logger.global.setLogManager(manager);  
           manager.addLogger(Logger.global);  

           return null;  
       }  
   });  
} 

从静态初始化块中可以看出LoggerManager是可以使用系统属性java.util.logging.manager指定一个继承自java.util.logging.LoggerManager的类进行替换的,比如Tomcat启动脚本中就使用该机制以使用自己的LoggerManager。

不管是JDK默认的java.util.logging.LoggerManager还是自定义的LoggerManager,初始化工作中均会给LoggerManager添加两个logger,一个是名称为””的root logger,且logger级别设置为默认的INFO;另一个是名称为global的全局logger,级别仍然为INFO。

LogManager”类”初始化完成之后就会读取配置文件(默认为$JAVA_HOME/jre/lib/logging.properties),把配置文件的属性名<->属性值这样的键值对保存在内存中,方便之后初始化logger的时候使用。

第一步中Logger类发起的getLogger操作将会调用java.util.logging.LoggerManager的如下方法:

Logger demandLogger(String name) {  
    Logger result = getLogger(name);  
    if (result == null) {  
        result = newLogger(name, null);  
            addLogger(result);  
            result = getLogger(name);  
    }  
    return result;
} 
weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值