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 用于在运行时控制日志的输出内容。

你可能感兴趣的:(开发语言,android,java,kotlin)