IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> JDK自带的java.util.logging.Logger -> 正文阅读

[系统运维]JDK自带的java.util.logging.Logger

环境

  • 操作系统:Ubuntu 20.04
  • JDK:17.0.1

Java自带log功能,用的是JDK标准库中的类java.util.logging.Logger 。下面是一个简单的例子:

package pkg1;

import java.util.logging.*;

public class Test0509 {

    public static void main(String[] args) {
        Logger logger = Logger.getLogger(Test0509.class.getName());

        logger.finest("finest");
        logger.finer("finer");
        logger.fine("fine");
        logger.config("config");
        logger.info("info");
        logger.warning("warning");
        logger.severe("severe");
    }
}

运行程序,结果如下:

May 09, 2022 2:57:02 PM pkg1.Test0509 main
INFO: info
May 09, 2022 2:57:02 PM pkg1.Test0509 main
WARNING: warning
May 09, 2022 2:57:02 PM pkg1.Test0509 main
SEVERE: server

可见,默认的log级别是 INFO ,也就是说 INFO 以及更高级别的log会生效。

注:Logger的 info() 等方法都有一个重载方法,参数的类型是 Supplier<String> ,例如:

        logger.info("info1" + "info2");
        logger.info(() -> "info1" + "info2");

两者功能非常类似,区别在于,前者一定会运行 "info1" + "info2" ,而后者只有在log级别为 INFO 或者更低的时候,才会运行 "info1" + "info2" ,避免了不必要的运算,显然后者性能更好。

Logger与Handler

现在我们来尝试调整log级别:

        ......
        logger.setLevel(Level.WARNING);

        logger.finest("finest");
        logger.finer("finer");
        logger.fine("fine");
        logger.config("config");
        logger.info("info");
        logger.warning("warning");
        logger.severe("severe");
        ......

运行程序,结果如下:

May 09, 2022 3:01:00 PM pkg1.Test0509 main
WARNING: warning
May 09, 2022 3:01:00 PM pkg1.Test0509 main
SEVERE: server

可见,把Logger的级别调整到 WARNING 之后,只有 WARNINGSEVERE 级别的log生效。

接下来把Logger的级别换成 FINER 试试看:

        ......
        logger.setLevel(Level.FINER);

        // comment 1

        logger.finest("finest");
        logger.finer("finer");
        logger.fine("fine");
        logger.config("config");
        logger.info("info");
        logger.warning("warning");
        logger.severe("severe");
        ......

运行程序,结果如下:

May 09, 2022 6:56:55 PM pkg1.Test0509_3 main
INFO: info
May 09, 2022 6:56:55 PM pkg1.Test0509_3 main
WARNING: warning
May 09, 2022 6:56:55 PM pkg1.Test0509_3 main
SEVERE: severe

问题来了,为什么还是只有 INFO以及更高的log级别生效呢?

原因在于,Logger可以有多个Handler,比如下面要提到的 ConsoleHandlerFileHandler 。顾名思义,分别把log输出到控制台和文件。默认情况下(参见下面的默认配置文件),是使用 ConsoleHandler ,这就是为什么log默认会输出到命令行。

如果给Logger配置了多个Handler,则多个Handler同时生效,也就是说log可以既输出到控制台,同时也输出到文件。通过文件或者代码,都可以配置Handler。

事实上,Handler也可以设置级别(默认级别也是 INFO ),与Logger的级别相比,最终二者中较高的级别生效。这就解释了为什么把Logger级别设置为 WARNING 生效,而设置为 FINER 却不生效了,因为Handler的级别仍然是 INFO ,二者中 INFO 级别较高,因此 INFO 及以上级别生效。

要使 FINER 级别生效,需要把Handler的级别也设置成 FINER ,在上面的 comment 1 处添加代码:

        for (Handler handler : Logger.getLogger("").getHandlers()) {
            handler.setLevel(Level.FINER);
        }

再次运行程序,结果如下:

