Java自带日志工具java.util.logging.Logger-程序员宅基地

技术标签: java  program  后端  开发语言  

java.util.logging.Logger是JDK自带的日志工具类,从1.4版本开始就已经有了。由于log4j等开源的日志组件,这个Logger并没有太多展现机会。但在一些测试性的代码中,JDK自带的Logger比log4j等更方便。

创建Logger对象

要使用JDK的日志功能,首先要取得java.util.logging.Logger实例,这可以通过Logger类的两个静态getLogger()方法来取得:

static Logger getLogger(String name) 
        查找或创建一个logger。
static Logger getLogger(String name, String resourceBundleName)
        为指定子系统查找或创建一个logger。

name是Logger的名称,当名称相同时候,同一个名称的Logger只创建一个。

Logger的日志级别

全部定义在java.util.logging.Level里面。
各级别按降序排列如下:

  • SEVERE(最高值)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST(最低值)

此外,还有一个级别 OFF,可用来关闭日志记录。

使用级别 ALL 启用所有消息的日志记录。

Logger默认的级别是INFO,比INFO更低的日志将不显示。

比如下面这段代码:

package com.peterwanghao.samples.java.utils.java;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingDemo {
    
	public static void main(String[] args){
    
        Logger myLogger = Logger.getLogger("com.peterwanghao.LoggingDemo");
        
        myLogger.log(Level.SEVERE, "严重信息");
        myLogger.log(Level.WARNING, "警告信息");
        myLogger.log(Level.INFO, "一般信息");
        myLogger.log(Level.CONFIG, "设定方面的信息");
        myLogger.log(Level.FINE, "细微的信息");
        myLogger.log(Level.FINER, "更细微的信息");
        myLogger.log(Level.FINEST, "最细微的信息");
    }
}

它的执行结果如下,只看到3条日志信息:
默认日志级别

Logger的默认级别定义是在jre安装目录的lib下面logging.properties文件中。

# 缺省的全局级别.
.level= INFO

# 控制台级别
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

如果将控制台级别设置为ALL:

java.util.logging.ConsoleHandler.level = ALL

同时降低创建的Logger实例级别则可以显示出想要的内容:

package com.peterwanghao.samples.java.utils.java;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingDemo {
    
	public static void main(String[] args){
    
        Logger myLogger = Logger.getLogger("com.peterwanghao.LoggingDemo");

        myLogger.setLevel(Level.ALL);//设置级别为ALL,显示全部日志
        
        myLogger.log(Level.SEVERE, "严重信息");
        myLogger.log(Level.WARNING, "警告信息");
        myLogger.log(Level.INFO, "一般信息");
        myLogger.log(Level.CONFIG, "设定方面的信息");
        myLogger.log(Level.FINE, "细微的信息");
        myLogger.log(Level.FINER, "更细微的信息");
        myLogger.log(Level.FINEST, "最细微的信息");
    }
}

执行结果如下:
全部日志级别

输出媒介控制器Handler

如果不想修改系统配置文件logging.properties,可以自己创建ConsolerHandler,也就是将信息输出至控制台。在自建的ConsolerHandler中调整日志级别。

package com.peterwanghao.samples.java.utils.java;

import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingDemo {
    
	public static void main(String[] args){
    
        Logger myLogger = Logger.getLogger("com.peterwanghao.LoggingDemo");

        myLogger.setLevel(Level.ALL);
        
        ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setLevel(Level.ALL);
        myLogger.addHandler(consoleHandler);
        
        myLogger.log(Level.SEVERE, "严重信息");
        myLogger.log(Level.WARNING, "警告信息");
        myLogger.log(Level.INFO, "一般信息");
        myLogger.log(Level.CONFIG, "设定方面的信息");
        myLogger.log(Level.FINE, "细微的信息");
        myLogger.log(Level.FINER, "更细微的信息");
        myLogger.log(Level.FINEST, "最细微的信息");
    }
}

执行效果跟上面一样。

日志信息除了输出到控制台外,还可以写到日志文件里,使用java.util.logging.FileHandler 将信息输出到文件。

