简单介绍:
Logger 对象用来记录特定系统或应用程序组件的日志消息。一般使用圆点分隔的层次名称空间来命名 Logger。Logger 名称可以是任意的字符串,但是它们一般应该基于被记录组件的包名或类名,如 java.net 或 javax.swing。此外,可以创建“匿名”的 Logger,其名称未存储在 Logger 名称空间中。
可通过调用某个 getLogger 工厂方法来获得 Logger 对象。这些方法要么创建一个新 Logger,要么返回一个合适的现有 Logger。
日志消息被转发到已注册的 Handler 对象,该对象可以将消息转发到各种目的地,包括控制台、文件、OS 日志等等。
每个 Logger 都跟踪一个“父”Logger,也就是 Logger 名称空间中与其最近的现有祖先。
每个 Logger 都有一个与其相关的 "Level"。这反映了此 logger 所关心的最低 Level。如果将 Logger 的级别设置为 null,那么它的有效级别继承自父 Logger,这可以通过其父 Logger 一直沿树向上递归得到。
可以根据日志配置文件的属性来配置日志级别,在 LogManager 类的描述中对此有所说明。但是也可以通过调用 Logger.setLevel 方法动态地改变它。如果日志级别改变了,则此变化也会影响它的子 logger,因为任何级别为 null 的子 logger 的有效级别都继承自它的父 Logger。
对于每次日志记录调用,Logger 最初都依照 logger 的有效日志级别对请求级别(例如 SEVERE 或 FINE)进行简单的检查。如果请求级别低于日志级别,则日志记录调用将立即返回。
通过此初始(简单)测试后,Logger 将分配一个 LogRecord 来描述日志记录消息。接着调用 Filter(如果存在)进行更详细的检查,以确定是否应该发布该记录。如果检查通过,则将 LogRecord 发布到其输出 Handler。在默认情况下,logger 也将 LogRecord 沿树递推发布到其父 Handler。
每个 Logger 都有一个与其关联的 ResourceBundle 名称。该指定的包用于本地化日志消息。如果一个 Logger 没有自己的 ResourceBundle 名称,则它将通过其父 Logger 沿树递归继承到 ResourceBundle 名称。
大多数 logger 输出方法都带有 "msg" 参数。此 msg 参数可以是一个原始值,也可以是一个本地化的键。在格式化期间,如果 logger 具有(或继承)一个本地化 ResourceBundle,并且 ResourceBundle 包含 msg 字符串的映射关系,那么用本地化值替换 msg 字符串。否则使用原来的 msg 字符串。通常,格式器使用 java.text.MessageFormat 形式的格式来格式化参数,例如,格式字符串 "{0} {1}" 将两个参数格式化为字符串。
将 ResourceBundle 名称映射到 ResourceBundle 时,Logger 首先试图使用该线程的 ContextClassLoader。如果 ContextClassLoader 为 null,则 Logger 将尝试 SystemClassLoader。作为初始实现中的临时过渡功能,如果 Logger 无法从 ContextClassLoader 或 SystemClassLoaderis 中找到一个 ResourceBundle,则 Logger 将会向上搜索类堆栈并连续调用 ClassLoader 来试图找到 ResourceBundle(此调用堆栈搜索是为了允许容器过渡到使用 ContextClassLoader,该功能可能在以后版本中取消)。
格式化(包括本地化)是输出 Handler 的责任,它通常会调用格式器。
注意,格式化不必同步发生。它可以延迟,直到 LogRecord 被实际写入到外部接收器。
日志记录方法划分为 5 个主要类别:
-
一系列的 "log" 方法,这种方法带有日志级别、消息字符串,以及可选的一些消息字符串参数。
-
一系列的 "logp" 方法(即 "log precise"),其与 "log" 方法相似,但是带有显式的源类名称和方法名称。
-
一系列的 "logrb" 方法(即 "log with resource bundle"),其与 "logp" 方法相似,但是带有显式的在本地化日志消息中使用的资源包名称。
-
还有跟踪方法条目("entering" 方法)、方法返回("exiting" 方法)和抛出异常("throwing" 方法)的便捷方法。
-
最后,还有一系列在非常简单的情况下(如开发人员只想为给定的日志级别记录一条简单的字符串)使用的便捷方法。这些方法按标准级别名称命名("severe"、"warning"、"info" 等等),并带有单个参数,即一个消息字符串。
对于不带显式源名和方法名的方法,日志记录框架将尽可能确定日志记录方法中调用了哪个类和方法。但是应认识到,这样自动推断的信息可能只是近似的,甚至可能是完全错误的。这是因为允许虚拟机在 JIT 编译时可以进行广泛的优化,并且可以完全移除栈帧,导致它无法可靠地找到调用的类和方法。
Logger 上执行的所有方法都是多线程安全的。
子类化信息:注意,对于名称空间中的任意点,LogManager 类都可以提供自身的指定 Logger 实现。因此,Logger 的任何子类(它们与新的 LogManager 类一起实现的情况除外)要注意应该从 LogManager 类获得一个 Logger 实例,并应该将诸如 "isLoggable" 和 "log(LogRecord)" 这样的操作委托给该实例。注意,为了截取所有的日志记录输出,子类只需要重写 log(LogRecord) 方法。所有其他日志记录方法作为在此 log(LogRecord) 方法上的调用而实现。
基础功能实现:
Logger log = Logger.getLogger("lavasoft"); log.setLevel(Level.ALL); System.out.println("日志级别是"+log.getLevel()); log.finest("log finest"); log.finer("log finer"); log.fine("log fine"); log.info("log info"); log.warning("log warning"); System.out.println("父日志"+log.getParent().getName());
复杂功能:
public static void main(String[] args) { //"javasoft"是"javasoft.blog"的父,这是规定,原理是:命名空间问题 Logger log1 = Logger.getLogger("javasoft"); log1.setLevel(Level.ALL); //log1是log的父日志,如果子日志没有设置Level,默认继承父level,如果没有绑定**Handler,默认继承父日志绑定的Handler Logger log = Logger.getLogger("javasoft.blog"); ConsoleHandler consoleHandler = new ConsoleHandler(); FileHandler filehandler = null; try { filehandler = new FileHandler("log.xml"); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } log1.addHandler(consoleHandler); log1.addHandler(filehandler); filehandler.setLevel(Level.WARNING); consoleHandler.setLevel(Level.FINE); System.out.println("日志级别是"+log.getLevel()); log.finest("log finest"); log.finer("log finer"); log.fine("log fine"); log.info("log info"); log.warning("log warning"); System.out.println("父logger:"+log.getParent().getName()); System.out.println("父logger:"+log.getParent().getParent().getName()); System.out.println(log.getParent().getParent()==log1); }
相关推荐
本篇将深入探讨如何利用JDK自带的日志包进行简单的日志应用。 首先,`java.util.logging.Logger`是日志系统的核心类,用于创建和管理日志消息。每个类都可以拥有自己的`Logger`实例,通过`Logger.getLogger()`方法...
本篇文章将详细介绍如何简单地建立数据连接池以及如何使用JDK自带的日志功能。 首先,我们来了解数据连接池的基本原理。数据连接池,如Apache的Commons DBCP、C3P0或HikariCP,它们预先创建一定数量的数据库连接,...
本示例将重点讨论如何使用JDBC API和JDK自带的日志系统进行简单的数据库连接池配置。 首先,数据库连接池的基本工作原理是预先创建一定数量的数据库连接,并存储在一个池中。当应用需要连接数据库时,它会从池中...
- **JDK自带的日志(JUL, Java Util Logging)**: - 内置于标准JDK中。 - 功能相对简单,易于上手。 - 在早期Java应用中较为常见。 - 配置和扩展性有限。 - **Log4j1**: - 由Apache基金会维护的开源项目。 ...
- **JdkLogger Class**:实现 `Log` 接口的一个具体实现,利用 Java SDK 内置的 `java.util.logging.Logger` 类进行日志记录。 - **LogFactory Abstract Class**:提供了获取 `Log` 实例的方法,并负责选择和配置...
Java原生日志工具Logger是JDK自带的日志处理工具,位于java.util.logging包中。它提供了一个灵活的日志处理机制,允许开发者自定义日志的输出级别、输出目标和格式。 日志级别是可以动态设置的,开发者可以根据需要...
用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。当然,common-logging内部有一个Simple logger的...
- **简介**:JUL是Java自带的日志框架,无需引入额外的依赖,适合于简单的日志记录需求。 - **主要组件**: - **Logger**:日志记录器,通过它来发布日志信息。 - **Handler**:负责处理日志的输出,如控制台...
1. 使用JDK自带的日志系统: 将`slf4j-api-1.5.10.jar`和`slf4j-jdk14-1.5.10.jar`添加到类路径中,程序会使用JDK的日志系统。运行后,日志将以JDK的标准格式输出。 2. 使用SLF4J的简单日志: 将`slf4j-api-...
这是Java标准库中自带的日志系统,简单易用。它的主要优点在于无需额外引入依赖,缺点是功能相对有限,不支持复杂的配置和日志级别控制。例如,`java.util.logging.Logger`类提供了基础的日志记录功能,但其灵活性和...
尽管Java Development Kit (JDK) 自带了基础的日志库,但通常开发者会选择第三方的日志框架,如Log4j、SLF4j和LogBack,以获得更强大的功能和灵活性。 SLF4J(Simple Logging Facade for Java)是一个为各种日志API...
Java Logging API是Java平台自带的日志记录工具,自JDK 1.4版本起开始提供。主要由`java.util.logging.*`包中的类和接口组成。日志的核心概念包括: 1. **Logger**:这是记录日志的主要对象,负责生成和管理日志...
在Java世界里,有多种日志框架可供选择,其中包括Jakarta Commons Logging(JCL)、JDK 1.4自带的Logger以及广泛使用的Log4j。下面将详细阐述这些日志工具的使用方法。 1. **Jakarta Commons Logging (JCL)** JCL...
本篇文章旨在详细介绍如何在Java中使用Log4j来管理日志,包括其配置方法以及与其他日志框架(如Commons Logging和JDK自带Logger)的对比。 #### 二、Jakarta Commons Logging (JCL) ##### 2.1 概述 Jakarta ...
- **Logger**: 方便的日志记录工具。 - **Android ButterKnife Zelezny**: 提升 ButterKnife 使用体验的插件。 - **Android Parcelable code generator**: 自动生成 Parcelable 接口实现代码。 - **GsonFormat**...
Java Logging API 是 Java Development Kit (JDK) 提供的一套标准日志记录工具,自 JDK 1.4 版本起得到支持。主要组件包括: - **Logger**:负责记录日志的对象,提供一系列方法用于记录不同级别的日志信息。 - **...
4. **JDK自带日志**:如果上述条件均不满足,则检查JDK版本是否支持日志记录功能(通常从JDK 1.4开始提供),如果是,则使用JDK自带的日志实现。 5. **SimpleLog**:最后,如果上述所有选项都不可用,则使用Commons-...