May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
FINER: finer
May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
FINE: fine
May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
CONFIG: config
May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
INFO: info
May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
WARNING: warning
May 09, 2022 7:09:44 PM pkg1.Test0509_3 main
SEVERE: severe

可见,这回 Finer 及以上级别生效了。

配置Log

文件配置

默认配置文件是 $JAVA_HOME/conf/logging.properties ,里面可以配置各种日志选项,比如:

  • handlers= java.util.logging.ConsoleHandler :设置Handler,若有多个Handler(比如 FileHandler ),handler之间用 , 隔开;
  • .level= INFO :默认的全局log级别;
  • java.util.logging.FileHandler.pattern = %h/java%u.log :文件日志的命名,其中 %h 表示home目录, %u 表示0、1、2这样的数字;
  • java.util.logging.FileHandler.limit = 50000 :文件日志的大小?
  • java.util.logging.FileHandler.count = 1 :文件日志的数量?
  • java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter :文件日志的格式
  • java.util.logging.ConsoleHandler.level = INFO :控制台日志的级别
  • java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter :控制台日志的格式
  • ……

例如:把 java.util.logging.ConsoleHandler.level = INFO 改为 java.util.logging.ConsoleHandler.level = SEVERE 。再次运行程序,结果如下:

May 09, 2022 3:31:25 PM pkg1.Test0509 main
SEVERE: severe

注意:配置文件里Handler的级别为 SEVERE ,而代码里Logger级别设置为 WARNING ,二者相比,级别较高者生效。

如果要使用自定义配置文件,需要在运行程序时,指定 java.util.logging.config.file 选项。比如 java -Djava.util.logging.config.file=myfile

最后别忘了还原默认配置文件。

代码配置

前面我们已经试过在代码中设置log级别,下面我们再看看其它配置。比如添加一个 FileHandler

        ......
        try {
            Handler handler = new FileHandler();
            // handler.setLevel(Level.INFO);
            logger.addHandler(handler);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        
        logger.setLevel(Level.WARNING);

        logger.finest("finest");
        logger.finer("finer");
        logger.fine("fine");
        logger.config("config");
        logger.info("info");
        logger.warning("warning");
        logger.severe("severe");
        ......

运行程序,除了命令行输出结果以外,在home目录下生成 java0.log 文件(这是默认的log文件路径和命名),内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2022-05-09T07:51:05.215198475Z</date>
  <millis>1652082665215</millis>
  <nanos>198475</nanos>
  <sequence>0</sequence>
  <logger>pkg1.Test0509</logger>
  <level>WARNING</level>
  <class>pkg1.Test0509</class>
  <method>main</method>
  <thread>1</thread>
  <message>warning</message>
</record>
<record>
  <date>2022-05-09T07:51:05.265971919Z</date>
  <millis>1652082665265</millis>
  <nanos>971919</nanos>
  <sequence>1</sequence>
  <logger>pkg1.Test0509</logger>
  <level>SEVERE</level>
  <class>pkg1.Test0509</class>
  <method>main</method>
  <thread>1</thread>
  <message>severe</message>
</record>
</log>

可见,对于log文件和命令行log,都是 WARNINGSEVERE 级别的log生效,只不过两种log的格式不同。

如果要指定文件路径和文件名,只需在创建 FileHandler 时指定,比如:

Handler handler = new FileHandler("aaa.log");

现在运行程序,就会在当前目录下生成 aaa.log 文件。注意,在本例中,当前目录指的是项目的根目录。

注意代码中被注释那一行。如果Handler没有设置级别,默认级别是 INFO ,与Logger级别 WARNING 相比,取较高的 WARNING 。如果设置了级别,则二者中级别较高者生效:

  • handler.setLevel(Level.SEVERE); :Handler中 SEVERE 级别生效;
  • handler.setLevel(Level.INFO); :Logger中 WARNING 级别生效;

参考

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:16:32  更:2022-05-10 12:17:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 15:41:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码