package com.peterwanghao.samples.java.utils.java;

import java.io.File;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingDemo {
    
	public static void main(String[] args){
    
        Logger myLogger = Logger.getLogger("com.peterwanghao.LoggingDemo");

        myLogger.setLevel(Level.ALL);
        
        ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setLevel(Level.ALL);
        myLogger.addHandler(consoleHandler);
        
        FileHandler fileHandler = null;
        try {
    
			String filePath = "E:\\" + File.separator + "logs";
			String logPath = "LoggingDemo.log";
			File fi = new File(filePath);
			if ((fi.exists()) && (fi.isDirectory())) {
    
				logPath = filePath + File.separator + logPath;
			} else if (!fi.exists()) {
    
				try {
    
					fi.mkdirs();
					logPath = filePath + File.separator + logPath;
				} catch (Exception localException) {
    
				}
			}
			fileHandler = new FileHandler(logPath, true);//true表示日志内容在文件中追加
			fileHandler.setLevel(Level.ALL);//级别为ALL,记录所有消息
			
			myLogger.addHandler(fileHandler);
			
		} catch (Throwable e) {
    
			System.out.println("创建文件失败!" + e.getMessage());
		}
        
        myLogger.log(Level.SEVERE, "严重信息");
        myLogger.log(Level.WARNING, "警告信息");
        myLogger.log(Level.INFO, "一般信息");
        myLogger.log(Level.CONFIG, "设定方面的信息");
        myLogger.log(Level.FINE, "细微的信息");
        myLogger.log(Level.FINER, "更细微的信息");
        myLogger.log(Level.FINEST, "最细微的信息");
    }
}

执行后会自动生成日志文件,内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2021-12-24T17:52:38</date>
  <millis>1640339558986</millis>
  <sequence>0</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>SEVERE</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>严重信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559068</millis>
  <sequence>1</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>WARNING</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>警告信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559074</millis>
  <sequence>2</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>INFO</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>一般信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559076</millis>
  <sequence>3</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>CONFIG</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>设定方面的信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559078</millis>
  <sequence>4</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>FINE</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>细微的信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559079</millis>
  <sequence>5</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>FINER</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>更细微的信息</message>
</record>
<record>
  <date>2021-12-24T17:52:39</date>
  <millis>1640339559080</millis>
  <sequence>6</sequence>
  <logger>com.peterwanghao.LoggingDemo</logger>
  <level>FINEST</level>
  <class>com.peterwanghao.samples.java.utils.java.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>最细微的信息</message>
</record>
</log>

不同的处理器可以设置不同的日志级别,接收不同的日志信息。

自定义Formatter

Formatter可以为日志信息做格式化处理。Formatter接受LogRecord,并将它转换为一个特定格式字符串。

默认提供了两种Formatter:
1.java.util.logging.SimpleFormatter:标准日志格式。

2.java.util.logging.XMLFormatter:XML形式的日志格式。

从上一节的例子可知,FileHandler的默认格式是java.util.logging.XMLFormatter,而ConsolerHandler的默认格式是java.util.logging.SimpleFormatter。

可自己设计想要的日志格式:

package com.peterwanghao.samples.java.utils.java;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class LoggingDemo {
    
	public static void main(String[] args){
    
        Logger myLogger = Logger.getLogger("com.peterwanghao.LoggingDemo");

        myLogger.setLevel(Level.ALL);
        
        ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setLevel(Level.ALL);
        myLogger.addHandler(consoleHandler);
        
        FileHandler fileHandler = null;
        try {
    
			String filePath = "E:\\" + File.separator + "logs";
			String logPath = "LoggingDemo.log";
			File fi = new File(filePath);
			if ((fi.exists()) && (fi.isDirectory())) {
    
				logPath = filePath + File.separator + logPath;
			} else if (!fi.exists()) {
    
				try {
    
					fi.mkdirs();
					logPath = filePath + File.separator + logPath;
				} catch (Exception localException) {
    
				}
			}
			fileHandler = new FileHandler(logPath, true);//true表示日志内容在文件中追加
			fileHandler.setLevel(Level.ALL);//级别为ALL,记录所有消息
			fileHandler.setFormatter(new Formatter() {
    
				private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

				public String format(LogRecord record) {
    
					StringBuilder sb = new StringBuilder();
					String dataFormat = this.sdf.format(Long.valueOf(record.getMillis()));
					sb.append(dataFormat).append(" ");
					sb.append("level:").append(record.getLevel()).append(" ");
					sb.append(record.getMessage()).append("\n");

					return sb.toString();
				}
			});
			myLogger.addHandler(fileHandler);
			
		} catch (Throwable e) {
    
			System.out.println("创建文件失败!" + e.getMessage());
		}
        
        myLogger.log(Level.SEVERE, "严重信息");
        myLogger.log(Level.WARNING, "警告信息");
        myLogger.log(Level.INFO, "一般信息");
        myLogger.log(Level.CONFIG, "设定方面的信息");
        myLogger.log(Level.FINE, "细微的信息");
        myLogger.log(Level.FINER, "更细微的信息");
        myLogger.log(Level.FINEST, "最细微的信息");
    }
}

执行效果如下:

2021-12-24 18:13:44 level:SEVERE 严重信息
2021-12-24 18:13:44 level:WARNING 警告信息
2021-12-24 18:13:44 level:INFO 一般信息
2021-12-24 18:13:44 level:CONFIG 设定方面的信息
2021-12-24 18:13:44 level:FINE 细微的信息
2021-12-24 18:13:44 level:FINER 更细微的信息
2021-12-24 18:13:44 level:FINEST 最细微的信息
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/peterwanghao/article/details/122133819

智能推荐

Java语法进阶及常用技术(三)--Maven项目管理-程序员宅基地

文章浏览阅读559次。Maven介绍Maven是项目管理工具,对软件项目提供构建与依赖管理。Maven是Apache下的Java开源项目。Maven为Java项目提供了统一的管理方式,已成为业界标准。Maven核心特性项目设置遵循统一的规则,保证不同开发环境的兼容性。强大的依赖管理,项目依赖组件自动下载、自动更新。可扩展的插件机制,使用简单,功能丰富。Maven的安装与配置安装Maven之前需要安装jdk1.8。从官网下载MavenMaven官网:https://maven.apache.org/bin

C#排序 访问指定下标_c# 获取list 下表-程序员宅基地

文章浏览阅读1.9k次。一、C #中Sort()函数的使用与C++中类似,C#中也有自己的Sort()函数,其使用方式:(列表List的排序使用方式)第一步:声明一个myComparer类,它继承自IComparer:class myComparer : IComparer<MyPoint>/*实现 IComparer<T> 接口中的 Compare 方法, ..._c# 获取list 下表

Python不可变序列类型--字符串-程序员宅基地

文章浏览阅读1.7w次,点赞16次,收藏17次。Python从入门到精通零基础入门篇

java中预处理PrepareStatement起到防止SQL注入的作用_java sql prepare的作用-程序员宅基地

文章浏览阅读1.1k次。大家都知道,java中JDBC中,有个预处理功能,这个功能一大优势就是能提高执行速度尤其是多次操作数据库的情况,再一个优势就是预防SQL注入,严格的说,应该是预防绝大多数的SQL注入。 用法就是如下边所示:[java] view plain copyString sql="update cz_zj_directpayment dp_java sql prepare的作用

Android AppWidget(桌面小部件-音乐播放动画)_小部件 使用帧动画-程序员宅基地

文章浏览阅读4.3k次,点赞6次,收藏13次。桌面小部件基础篇:Android AppWidget (桌面小部件)音乐播放 (动画实现) 一个音乐播放的柱状图(不会上传动图,自行脑补)思路方案:1,自定义View,widget 仅支持部分控件,自定义没用,我把自定义弄完了,才想起来。所以这个方案pass2,帧动画,直接使用ImageView,也不行,无法获取子控件属性,帧动画运行不了3,LayoutAnimat..._小部件 使用帧动画

Ubuntu18.04扩展屏幕(副屏幕)不显示 登录时数字键不开问题_ubuntu18.04双屏扩展-程序员宅基地

