Logger日志记录


Java 日志记录简介

日志是软件应用程序中的记录信息,我们可以选择将其保存到文件中,或显示在控制台上。这些记录可以描述任何内容:程序中的一个事件、变量的值、错误或异常等。日志主要用于调试目的。

今天,我们将学习 Java 标准 SDK 中用于日志记录的 java.util.logging 包。要使用 Java 的日志功能,你需要了解以下几个组件:

  • Logger

  • FileHandler

  • ConsoleHandler

  • SimpleFormatter

  • XMLFormatter

  • Level

  • LogRecord

  • LogManager

在本主题中,我们将重点介绍前六个组件,并学习 Logger、Handler、Filter 和 Formatter 是如何协同工作的。


Logger 类

Logger 是整个日志系统中最核心的组件。标准做法是:为每一个类创建一个对应的 Logger 实例。

Logger 提供了多种记录日志的方法,其中 log() 是最基本的一种。来看一个简单示例:

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

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val logger = Logger.getLogger(Main::class.java.name)
        logger.log(Level.WARNING, "Hello " + logger.name)
    }
}

解释:

  • 创建了一个 Logger 实例,名称为 Main 类的名字。

  • 使用 log() 方法记录一条日志。

  • 第一个参数是日志级别(Level),第二个是日志消息。

输出如下:

WARNING: Hello Main

日志级别(Level)

每条日志都对应一个级别。在上面的例子中是 WARNING。Java 默认的日志级别是 INFO

Java 中的日志级别,从严重到轻微如下:

日志级别(Level)中文含义说明
SEVERE严重错误表示严重的问题,程序可能会中断,例如系统崩溃、异常终止等。
WARNING警告表示可能的问题,程序可以继续运行,但可能会出错或存在风险。
INFO信息一般性的信息,表示程序正常运行过程中的关键信息,如启动、配置成功等。
CONFIG配置信息表示一些配置信息,通常在系统初始化或模块加载时记录。
FINE详细调试信息用于提供比 INFO 更细致的调试信息,开发调试时较为常见。
FINER更详细的调试信息更进一步的调试信息,用于跟踪程序内部流程。
FINEST最详细的调试信息提供最细致的调试信息,几乎包括所有可跟踪的操作。

Logger 还提供了快捷方法,比如 info()config() 等,不需要指定 Level 参数:

import java.util.logging.Logger

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val logger = Logger.getLogger(Main::class.java.name)
        logger.severe("Severe Log")
        logger.warning("Warning Log")
        logger.info("Info Log")
    }
}

输出示例:

2023年1月9日 上午9:26:04 Main main
SEVERE: Severe Log
2023年1月9日 上午9:26:04 Main main
WARNING: Warning Log
2023年1月9日 上午9:26:04 Main main
INFO: Info Log

Handlers 和 Formatters

在日志系统中,Handler 负责将日志信息输出到外部系统,如控制台或文件。

Java 提供了 Handler 抽象类,以及几个具体实现类,其中重要的两个是:

  • ConsoleHandler:将日志输出到控制台(默认是 System.err

  • FileHandler:将日志写入到指定文件中

每个 Handler 都可以搭配 Formatter 使用,用于设置输出格式:

  • SimpleFormatter:普通文本格式

  • XMLFormatter:XML 格式输出

示例:

import java.util.logging.FileHandler
import java.util.logging.Handler
import java.util.logging.Logger
import java.util.logging.XMLFormatter

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val logger = Logger.getLogger(Main::class.java.name)
        val fileHandler: Handler = FileHandler("default.log")
        logger.addHandler(fileHandler)
        fileHandler.formatter = XMLFormatter()
        logger.info("Info log message")
    }
}

这段代码会在当前目录下生成 default.log 文件,内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2023-01-09T07:29:56.688157Z</date>
  <millis>1673249396688</millis>
  <nanos>157000</nanos>
  <sequence>0</sequence>
  <logger>Main</logger>
  <level>INFO</level>
  <class>Main</class>
  <method>main</method>
  <thread>1</thread>
  <message>Info log message</message>
</record>
</log>

Filter(过滤器)

在开发中,我们往往会记录大量日志信息,但在运行时并不需要全部输出,以免浪费资源。这时候就可以用 Filter 来控制输出哪些日志。

例如,下面的 Filter 只允许 INFO 级别的日志被记录:

import java.util.logging.Filter
import java.util.logging.Level
import java.util.logging.LogRecord

class FilterExample : Filter {
    override fun isLoggable(record: LogRecord): Boolean {
        return record.level == Level.INFO
    }
}

使用这个 Filter 的示例:

import java.util.logging.Filter
import java.util.logging.Level
import java.util.logging.Logger

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val logger = Logger.getLogger(Main::class.java.name)
        val filter: Filter = FilterExample()
        logger.filter = filter
        logger.severe("Severe Log")
        logger.info("Info Log")
        logger.warning("Warning Log")
    }
}

输出结果:

202319日 上午9:36:42 Main main
INFO: Info Log

只有 INFO 级别的日志被打印出来,其他被过滤掉了。


总结

  • java.util.logging 是 Java SDK 自带的日志系统。

  • Logger 用于创建日志对象,通常每个类一个。

  • Handler 决定日志信息的输出方式,常用的有 ConsoleHandlerFileHandler

  • Formatter 用于设置日志格式,如 SimpleFormatterXMLFormatter

  • Filter 用于在运行时控制日志的输出内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值