文章浏览阅读323次。2.在附加驱动选项卡中选择独显显卡的驱动(不知道选哪个就直接选最新的就行),点击应用,重启即可。1.登录界面输入密码是NumLock不开,每次都要手动按一下才能输入密码。2.HDMI扩展屏幕不显示,信号灯亮,但是没有画面。3.查看一下独显驱动装上没(也可以不看)1.打开软件和更新功能,_ubuntu18.04双屏扩展

随便推点

无人直播系统源码开发:功能、优势与开发方法探析-程序员宅基地

文章浏览阅读617次,点赞8次,收藏8次。本文介绍了无人直播系统的功能和优势,以及如何进行开发。无人直播系统能够实时采集、编码和传输视频流,支持弹幕互动,并具备实时性、互动性、灵活性和可扩展性等优势。开发无人直播系统的方法包括确定需求、设计系统架构、实现功能、部署上线和维护优化。通过定制开发无人直播系统,可以满足不同业务场景下的实时视频传输和互动需求,提供高质量的直播体验。_无人直播系统源码

windows10环境VS2017 编译Opencv和TensorFlow程序(cmake)-程序员宅基地

文章浏览阅读539次。嘿嘿,我刚上研一,体育方面的研究生,想做计算机视觉方面的课题,这几天都在配置opencv和tensorflow的环境,走了不少歪路,总结了一下。一、关于opencv源码的查看和编译:http://blog.csdn.net/poem_qianmo/article/details/21974023 这个网址介绍的很全。其中要注意的是:如果安装的是vs2017,那么current generato...

Android 设��默认浏览器后安装另外浏览器后默认浏览器功能修复-程序员宅基地

文章浏览阅读84次。在“设置”应用中,找到“应用程序”或“应用管理器”选项,然后找到默认浏览器应用。点击该应用,然后找到“存储”或“存储空间”选项,点击进入。在存储页面中,找到“清除数据”或“清除缓存”选项,并点击确认。在Android设备上,打开“设置”应用,并找到“应用程序”或“应用管理器”选项。点击该应用,然后找到“清除默认值”或“清除默认设置”的选项,并点击确认。在“设置”应用中,找到“应用程序”或“应用管理器”选项,然后找到另外一个浏览器应用。点击该应用,然后找到“清除数据”或“清除缓存”选项,并点击确认。

Ant Design vue自定义文件上传_ant design vue 上传-程序员宅基地

文章浏览阅读4.4k次。实际项目中,上传文件时实际可能需要传输一个token。方法一:1、查看vue antdesign文档https://vue.ant.design/components/upload-cn/2、使用customRequestcustomRequest 通过覆盖默认的上传行为,可以自定义自己的上传实现 Function3、定义customRequest,之前定义action行为会被覆盖,可以注释掉4、customRequest代码如下customRequest ._ant design vue 上传

C++ 学习路线:快速入门到进阶_c++学习路线-程序员宅基地

文章浏览阅读4.9k次,点赞12次,收藏92次。C/C++ 是一门底层、细粒度、功能强大、学习曲线陡峭的语言,掌握这门语言的程序员通常有着更长的生命周期以及更深的护城河。但入门门槛高也是不争的事实,这篇文章把C++学习划分为入门、进阶、深入三个阶段,每步提供相应的学习方法和资源,帮助大家更好地掌握这门语言。_c++学习路线

解决javaweb项目使用Tomcat服务在网页中的某些页面中的图片无法显示问题。_为啥单独打开html显示图片,用tomcat打开图片不显示-程序员宅基地

文章浏览阅读7.1k次,点赞5次,收藏16次。最近写了一个web项目,但在浏览器中测试,发现某些页面中的图片无法显示。原因是在加载页面时一些img标签或者css中的background-image请求了一些含有中文的图片。于是这个页面会自动向服务端发送请求获取资源,但是这个过程不会体现到地址栏的,是在后台操作的。例如我请求了一个index.html页面但是页面中有一个<img src="img/测试图片.png">标签。通过f..._为啥单独打开html显示图片,用tomcat打开图片不显示

推荐文章

热门文章

相关标签