log4j 配置文件示例_Log4j2示例教程–配置,级别,附加程序

Apache Log4j2是Java应用程序广泛使用的日志框架,优于Log4j1.x。本文提供了一个Log4j2教程,涵盖其概述、架构、配置、级别、查询、附加程序、过滤器、布局等,帮助开发者理解如何在项目中有效利用Log4j2进行日志记录,提高生产环境的维护效率。
摘要由CSDN通过智能技术生成

log4j 配置文件示例

Welcome to the Apache Log4j2 Example Tutorial. If you ask an expert developer about the most annoying thing about an application, the answer might be related to logging. If there is no suitable logging in an application, maintenance will be a nightmare.

欢迎使用Apache Log4j2示例教程。 如果您向专家开发人员询问有关应用程序的最烦人的事情,答案可能与日志记录有关。 如果在应用程序中没有合适的日志记录,维护将是一场噩梦。

Most of the application go through Development testing, unit testing, integration testing. But when it comes to production, you will always face unique scenarios and exception. So the only way to figure out what happened in a specific case is to debug through the logs.

大多数应用程序都经过开发测试,单元测试,集成测试。 但是当涉及到生产时,您将始终面临独特的场景和例外。 因此,弄清楚在特定情况下发生了什么的唯一方法是通过日志进行调试。

Many frameworks provide some way of default logging, but it’s always best to go with the industry standard logging mechanism. Apache Log4j is one of the most widely used logging frameworks. Apache Log4j 2 is the next version, that is far better than Log4j.

许多框架都提供了某种默认日志记录方式,但是最好始终采用行业标准的日志记录机制。 Apache Log4j是使用最广泛的日志记录框架之一。 下一个版本是Apache Log4j 2,它比Log4j更好。

Log4j示例教程 (Log4j Example Tutorial)

In this Log4j2 Example Tutorial, you will learn how to get started with Apache Log4j2. We will also explore Log4j2 architecture, log4j2 configuration, log4j2 logging levels, appenders, filters and much more.

在此Log4j2示例教程中,您将学习如何开始使用Apache Log4j2 。 我们还将探索Log4j2体系结构,log4j2配置,log4j2日志记录级别,附加程序,过滤器等等。

  1. Log4j2 Overview

    Log4j2概述
  2. Log4j2 Architecture

    Log4j2架构
  3. Log4j2 Configuration

    Log4j2配置
  4. Log4j2 Levels

    Log4j2级别
  5. Log4j2 Lookups

    Log4j2查询
  6. Log4j2 Appenders

    Log4j2 Appenders
  7. Log4j2 Filters

    Log4j2过滤器
  8. Log4j2 Layouts

    Log4j2布局
  9. Which Log4j2 Level should you use

    您应该使用哪个Log4j2级别
  10. Log4j2 Tutorial Summary

    Log4j2教程摘要

Log4j2概述 (Log4j2 Overview)

Using Logging API in application isn’t a luxury, it’s a must have. Log4j is an open source library that’s published and licensed under Apache Software.

在应用程序中使用Logging API并非奢侈,这是必须的。 Log4j是一个开放源代码库,已在Apache Software下发布并获得许可。

You can debug an application using Eclipse Debugging or some other tools, but that is not sufficient and feasible in a production environment.

您可以使用Eclipse Debugging或其他一些工具来调试应用程序,但这在生产环境中还不够可行。

Logging mechanism will provide you several benefits that you will not find in normal debugging.

日志记录机制将为您提供一些普通调试中找不到的好处。

Category / Operation (Debugging, Logging)DebuggingLogging
Human InterventionThere’s a need for human interventionNo need for human intervention
Persistent MediumCan’t be integrated with persistent storageCan be integrated with persistent storage (Files, Database, NoSQL database, etc.)
May used for AuditingCan’t be used for achieving auditingCan be used for achieving auditing if it’s used efficiently
Sufficient for complicated structure and flowNot sufficient; you may get lost with flow.Sufficient
ProductivityLess productiveMore productive
类别/操作(调试,记录) 调试 记录中
人为干预 需要人工干预 无需人工干预
持久介质 不能与持久性存储集成 可以与持久性存储(文件,数据库,NoSQL数据库等)集成
可用于审核 不能用于实现审核 如果有效利用,可用于实现审核
足以应付复杂的结构和流程 不够 您可能会迷失方向。 足够
生产率 生产力较低 更高产

As you can see above, using of logging mechanism will be more efficient with less maintenance cost.

正如您在上面看到的,使用日志记录机制将更有效,维护成本也更少。

Apache Log4j is the front runner tool for logging in Java applications, so you should use it.

Apache Log4j是用于登录Java应用程序的领先工具,因此您应该使用它。

Log4j2架构 (Log4j2 Architecture)

Before we proceed for Log4j Example tutorial, it’s good to look into Log4j2 architecture. Below image shows the important classes in Log4j2 API.

在继续进行Log4j示例教程之前,最好先研究一下Log4j2体系结构。 下图显示了Log4j2 API中的重要类。

Here’s the detailed explanation for the architecture shown above:

这是上面显示的体系结构的详细说明:

  • Applications will ask LogManager for a Logger with a specific name.

    应用程序将向LogManager询问具有特定名称的Logger
  • LogManager will locate the appropriate LoggerContext and then obtain Logger from it.

    LogManager将找到适当的LoggerContext ,然后从中获取Logger
  • If the Logger isn’t created yet, it will be created and associated with LoggerConfig according to three choices below:
    1. Logger instance will be created and associated with the LoggerConfig that have the same name. For example App.class in getLogger(App.class) will be evaluated to be a String com.journaldev.App. LoggerConfig name is identical to fully qualified class name (Software component).
    2. Logger instance will be created and associated with the LoggerConfig that have the same Loggers parent package. For example com.journaldev in getLogger("com.journaldev")
    3. Logger instance will be created and associated with the Root LoggerConfig. Root LoggerConfig will be used when there is no configuration file or when you’re obtaining a logger with name not defined in the logger declarations.

    如果尚未创建Logger,则会根据以下三个选择创建它并将其与LoggerConfig关联:
    1. 将创建具有相同名称的Logger实例并将其与LoggerConfig关联。 例如, getLogger(App.class)中的getLogger(App.class)将被评估为String com.journaldev.App 。 LoggerConfig名称与完全限定的类名称(软件组件)相同。
    2. 将创建具有相同Loggers父程序包的Logger实例并将其与LoggerConfig关联。 例如com.journaldev getLogger("com.journaldev")
    3. 将创建Logger实例并将其与Root LoggerConfig关联。 当没有配置文件或获取名称未在记录器声明中定义的记录器时,将使用Root LoggerConfig。
  • LoggerConfig objects are created from Logger declaration in the configuration file. LoggerConfig is also used to handle LogEvents and delegate them for their defined Log4j2 Appenders.

    LoggerConfig对象是根据配置文件中的Logger声明创建的。 LoggerConfig还用于处理LogEvents并将它们委派给已定义的Log4j2 Appender
  • Root logger is an exceptional case, in terms of its existence. It always exists and at the top of any logger hierarchy.

    就其存在而言,根记录器是一个特例。 它始终存在,并且在任何记录器层次结构的顶部。
  • You may obtain the root logger by using the below statements:
    Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    Logger logger = LogManager.getRootLogger();

    您可以使用以下语句获取root记录器:
  • The name of log4j2 loggers are case sensitive.

    log4j2记录器的名称区分大小写。
  • Except root logger, all loggers can be obtained through passing their name into LogManager.getLogger().

    除根记录程序外,所有记录程序都可以通过将其名称传递到LogManager.getLogger()来获得。
  • LoggerContext is a vocal point for Logging system as you may have multiple LoggerContexts inside your application. Per each LoggerContext an active configuration should be set.

    LoggerContext是Logging系统的主角,因为您的应用程序内部可能有多个LoggerContext。 对于每个LoggerContext,应设置一个活动配置。
  • Log4j2 configuration contains all Logging system assets; LoggerConfig(s), Appender(s), Filter(s) and many others.

    Log4j2配置包含所有Logging系统资产; LoggerConfig,Appender,过滤器等。
  • Calling of LogManager.getLogger() by passing the same name will always return the reference for the exact same logger instance.

    通过传递相同的名称来调用LogManager.getLogger()将始终返回完全相同的记录器实例的引用。
  • Configuration of Logging system is typically done with the application initialization. This can take different forms; programmatically or by reading a log4j2 configuration file.

    日志记录系统的配置通常通过应用程序初始化完成。 这可以采取不同的形式。 以编程方式或通过读取log4j2配置文件。

Every logger is associated with a LoggerConfig object, set of LoggerConfig objects made up a Hierarchy of loggers. This concept is known as Logger Hierarchy.

每个记录器都与一个LoggerConfig对象相关联,LoggerConfig对象集构成了一个记录器层次结构。 这个概念称为Logger层次结构

Logger Hierarchy is made up of set of LoggerConfig objects with a parent-child relationship. The topmost element in every Logger Hierarchy is the Root Logger.

Logger层次结构由一组具有父子关系的LoggerConfig对象组成。 每个Logger层次结构中最顶层的元素是Root Logger。

If Log4j2 doesn’t find the configuration file, only Root Logger will be used for logging with logging level as ERROR. Below image shows the warning message you will get in this case.

如果Log4j2找不到配置文件,则仅将Root Logger用于日志记录级别为ERROR的日志记录。 下图显示了在这种情况下将收到的警告消息。

Error StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

错误StatusLogger未找到log4j2配置文件。 使用默认配置:仅将错误记录到控制台。

The table below shows the parent-child relationship in the Logger Hierarchy.

下表显示了Logger层次结构中的父子关系。

LoggerConfig (Is A)Rootcomcom.journaldevcom.journaldev.logging
RootXChilddescendantdescendant
comParentXChilddescendant
com.journaldevAncestorParentXChild
com.journaldev.loggingAncestorAncestorParentX
LoggerConfig(是A) com com.journaldev com.journaldev.logging
X 儿童 后裔 后裔
com 父母 X 儿童 后裔
com.journaldev 祖先 父母 X 儿童
com.journaldev.logging 祖先 祖先 父母 X

To clarify Parent-Child relationship, table above would be read as follows:

为了阐明父子关系,上表的内容如下:

  • Root is a parent for com.

    根是com的父代。
  • Root is an ancestor for com.journaldev.

    Root是com.journaldev的祖先。
  • Root is an ancestor for com.journaldev.logging.

    Root是com.journaldev.logging的祖先。
  • com is a child for Root.

    com是Root的孩子。
  • com is a parent for com.journaldev.

    com是com.journaldev的父级。
  • com is an ancestor for com.journaldev.logging.

    com是com.journaldev.logging的祖先。
  • com.journaldev.logging is a child for com.journaldev and so on.

    com.journaldev.logging是com.journaldev的子级,依此类推。

An instance of LoggerConfig is said to be an ancestor of another LoggerConfig; if its name followed by a dot is a prefix for the descendant name.

LoggerConfig的一个实例被称为是另一个LoggerConfig的祖先。 如果其名称后跟一个点,则为后代名称的前缀。

An instance of LoggerConfig is said to be a parent for another LoggerConfig; if there are no interleaving names between both of them.

LoggerConfig的一个实例被称为另一个LoggerConfig的父级; 如果两者之间没有交错的名称。

Log4j2配置 (Log4j2 Configuration)

There are many ways to use Log4j2 configuration in you application.

应用程序中有多种使用Log4j2配置的方法。

  1. Using a configuration file written in XML, JSON, YAML or properties file.

    使用以XML,JSON,YAML或属性文件编写的配置文件。
  2. Programmatically, by creating a configuration factory and configuration implementation.

    通过创建配置工厂和配置实现以编程方式。
  3. Programmatically, by calling APIs exposed in the configuration interface.

    通过调用配置界面中公开的API,以编程方式进行。
  4. Programmatically, by calling methods on the internal logger class.

    通过调用内部记录器类上的方法以编程方式。

We will focus mainly on the configuration file. However, it’s good to know the programming approach too, in case you want to configure a specific logging strategy for some specific Logger.

我们将主要关注配置文件。 但是,如果您想为某些特定的Logger配置特定的日志记录策略,也应该了解编程方法。

First of all, let’s consider the case where you didn’t provide a configuration file. Log4j2 implementation assumes that there is a System variable called log4j.configurationFile to point the location of log4j2 configuration file.

首先,让我们考虑一下您没有提供配置文件的情况。 Log4j2实现假定有一个名为log4j.configurationFile的系统变量来指向log4j2配置文件的位置。

package com.journaldev;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App
{
    public static void main( String[] args ) {
    	Logger logger = LogManager.getRootLogger();
    	logger.trace("Configuration File Defined To Be :: "+System.getProperty("log4j.configurationFile"));
    }
}

A simple log4j2 configuration file will look like below.

一个简单的log4j2配置文件如下所示。

configuration.xml:

configuration.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

And here is the detailed explanation for the code listed above:

这是上面列出的代码的详细说明:

  • App has referenced the Root logger by calling LogManager getRootLogger method.

    应用程序通过调用LogManager getRootLogger方法引用了Root记录器。
  • Referencing of logger from LogManager has started Log4j system.

    从LogManager引用记录器已启动Log4j系统。
  • Log4j will inspect log4j.configurationFile system property to determine log4j2 configuration file. Log4j configuration can be written in JSON, YAML and XML.

    Log4j将检查log4j.configurationFile系统属性以确定log4j2配置文件。 Log4j配置可以用JSON,YAML和XML编写。
  • We can set log4j.configurationFile system property through System.setProperties("log4j.configurationFile","FILE_PATH") or by passing it as a JVM parameter like you see in the figure below. Notice also File protocol prefix.

    我们可以通过System.setProperties("log4j.configurationFile","FILE_PATH")或通过将其作为JVM参数传递来设置log4j.configurationFile系统属性System.setProperties("log4j.configurationFile","FILE_PATH")如下图所示。 还要注意文件协议前缀。
  • In case no system property is defined the configuration order takes below precedence:
    • Property ConfigurationFactory will look for log4j2-test.properties in the classpath.
    • YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.
    • JSON ConfigurationFactory will look for log4j2-test.jsn or log4j2-test.json in the classpath.
    • XML ConfigurationFactory will look for log4j2-test.xml in the classpath.
    • Property ConfigurationFactory will look for log4j2.properties on the classpath
    • YAML ConfigurationFactory will look for log4j2.yml or log4j2.yaml in the classpath.
    • JSON ConfigurationFactory will look for log4j2.jsn or log4j2.json in the classpath.
    • XML ConfigurationFactory will look for log4j2.xml in the classpath.
    • If no configuration file was provided, the DefaultConfiguration takes place and that would lead you for set of default behaviors:
      • Root logger will be used.
      • Root logger level will be set to ERROR.
      • Root logger will propagate logging messages into console.
      • PatternLayout is set to be %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n

    如果未定义系统属性,则配置顺序优先于以下内容:
    • 属性ConfigurationFactory将在类路径中查找log4j2-test.properties
    • YAML ConfigurationFactory将在类路径中查找log4j2-test.yamllog4j2-test.yml
    • JSON ConfigurationFactory将在类路径中查找log4j2-test.jsnlog4j2-test.json
    • XML ConfigurationFactory将在类路径中查找log4j2-test.xml
    • 属性ConfigurationFactory将在类路径上查找log4j2.properties
    • YAML ConfigurationFactory将在类路径中查找log4j2.ymllog4j2.yaml
    • JSON ConfigurationFactory将在类路径中查找log4j2.jsnlog4j2.json
    • XML ConfigurationFactory将在类路径中查找log4j2.xml
    • 如果没有提供配置文件,则会发生DefaultConfiguration ,这将导致您进行默认行为设置:
      • 将使用根记录器。
      • 根记录器级别将设置为ERROR
      • 根记录器会将记录消息传播到控制台。
      • PatternLayout设置为%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n

Using log4j2 configuration file makes the log4j2 configuration so simple, but let’s see how we can configure it programmatically. This is all about using ConfigurationFactory.

使用log4j2配置文件使log4j2的配置变得如此简单,但让我们看看如何以编程方式对其进行配置。 这就是使用ConfigurationFactory的全部内容。

package com.journaldev;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
public class App
{
    public static void main( String[] args ) throws FileNotFoundException, IOException {
 
    	// Get instance of configuration factory; your options are default ConfigurationFactory, XMLConfigurationFactory,
    	// 	YamlConfigurationFactory & JsonConfigurationFactory
    	ConfigurationFactory factory =  XmlConfigurationFactory.getInstance();
 
    	// Locate the source of this configuration, this located file is dummy file contains just an empty configuration Tag
    	ConfigurationSource configurationSource = new ConfigurationSource(new FileInputStream(new File("C:/dummyConfiguration.xml")));
 
    	// Get a reference from configuration
    	Configuration configuration = factory.getConfiguration(configurationSource);
 
    	// Create default console appender
    	ConsoleAppender appender = ConsoleAppender.createDefaultAppenderForLayout(PatternLayout.createDefaultLayout());
 
    	// Add console appender into configuration
    	configuration.addAppender(appender);
 
    	// Create loggerConfig
    	LoggerConfig loggerConfig = new LoggerConfig("com",Level.FATAL,false);
 
    	// Add appender
    	loggerConfig.addAppender(appender,null,null);
 
    	// Add logger and associate it with loggerConfig instance
    	configuration.addLogger("com", loggerConfig);
 
    	// Get context instance
    	LoggerContext context = new LoggerContext("JournalDevLoggerContext");
 
    	// Start logging system
    	context.start(configuration);
 
    	// Get a reference for logger
    	Logger logger = context.getLogger("com");
 
    	// LogEvent of DEBUG message
    	logger.log(Level.FATAL, "Logger Name :: "+logger.getName()+" :: Passed Message ::");
 
    	// LogEvent of Error message for Logger configured as FATAL
    	logger.log(Level.ERROR, "Logger Name :: "+logger.getName()+" :: Not Passed Message ::");
 
    	// LogEvent of ERROR message that would be handled by Root
    	logger.getParent().log(Level.ERROR, "Root Logger :: Passed Message As Root Is Configured For ERROR Level messages");
    }
}
  • You may use any of ConfigurationFactory provided by Log4j2 or use the default one. We’ve used XMLConfigurationFactory to get an instance of ConfigurationFactory.

    您可以使用Log4j2提供的任何ConfigurationFactory或使用默认的。 我们使用XMLConfigurationFactory来获取ConfigurationFactory的实例。
  • Factory will give you an instance of required Configuration reference by passing the corresponding configuration file.

    工厂将通过传递相应的配置文件为您提供所需的配置参考实例。
  • Configuration instance will be used in conjunction with LoggerContext for starting the Logging System.

    配置实例将与LoggerContext结合使用以启动日志记录系统。
  • A console Appender has been configured and added into configuration instance with default layout. This Appender would print out messages into your console.

    已配置控制台Appender并以默认布局将其添加到配置实例中。 该Appender会将消息打印到控制台中。
  • LoggerConfig instance has been created with provided name, LEVEL and with no filter used. Created Appender will assigned for this instance of LoggerConfig.

    已使用提供的名称LEVEL创建了LoggerConfig实例,并且未使用任何过滤器。 将为该LoggerConfig实例分配创建的Appender。
  • LoggerConfig instance added into configuration instance.

    将LoggerConfig实例添加到配置实例中。
  • A new instance of LoggerContext is created with defined name.

    使用定义的名称创建LoggerContext的新实例。
  • The configuration instance has been passed for LoggerContext instance and invoked start upon the latter.

    已经为LoggerContext实例传递了配置实例,并从后者开始调用。
  • A logger instance has been acquired from LoggerContext. This logger instance will be used to fire set of Log events.

    已从LoggerContext获取记录器实例。 此记录器实例将用于触发Log事件集。
  • Logger instance has fired three events that would be explained in the Log4j2 Levels section.

    Logger实例触发了三个事件,这将在Log4j2 Levels部分中进行说明。
  • com logger has configured to print out messages whose levels are FATAL.

    com logger已配置为打印出致命级别的消息。
  • By default, Root logger is configured to print out messages whose levels is ERROR.

    默认情况下,根记录器配置为打印出级别为ERROR的消息。
  • ERROR messages will not be logged by ‘com’ logger because it’s level is FATAL.

    错误消息不会由“ com”记录器记录,因为它的级别为致命。

The same configuration can be done through using of YAML, JSON or properties file. However log4j2 property file configuration is different from the log4j property file, so make sure you are not trying to use the log4j property file configuration with log4j2. It will throw below error;

可以通过使用YAML,JSON或属性文件来完成相同的配置。 但是,log4j2属性文件的配置与log4j属性文件不同,因此请确保您不尝试将log4j属性文件配置与log4j2一起使用。 它将抛出以下错误;

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

While processing the above code would give you the below output:

在处理以上代码时,将为您提供以下输出:

Logger Name :: com :: Passed Message ::
00:01:27.705 [main] ERROR - Root Logger:: Passed Message As Root Is Configured For ERROR Level messages

The First line of logs is from com logger and the second is from the Root Logger. com logger error message is not printed because its level is Fatal.

第一行日志来自com logger,第二行来自Root Logger。 com logger错误消息未打印,因为其级别为致命。

Log4j2级别 (Log4j2 Levels)

You can see in above code examples that every time we define a LoggerConfig, we also provide logging level. By default log4j2 logging is additive. It means that all the parent loggers will also be used when a specific logger is used. Below image clarifies this situation.

您可以在上面的代码示例中看到,每次我们定义LoggerConfig时,我们还提供日志记录级别。 默认情况下,log4j2日志记录是累加的。 这意味着当使用特定的记录器时,还将使用所有父记录器。 下图阐明了这种情况。

And herein points of clarification for it:

在此需要澄清:

  • As we’ve stated earlier, each logger has associated with LoggerConfig instance. This loggerConfig has been defined at the configuration scope.

    如前所述,每个记录器都与LoggerConfig实例相关联。 此loggerConfig已在配置范围内定义。
  • Level of logging can be determined at the LoggerConfig scope.

    日志记录的级别可以在LoggerConfig范围内确定。
  • You may obtain the logger by its name, parent package or by pointing the Root Logger itself.

    您可以通过名称,父程序包或指向根记录器本身来获取记录器。
  • Root Logger is the top level node for every LoggerConfig hierarchy.

    根记录器是每个LoggerConfig层次结构的顶级节点。
  • Once you obtain the com.journaldev logger and initiate a logEvent for logging, the loggerConfig (net.journaldev) will log the message and the message will be propagated as well up in the hierarchy without any respect for parents logging levels. So log event will be propagated to com and Root loggers and they will also log the message respectively according to the levels defined.

    一旦获得com.journaldev记录器并启动logEvent进行记录,loggerConfig(net.journaldev)将记录该消息,并且该消息还将在层次结构中向上传播,而无需考虑父级记录级别。 因此,日志事件将传播到com和Root记录器,它们还将根据定义的级别分别记录消息。
  • Once you obtain the com logger and initiate a logEvent for logging, the loggerConfig(com) will log the message and the message will be propagated as well up in the hierarchy without any respect for parents’ logging levels. That is, Root logger will be propagated the log event and it also will log the message.

    获得com记录器并启动logEvent进行记录后,loggerConfig(com)将记录该消息,并且该消息也将在层次结构中向上传播,而无需考虑父级的记录级别。 也就是说,根记录器将传播日志事件,并且还将记录消息。
  • The same case for net.journaldev hierarchy.

    net.journaldev层次结构的情况相同。
  • Next sections, will add more clarifications for additive concept.

    在接下来的几节中,将为加性概念添加更多说明。
  • There’s a chance for the parent to ignore the message by using Filter concept or by setting the additive indicator to false, so log events will not be propagated to parents.

    父母可以通过使用筛选器概念或将添加指示器设置为false来忽略该消息,因此日志事件不会传播到父母。
  • There’s a chance for the logger to ignore the message if the respective loggerConfig’s level is GREATER THAN log events level.

    如果各个loggerConfig的级别大于日志事件级别,则记录器有可能忽略该消息。

Now, let’s see the example that’s associated with the concept of additivity explained above:

现在,让我们看一下与上述可加性概念相关的示例:

import net.NetApp;
import net.journaldev.NetJournalDevApp;
import com.ComApp;
import com.journaldev.ComJournalDevApp;
public class Main {
	public static void main(String [] args){
		new ComApp();
		new ComJournalDevApp();
		new NetApp();
		new NetJournalDevApp();
	}
}
package com.journaldev;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ComJournalDevApp {
	public ComJournalDevApp(){
		Logger logger = LogManager.getLogger(ComJournalDevApp.class);
		logger.trace("COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::");
	}
}
package net;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class NetApp {
	public NetApp(){
		Logger logger = LogManager.getLogger(NetApp.class);
		logger.error("NET :: LEVEL :: NetApp ERROR Message ::");
	}
}
package net.journaldev;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class NetJournalDevApp {
	public NetJournalDevApp(){
		Logger logger = LogManager.getLogger(NetJournalDevApp.class);
		logger.error("NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::");
	}
}

Whereas the log4j2 configuration file looks like below:

而log4j2配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  	<logger name="com" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net.journaldev" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  </Loggers>
</Configuration>

If you get Main class executed you would find the below results:

如果执行Main类,则会发现以下结果:

10:34:47.168 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
10:34:47.168 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
10:34:47.171 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
10:34:47.171 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

Here’s below detailed explanation for the code listed above:

以下是上面列出的代码的详细说明:

  • Configuration file contains five loggerConfig instances defined and they’re Root, com, com.journaldev, net & net.journaldev. Just like Logger Hierarchy shown above.

    配置文件包含定义的五个loggerConfig实例,它们分别是Root,com,com.journaldev,net和net.journaldev。 就像上面显示的Logger层次结构一样。
  • Root’s level is configured to be ERROR and that’s actually the default value.

    根级别配置为ERROR,而这实际上是默认值。
  • com & com.journaldev levels are configured to be TRACE.

    com&com.journaldev级别配置为TRACE。
  • net & net.journaldev levels are configured to be ERROR.

    net&net.journaldev级别配置为ERROR。
  • You may noticed that the ComAPP and ComJournalDevApp loggers messages have been shown two and three times respectively. These messages shown according to the Logger Hierarchy for ComApp & ComJournalDevApp where they’re in the com & com.journalDev packages respectively. We have similar case with NetApp & NetJournalDevApp classes.

    您可能会注意到,ComAPP和ComJournalDevApp记录器消息分别显示了两次和三次。 这些消息根据ComApp和ComJournalDevApp的Logger层次结构显示,它们分别位于com&com.journalDev程序包中。 对于NetApp和NetJournalDevApp类,我们也有类似的情况。
  • Parents are propagated as additive indicator is set to true by default.

    默认情况下,将加性指标设置为true来传播父级。

Logging Space takes into consideration Levels of log events and the loggerConfig’s level in addition to Logger Hierarchy.

除了Logger层次结构,Logging Space还考虑了日志事件的级别和loggerConfig的级别。

So what if we changed the LoggerConfig for com to be INFO and left the whole program as is:

因此,如果我们将com的LoggerConfig更改为INFO并将整个程序保留为原样,该怎么办:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  	<logger name="com" level="INFO">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net.journaldev" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  </Loggers>
</Configuration>

Then the result it would be like below:

那么结果将如下所示:

11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
11:08:10.307 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
11:08:10.307 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
  • For sure you may notice that the ComAPP log event has ignored and that is because of the defined level of loggerConfig for com package. INFO (400) level is less than log event’s level which is here TRACE(600). So, the message of ComApp won’t be shown anymore and to make it shown, you need to modify the LoggerConfig’s level for com to be TRACE(600) or ALL(Integer.MAX_VALUE).

    当然,您可能会注意到ComAPP日志事件已被忽略,这是由于com程序包的loggerConfig定义了级别。 INFO(400)级别小于日志事件的级别,即TRACE(600)。 因此,ComApp的消息将不再显示,并使其显示,您需要将Log的com的级别修改为TRACE(600)或ALL(Integer.MAX_VALUE)。

To make sure Log events have been displayed, the LoggerConfig’s Level should be greater than or equal to Log event’s level.

为了确保已显示日志事件,LoggerConfig的级别应大于或等于日志事件的级别。

Table below shows you the log4j2 Levels and the weight for each of them:

下表显示了log4j2级别和每个级别的权重:

LEVELWeight
OFF0
FATAL100
ERROR200
WARN300
INFO400
DEBUG500
TRACE600
ALLInteger.MAX_VALUE
水平 重量
0
致命 100
错误 200
警告 300
信息 400
调试 500
跟踪 600
所有 整数MAX_VALUE

For sure Table above clarifies much more than words and it gives you the main cause for being the Log event TRACE isn’t displayed while the LoggerConfig’s level is INFO.

可以肯定的是,上表对表的解释远不止于文字,它为您提供了一个主要原因,因为当LoggerConfig的级别为INFO时,没有显示日志事件TRACE。

Notice that the propagation of log events up in the logger hierarchy is beyond this computation and it ignores the levels.

请注意,日志事件在记录器层次结构中的传播不在此计算范围之内,它会忽略这些级别。

But what happens if we remove LoggerConfig of com.journaldev from the configuration and added a new one for com.journaldev.logging to make the configuration file looks like below:

但是,如果我们从配置中删除com.journaldev的LoggerConfig并为com.journaldev.logging添加了一个新文件以使配置文件如下所示,将会发生什么:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  	<logger name="com" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev.logging" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net.journaldev" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  </Loggers>
</Configuration>

You may find the figure below more convenient for you to understand what’s happened in the above log4j2 configuration.

您可能会发现下图更方便您了解上面的log4j2配置中发生的情况。

Here’s some clarification for the figure shown above and how it may affect the behavior of logging events:

这是对上面显示的图的一些说明,以及它如何影响日志记录事件的行为:

  • When log events have thrown by a Logger named com.journaldev.logging, the LoggerConfig that’s associated with that name (i.e. com.journaldev.logging) has been used to handle it and print out the message.

    当名为com.journaldev.logging的Logger引发了日志事件时,与该名称关联的LoggerConfig(即com.journaldev.logging)已用于处理它并打印出消息。
  • Being com.journaldev.logging LoggerConfig’s additive attribute is set by default to true, the log event has been propagated for the parent which’s in this case referring for com.journaldev.

    作为com.journaldev.logging的LoggerConfig的additive属性默认情况下设置为true,已经为父级传播了日志事件,在本例中是指com.journaldev。
  • Being com.journaldev LoggerConfig isn’t defined in the configuration, no action happens and the Log event will be propagated up to com and then Root LoggerConfig instances.

    由于未在配置中定义com.journaldev LoggerConfig,因此不会发生任何操作,并且Log事件将传播到com,然后传播到Root LoggerConfig实例。
  • Com & Root will receive the Log event and print it out regardless of the level it’s sent with.

    Com&Root将接收Log事件并将其打印出来,而不管其发送的级别如何。

As a result for the points mentioned, you would see the following outputs:

作为上述要点的结果,您将看到以下输出:

14:08:37.634 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
14:08:37.634 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
14:08:37.636 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
14:08:37.636 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:08:37.638 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:08:37.638 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

And you may notice the following:

您可能会注意到以下内容:

  • Log event at com package has been shown twice. One for com while second for Root.

    com软件包中的日志事件已显示两次。 一个用于com,第二个用于Root。
  • Log event at com.journaldev has been shown twice. One for com and second for Root. Even though it was three times before, but for now the LoggerConfig of com.journaldev is absent and so no logging might have happened at com.journaldev package and the event would be propagated for com and Root.

    com.journaldev的日志事件已显示两次。 一个用于com,第二个用于Root。 即使以前是3次,但现在com.journaldev的LoggerConfig不存在,因此com.journaldev软件包可能没有记录日志,并且该事件将传播给com和Root。
  • Log event at com.journaldev.logging has been shown three times, one for com.journaldev.logging package and second for com and third for Root. According to Logger Hierarchy propagation, it should be displayed forth times, but due to absence of com.jounraldev LoggerConfig, it displays three times.

    com.journaldev.logging的日志事件已显示三次,一次用于com.journaldev.logging软件包,第二次用于com,第三次用于Root。 根据Logger层次结构传播,应该将其显示四次,但由于缺少com.jounraldev LoggerConfig,因此它会显示三遍。

In case you’ve defined a com.journaldev LoggerConfig instance with no Level specified, it will inherit Level of its parent.

如果您定义了一个未指定Level的com.journaldev LoggerConfig实例,它将继承其父级的Level。

But what if you have defined com.journaldev LoggerConfig at your configuration file and missed out specifying the LoggerConfig’s level.

但是,如果您在配置文件中定义了com.journaldev LoggerConfig却错过了指定LoggerConfig级别的情况,该怎么办。

Fortunately, the concept of Logger Hierarchy will save you here and com.journaldev would inherit its level value from its parent. Below is a sample configuration file followed by the table for logging level of each logger config.

幸运的是,Logger层次结构的概念将在这里节省您的时间,而com.journaldev将从其父级继承其级别值。 以下是一个示例配置文件,后跟用于每个记录器配置的记录级别的表。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  	<logger name="com" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev.logging" level="TRACE">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net.journaldev" level="ERROR">
  		<AppenderRef ref="Console"/>
  	</logger>
  </Loggers>
</Configuration>
Logger NameAssigned LoggerConfigLoggerConfig LevelLogger Level
RootRootERRORERROR
comcomTRACETRACE
com.journaldevcomTRACETRACE
com.journaldev.loggingcom.journaldev.loggingTRACETRACE
记录仪名称 分配的LoggerConfig LoggerConfig级别 记录器级别
错误 错误
com com 跟踪 跟踪
com.journaldev com 跟踪 跟踪
com.journaldev.logging com.journaldev.logging 跟踪 跟踪
  • com.journaldev.logging package has already associated with a LoggerConfig with Log level TRACE.

    com.journaldev.logging软件包已与具有Log级别TRACE的LoggerConfig关联。
  • com.journaldev package has already associated with a LoggerConfig with no Log Level specified, so it would inherit its Parent Log Level and for sure the value would be TRACE for com package.

    com.journaldev软件包已经与未指定日志级别的LoggerConfig关联,因此它将继承其父日志级别,并确保该值将为com软件包的TRACE。
  • com package has already associated with Loggerconfig with log level TRACE.

    com软件包已与日志级别TRACE的Loggerconfig关联。
  • By default Root has ERROR as a log level.

    默认情况下,根将ERROR作为日志级别。
  • In case com package isn’t declared, com.journaldev LoggerConfig will inherit the log level of Root.

    如果未声明com软件包,则com.journaldev LoggerConfig将继承Root的日志级别。

Below is the result of execution while com.journaldev inherits com log level:

以下是com.journaldev继承com日志级别时的执行结果:

14:41:37.419 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
14:41:37.419 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
14:41:37.421 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
14:41:37.421 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
14:41:37.421 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
14:41:37.422 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:41:37.422 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:41:37.422 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:41:37.422 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:41:37.423 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:41:37.423 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:41:37.423 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:41:37.423 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:41:37.423 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

And below result would be if you remove declaring LoggerConfig for com package:

如果您删除为com包声明LoggerConfig的内容,则结果将如下所示:

14:43:28.809 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:43:28.809 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:43:28.809 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
14:43:28.811 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:43:28.811 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
14:43:28.812 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:43:28.812 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
14:43:28.812 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

You may notice that no messages have logged for com and com.journaldev, below are the reasons.

您可能会注意到com和com.journaldev没有消息记录,以下是原因。

  • Deletion of LoggerConfig associated with com package will make all Log events mentioned at that package to be ignored.

    与com软件包关联的LoggerConfig的删除将使在该软件包中提及的所有Log事件被忽略。
  • Since there’s no LoggerConfig defined for com package in the configuration, LoggerConfig that’s associated with com.journaldev will inherit Log Level from its parent. Com isn’t defined, and the Logger Hierarchy is reached to the Top and it’s referring now for Root. The root Log level is ERROR(200) and Log event’s level in com.journaldev is TRACE(600) – See ComJournalDevApp – and according to previous equation defined, LoggerConfig level should be greater than or equal to Log Event and that’s false, so no messages would be displayed here for com.journaldev.

    由于在配置中没有为com包定义LoggerConfig,因此与com.journaldev关联的LoggerConfig将从其父级继承Log Level。 未定义Com,并且Logger层次结构已到达顶部,并且现在是指Root。 根日志级别为ERROR(200),com.journaldev中的日志事件级别为TRACE(600)–请参阅ComJournalDevApp –根据先前定义的公式,LoggerConfig级别应大于或等于日志事件,并且为false,因此否将在此处显示com.journaldev的消息。

Last but not least, following below Table shows you all possible logging scenarios that you may face when using Logging system:

最后但并非最不重要的是,下表显示了使用日志记录系统时可能遇到的所有可能的日志记录方案:

X (N/A)LoggerConfig LevelOFF(0)FATAL(100)ERROR(200)WARN(300)INFO(400)DEBUG(500)TRACE(600)ALL(MAX)
Event LevelXXXXXXXXX
OFF(0)XYESNONONONONONONO
FATAL(100)XNOYESYESYESYESYESYESYES
ERROR(200)XNONOYESYESYESYESYESYES
WARN(300)XNONONOYESYESYESYESYES
INFO(400)XNONONONOYESYESYESYES
DEBUG(500)XNONONONONOYESYESYES
TRACE(600)XNONONONONONOYESYES
ALL(MAX)XNONONONONONONOYES
X(不适用) LoggerConfig级别 关(0) 致命(100) 错误(200) 警告(300) 信息(400) 调试(500) 追踪(600) 全部(最大)
活动等级 X X X X X X X X X
关(0) X 没有 没有 没有 没有 没有 没有 没有
致命(100) X 没有
错误(200) X 没有 没有
警告(300) X 没有 没有 没有
信息(400) X 没有 没有 没有 没有
调试(500) X 没有 没有 没有 没有 没有
追踪(600) X 没有 没有 没有 没有 没有 没有
全部(最大) X 没有 没有 没有 没有 没有 没有 没有
  • There’s no direct method that can be used for throwing an OFF/ALL log events.

    没有直接方法可用于引发OFF / ALL日志事件。
  • Mainly, for throwing OFF/ALL log events you may use logger.log(Level.OFF, “Msg”) or logger.log(LEVEL.ALL,”Msg”), respectively.

    主要是,要抛出OFF / ALL日志事件,可以分别使用logger.log(Level.OFF,“ Msg”)或logger.log(LEVEL.ALL,“ Msg”)。
  • The log method is responsible to handle log event according for the mentioned equation.

    log方法负责根据提到的公式处理对数事件。

Handling equation says: If the LoggerConfig Level’s is greater than or equal to Log event’s level the event would be accepted for further processing.

处理方程式说:如果LoggerConfig级别大于或等于Log事件的级别,则事件将被接受以进行进一步处理。

The log event would be accepted for further processing – this is so important because you have the ability to prevent some event from being handled even if it’s accepted by using Log4j2 Filters.

日志事件将被接受以进行进一步处理 –这非常重要,因为即使使用Log4j2过滤器已接受该事件,您也可以防止对其进行处理。

You can set additive property to false to avoid log event propagation to parent loggers.

您可以将添加剂属性设置为false,以避免日志事件传播到父记录器。

Following below the same example that you did see before but this time with an additivity attribute, so you may notice the difference.

在下面的示例中,您之前看到的相同,但是这次具有可加性属性,因此您可能会注意到其中的区别。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  	<logger name="com" level="TRACE" additivity="false">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev" additivity="false">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="com.journaldev.logging" level="TRACE" additivity="false">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net" level="ERROR" additivity="false">
  		<AppenderRef ref="Console"/>
  	</logger>
  	<logger name="net.journaldev" level="ERROR" additivity="false">
  		<AppenderRef ref="Console"/>
  	</logger>
  </Loggers>
</Configuration>

And the result of execution would be like below:

执行结果如下所示:

17:55:30.558 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
17:55:30.560 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
17:55:30.561 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
17:55:30.561 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
17:55:30.562 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

And you may notice that there’s no propagation of log events to its parent loggers.

您可能会注意到,日志事件没有传播到其父记录器。

Log4j2查询 (Log4j2 Lookups)

Ideally, you may define lookups as a way in which you can pass values for your Logging configuration file. Log4j2 provides you a different set of Lookups that can be used independently for setting values from different contexts:

理想情况下,您可以将查找定义为可以为Logging配置文件传递值的一种方式。 Log4j2为您提供了一组不同的查询,这些查询可以独立用于设置来自不同上下文的值:

  • Context Map Lookup

    上下文映射查找
  • Date Lookup

    日期查询
  • Environment Lookup

    环境查询
  • Java Lookup

    Java查询
  • JNDI Lookup

    JNDI查找
  • JVM Input Argument Lookup (JMX)

    JVM输入参数查询(JMX)
  • Main Arguments Lookup

    主要参数查询
  • Map Lookup

    地图查询
  • Structured Data Lookup

    结构化数据查找
  • System Properties Lookup

    系统属性查询
  • Web Lookup

    网页查询

You may refer for Log4j2 documentation for further details on every type of lookups, but let’s look at some example here to cover the basics of the Log4j2 Lookup.

您可以参考Log4j2 文档以获取有关每种类型的查找的更多详细信息,但让我们在此处查看一些示例以介绍Log4j2查找的基础。

Environment Lookup represents the way in which you can pass an environment value (either by Linux etc/profile, windows system environment or Startup scripts for the application.

Environment Lookup表示传递环境值的方式(通过Linux etc / profile,Windows系统环境或应用程序的启动脚本)。

As most of us know, we have the ability to define a set of environmental values for Application to use. Let’s see the most famous ways to define your environmental variables.

如我们大多数人所知,我们能够定义一组环境值供Application使用。 让我们看看定义环境变量的最著名方法。

  1. Define environment variable by using Windows environment facility:
    • Right click on you computer icon and select properties. Control panel home should be displayed.
    • Click on Advanced system settings and then open Environment Variables window.
    • Under System Variables section, define variable JournalDevVar with JournalDev value.
    • Updating PatternLayout inside your log4j2.xml to contain your newly added variable.

    使用Windows环境工具定义环境变量:
    • 右键单击您的计算机图标,然后选择属性。 应显示控制面板主页。
    • 单击高级系统设置,然后打开环境变量窗口。
    • 在“ 系统变量”部分下,使用JournalDev值定义变量JournalDevVar。
    • 更新log4j2.xml内的PatternLayout以包含新添加的变量。
  1. Define your environmental variables by using the Startup script facility.
    • Instead, of using normal default script, you may use Eclipse IDE Running Script facility, click on your Run Menu and choose Run Configuration.
    • Navigate into Environment Tab & define your variable therein.

    使用启动脚本工具定义环境变量。
    • 可以使用Eclipse IDE运行脚本工具代替普通的默认脚本,在“运行菜单”上单击并选择“运行配置”。
    • 导航到“环境”选项卡并在其中定义变量。

Look now at the modified log4j2.xml file and notice the use of environment variables.

现在查看修改后的log4j2.xml文件,并注意环境变量的使用。

<Console name="Console" target="SYSTEM_OUT">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} $${env:JournalDevVar} $${env:JournalDevSecondVar} [%t] %-5level %logger{36} - %msg%n"/>
</Console>

And the result of execution would look like below:

执行结果如下所示:

23:57:02.511 JournalDev www.journaldev.com [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::
23:57:02.517 JournalDev www.journaldev.com [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::
23:57:02.520 JournalDev www.journaldev.com [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::
23:57:02.523 JournalDev www.journaldev.com [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::
23:57:02.527 JournalDev www.journaldev.com [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::

But you may face a little issue here and especially when you’re defining an OS’s environment variables and it’s the Eclipse Cache. Ideally, Eclipse has cached all system variables when it gets running and you may find all of them under Run – Run Configuration – Environment Tab – Click Select button.

但是您在这里可能会遇到一些小问题,尤其是在定义OS的环境变量(即Eclipse Cache)时。 理想情况下,Eclipse在运行时会缓存所有系统变量,您可以在“运行” –“运行配置” –“环境”选项卡–单击“选择”按钮下找到所有这些系统变量。

So, you may be confusing when you have defined it but the Application doesn’t recognize it. Even if you restart your Eclipse, you won’t get the solution and to solve it you must execute eclipse.exe -clean upon your Eclipse installation.

因此,当您定义它但应用程序无法识别它时,您可能会感到困惑。 即使重新启动Eclipse,也不会获得解决方案,要解决该问题,必须在安装Eclipse时执行eclipse.exe -clean。

To make sure your environment variables are defined properly and your system is going to find them willingly, you may use the correspondence plugin type that’s provided by Log4j2 API.

为了确保正确定义环境变量,并且系统愿意找到它们,您可以使用Log4j2 API提供的对应插件类型。

Make an instance of EnvironmentLookup and ask it for looking up certain variable and if it’s defined, so you would find them easily.

创建一个EnvironmentLookup实例,并要求它查找某些变量以及是否已定义它,因此您可以轻松找到它们。

EnvironmentLookup lookup = new EnvironmentLookup();
LogManager.getRootLogger().error(lookup.lookup("JournalDevSecondVar"));

Log4j2 Appenders (Log4j2 Appenders)

You did see previously how can use Lookups for injecting variables into your configuration file. Though, you may want to modify the medium that your messages went through.

您之前已经看过如何使用查阅将变量注入配置文件中。 但是,您可能需要修改消息通过的媒介。

Instead of using console directly, you may want such a file or database repository to make sure your messages are retained permanently. Log4j2 has provided a lot of Appenders, and you may refer for log4j2 documentation to get further details for Appender.

您可能不希望直接使用控制台,而希望使用这样的文件或数据库存储库来确保您的消息被永久保留。 Log4j2提供了许多Appender,您可以参考log4j2文档以获取有关Appender的更多详细信息。

In a brief manner, below is the list of all Log4j2 Appenders.

简要地,下面是所有Log4j2 Appender的列表。

  1. ConsoleAppender

    ConsoleAppender
  2. AsyncAppender

    AsyncAppender
  3. FailoverAppender

    故障转移
  4. FileAppender

    FileAppender
  5. FlumeAppender

    FlumeAppender
  6. JDBCAppender

    JDBCAppender
  7. JMSAppender

    JMSAppender
  8. JPAAppender

    JPAAppender
  9. MemoryMappedFileAppender

    MemoryMappedFileAppender
  10. NoSQLAppender

    NoSQLAppender
  11. OutputStreamAppender

    OutputStreamAppender
  12. RandomAccessFileAppender

    RandomAccessFileAppender
  13. RewriteAppender

    RewriteAppender
  14. RollingFileAppender

    RollingFileAppender
  15. RollingRandomAccessFileAppender

    RollingRandomAccessFileAppender
  16. RoutingAppender

    RoutingAppender
  17. SMTPAppender

    SMTPAppender
  18. SocketAppender

    SocketAppender
  19. SyslogAppender

    SyslogAppender

The most famous mediums used for logging events are console, file, and Database. Since the file would save your messages, the database might be used for auditing them. For this purpose, this section would focus on how JDBCAppender can be used efficiently.

用于记录事件的最著名的媒介是控制台,文件和数据库。 由于该文件将保存您的消息,因此数据库可用于审核消息。 为此,本节将重点介绍如何有效地使用JDBCAppender。

JDBCAppender (JDBCAppender)

The main goal of JDBCAppender is to write Log events into a relational table through JDBC connections. We don’t consume much time explaining how you can optimize your connection pools as this tutorial isn’t intended for this purpose.

JDBCAppender的主要目标是通过JDBC连接将Log事件写入关系表中。 我们不会花费太多时间来解释如何优化连接池,因为本教程并非旨在用于此目的。

But for sure you will get a full functional example that helps writing your log events into database. Before we may proceed in, let’s see all needed parameters and a description for each to get JDBCAppender configured properly.

但是可以肯定的是,您将获得一个完整的功能示例,该示例有助于将日志事件写入数据库。 在继续进行之前,让我们看一下所有必要的参数以及每个参数的描述,以正确配置JDBCAppender。

Parameter NameTypeDescription
NameStringRequired, The name of the Appender
ignoreExceptionsbooleanDefault value is set to true, making exceptions thrown to be logged also and then ignored.
False value means the exception will be propagated for the caller.
filterFilterThe filter that should be used to make a decision whether the log events are going to be
handled by this Appender or not.
bufferSizeintDefault value is zero, indicating there’s no buffering have been done upon log events.
Value greater than 0 would lead the Appender to buffer log events and then flush them
once the buffer reaches the limit specified.
connectionSourceConnectionSourceRequired, the connections source from which the database connections should be retrieved.
tableNameStringRequired, the name of the Table on which your log events should be persisted.
columnConfigsColumnConfig[]Required, additional information may be set upon those used columns and how the data
should be persisted on each of them. This can be handled with multiple <Column> elements.
参数名称 类型 描述
名称 必填,申请人姓名
ignoreExceptions 布尔值 默认值设置为true,也会引发引发异常并将其记录下来然后忽略的情况。
False值表示将为调用方传播异常。
过滤 过滤 用于确定是否要记录日志事件的过滤器
是否由该Appender处理。
缓冲区大小 整型 默认值为零,表示在日志事件中未进行任何缓冲。
大于0的值将导致Appender缓冲日志事件,然后刷新它们
一旦缓冲区达到指定的限制。
connectionSource 连接源 必需,应从中检索数据库连接的连接源。
tableName 必填,应保留日志事件的表的名称。
columnConfigs ColumnConfig [] 必要时,可以在使用的那些列上以及如何显示数据上设置其他信息
应该坚持每个人。 可以使用多个<Column>元素来处理。
Parameter NameTypeDescription
jndiNameStringRequired, full prefixed JNDI name that the javax.sql.Datasource is bound to.
参数名称 类型 描述
jndiName javax.sql.Datasource绑定到的必需的全前缀JNDI名称。
Parameter NameTypeDescription
classStringRequird, The fully qualified name for a class containg a static factory method for obtaining JDBC connections.
methodbooleanRequired, The name of the static factory method for obtaining JDBC connections.
参数名称 类型 描述
要求,类的完全限定名称包含用于获取JDBC连接的静态工厂方法。
方法 布尔值 必需,用于获取JDBC连接的静态工厂方法的名称。
Parameter NameTypeDescription
nameStringRequired, the name of the database column
patternStringAbility to specify any legal pattern that Log event would be formatted with
literalStringAbility to specify literal value in this column (i.e. SEQ.NEXTVAL)
isEventTimestampbooleanIndicating whether the event would consider Timestamp
isUnicodebooleanFor unicode purpose as you may refer for Log4j2 documentation
for further details
isClobbooleanFor storing character large object, you may refer for Log4j2 documentation
for further details.
参数名称 类型 描述
名称 必需,数据库列的名称
模式 能够指定将Log事件格式化的任何合法模式
文字 可以在此列中指定文字值(即SEQ.NEXTVAL)
isEventTimestamp 布尔值 指示事件是否考虑时间戳
isUnicode 布尔值 出于Unicode的目的,您可以参考Log4j2文档
了解更多详情
isClob 布尔值 对于存储字符大对象,您可以参考Log4j2文档
有关更多详细信息。

Since you’re enforced to use JNDI, our example would configure a connection data source for Oracle database and Apache Tomcat 7.

由于您必须使用JNDI,因此我们的示例将为Oracle数据库和Apache Tomcat 7配置连接数据源。

  • If you didn’t install Oracle database into your environment, it’s appreciated if you can do so. If you’re not much aware of Oracle, i recommend you installing its Express Edition.

    如果您没有将Oracle数据库安装到您的环境中,可以的话,我们将不胜感激。 如果您不太了解Oracle,建议您安装其Express Edition
  • Install Apache Tomcat 7 into your environment.

    将Apache Tomcat 7安装到您的环境中。
  • Create a Maven WebApp project into your Eclipse.

    在Eclipse中创建一个Maven WebApp项目。
  • Make sure your project is created successfully and if you notice any error at the pom, make sure your fix them.

    确保成功创建了项目,并且如果在pom上发现任何错误,请确保对其进行修复。
  • Add Log4j2 dependencies.

    添加Log4j2依赖项。
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-api</artifactId>
   <version>2.2</version>
</dependency>
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-core</artifactId>
   <version>2.2</version>
</dependency>
  • Configure your context to include a MySQL data source declaration. According for Apache documentation, this file should be inside your Web Application META-INF folder.

    配置上下文以包括MySQL数据源声明。 根据Apache文档,此文件应位于Web应用程序META-INF文件夹中。
<Context path="/JournalDevWebLogging"
	privileged="true" antiResourceLocking="false" antiJARLocking="false">
	<Resource name="jdbc/JournalDevDB" auth="Container"
			factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
			type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000"
			username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
			url="jdbc:mysql://localhost:3306/journaldev" />
</Context>
  • Configure your database and create your Logging Table,

    配置数据库并创建日志表,
CREATE TABLE `logging` (
  `EVENT_ID` int(11) NOT NULL AUTO_INCREMENT,
  `EVENT_DATE` datetime DEFAULT NULL,
  `LEVEL` varchar(45) DEFAULT NULL,
  `LOGGER` varchar(45) DEFAULT NULL,
  `MSG` varchar(45) DEFAULT NULL,
  `THROWABLE` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`EVENT_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
  • Configure your log4j2.xml to look like below:

    将log4j2.xml配置为如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout
				pattern="%d{HH:mm:ss.SSS} $${env:JournalDevVar} $${env:JournalDevSecondVar} [%t] %-5level %logger{36} - %msg%n" />
		</Console>
		<JDBC name="databaseAppender" tableName="journaldev.logging">
			<DataSource jndiName="java:/comp/env/jdbc/JournalDevDB" />
			<Column name="EVENT_DATE" isEventTimestamp="true" />
			<Column name="LEVEL" pattern="%level" />
			<Column name="LOGGER" pattern="%logger" />
			<Column name="MSG" pattern="%message" />
			<Column name="THROWABLE" pattern="%ex{full}" />
		</JDBC>
	</Appenders>
	<Loggers>
		<Root level="ERROR">
			<AppenderRef ref="Console" />
		</Root>
		<logger name="com" level="TRACE" additivity="false">
			<AppenderRef ref="databaseAppender" />
		</logger>
		<logger name="com.journaldev" additivity="false">
			<AppenderRef ref="databaseAppender" />
		</logger>
	</Loggers>
</Configuration>
  • Create any Web resource that enable you from getting a reference for a logger and then log an event.

    创建任何使您无法获取记录器参考的Web资源,然后记录事件。
package com.journaldev;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class JournalDevServlet extends HttpServlet{
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
			Logger logger = LogManager.getLogger(JournalDevServlet.class);
			logger.trace("JournalDev Database Logging Message !");
	}
}
  • You may optionally configure a ServletContextListener that may ensure the initialization of data source is done properly.

    您可以选择配置ServletContextListener,以确保正确完成数据源的初始化。
package com.journaldev;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.logging.log4j.LogManager;
public class JournalDevServletContextListener implements ServletContextListener{
	private InitialContext context = null;
	public void contextDestroyed(ServletContextEvent event) {
	}
	public void contextInitialized(ServletContextEvent event) {
		try {
			// Get initial context
			context = new InitialContext();
			// Get a reference for sub context env
			Context envContext = (Context)context.lookup("java:comp/env");
			// Get a reference for sub context jdbc and then locating the data source defined
			LogManager.getRootLogger().error(((Context)envContext.lookup("jdbc")).lookup("JournalDevDB"));
		} catch (NamingException e) {
			LogManager.getRootLogger().error(e);
		}
	}
}
  • Define your Servlet inside your web.xml file.

    在web.xml文件中定义Servlet。
  • Run the application and access defined Servlet above. You will see below logs.

    运行应用程序并访问上面定义的Servlet。 您将在下面看到日志。
Mar 15, 2015 2:31:41 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.6.0_26\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Java\jdk1.6.0_26\jre\bin;C:/Program Files/Java/jdk1.6.0_26/bin/../jre/bin/server;C:/Program Files/Java/jdk1.6.0_26/bin/../jre/bin;C:/Program Files/Java/jdk1.6.0_26/bin/../jre/lib/amd64;D:\OracleWebCenter\OracleWC\Oracle11g\app\oracle\product\11.2.0\server\bin;;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;D:\OracleDB\app\product\11.2.0\dbhome_1\bin;org.C:\Program Files (x86)\Common Files\NetSarang;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;D:\SpringRoo\spring-roo-1.2.5.RELEASE\bin;D:\Ant\apache-ant-1.9.2\bin;C:\Python27;C:\Program Files\Java\jdk1.6.0_26\bin;D:\Maven\apache-maven-3.2.1/bin;D:\bower-master\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\nodejs\;C:\Program Files\Microsoft Windows Performance Toolkit\;D:\Grails\grails-2.4.0\bin;D:\Gradle\gradle-2.0\bin;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\TortoiseSVN\bin;D:\Strawberry\perl\bin;D:\Strawberry\perl\site\bin;D:\Strawberry\c\bin;C:\Users\mohammad.amr\AppData\Roaming\npm;D:\JournalDev\eclipse;;.
Mar 15, 2015 2:31:41 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:JournalDevWebLogging' did not find a matching property.
Mar 15, 2015 2:31:41 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Mar 15, 2015 2:31:41 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Mar 15, 2015 2:31:41 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1020 ms
Mar 15, 2015 2:31:41 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Mar 15, 2015 2:31:41 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.35
14:31:43.847 [localhost-startStop-1] ERROR  - org.apache.tomcat.jdbc.pool.DataSource@10fd0a62{ConnectionPool[defaultAutoCommit=null; defaultReadOnly=null; defaultTransactionIsolation=-1; defaultCatalog=null; driverClassName=com.mysql.jdbc.Driver; maxActive=100; maxIdle=30; minIdle=10; initialSize=10; maxWait=10000; testOnBorrow=false; testOnReturn=false; timeBetweenEvictionRunsMillis=5000; numTestsPerEvictionRun=0; minEvictableIdleTimeMillis=60000; testWhileIdle=false; testOnConnect=false; password=root; url=jdbc:mysql://localhost:3306/journaldev; username=root; validationQuery=null; validatorClassName=null; validationInterval=30000; accessToUnderlyingConnectionAllowed=true; removeAbandoned=false; removeAbandonedTimeout=60; logAbandoned=false; connectionProperties=null; initSQL=null; jdbcInterceptors=null; jmxEnabled=true; fairQueue=true; useEquals=true; abandonWhenPercentageFull=0; maxAge=0; useLock=false; dataSource=null; dataSourceJNDI=null; suspectTimeout=0; alternateUsernameAllowed=false; commitOnReturn=false; rollbackOnReturn=false; useDisposableConnectionFacade=true; logValidationErrors=false; propagateInterruptState=false; }
Mar 15, 2015 2:31:43 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Mar 15, 2015 2:31:43 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Mar 15, 2015 2:31:43 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1909 ms

Log4j2过滤器 (Log4j2 Filters)

Even if there’s a LoggerConfig candidate for handling Log event, you may configure it to deny passing the Log events into back end Appenders. This can be done by log4j2 Filter.

即使有一个LoggerConfig候选对象来处理Log事件,您也可以将其配置为拒绝将Log事件传递到后端Appender。 这可以通过log4j2过滤器完成。

This section isn’t intended for providing you an invasive, massive and huge amount of tutorial about using filters in Log4j2, as they need a lot of articles covering every one of them. But here, you would see how to use the most simple filter to learn the concept.

本部分的目的不是为您提供有关在Log4j2中使用过滤器的大量侵入性教程,因为它们需要大量涉及每个过滤器的文章。 但是在这里,您将看到如何使用最简单的过滤器来学习该概念。

One of the most simple filters that you may use is BurstFilter that provides you with a mechanism to control the rate at which LogEvents are processed by silently discarding events after the maximum limit has been reached.

您可以使用的最简单的过滤器之一是BurstFilter,它为您提供了一种机制,可以通过在达到最大限制后通过静默丢弃事件来控制LogEvent的处理速率。

For now, you may see below all details needed to use BurstFilter.

现在,您可能会在下面看到使用BurstFilter所需的所有详细信息。

Parameter NameTypeDescription
levelStringLevel of messages to be filtered
ratefloatThe average number of events per second to allow
maxBurstintegerThe maximum number of events that can occur before events are filtered for exceeding the average rate.
The default is 10 times the rate.
onMatchStringAction to take when filter matches. May be Accept, DENY or NEUTRAL. The default is NEUTRAL
onMismatchStringAction to tale when filter doesn’t match. May be Accept, DENY or NEUTRAL. The default is NEUTRAL
参数名称 类型 描述
水平 要过滤的邮件级别
浮动 每秒允许的平均事件数
maxBurst 整数 在过滤事件超过平均速率之前可以发生的最大事件数。
默认值为速率的10倍。
onMatch 过滤器匹配时采取的措施。 可以是“接受”,“拒绝”或“中性”。 默认值为NEUTRAL
onMismatch 筛选器不匹配时执行故事操作。 可以是“接受”,“拒绝”或“中性”。 默认值为NEUTRAL

Now, look at the location of BurstFilter inside your database Appender.

现在,查看数据库Appender中BurstFilter的位置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout
				pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
		</Console>
		<JDBC name="databaseAppender" tableName="journaldev.logging">
			<DataSource jndiName="java:/comp/env/jdbc/JournalDevDB" />
			<BurstFilter level="TRACE" rate="20" maxBurst="2"/>
			<Column name="EVENT_DATE" isEventTimestamp="true" />
			<Column name="LEVEL" pattern="%level" />
			<Column name="LOGGER" pattern="%logger" />
			<Column name="MSG" pattern="%message" />
			<Column name="THROWABLE" pattern="%ex{full}" />
		</JDBC>
	</Appenders>
	<Loggers>
		<Root level="ERROR">
			<AppenderRef ref="Console" />
		</Root>
		<logger name="com" level="TRACE" additivity="false">
			<AppenderRef ref="databaseAppender" />
		</logger>
		<logger name="com.journaldev" additivity="false">
			<AppenderRef ref="databaseAppender" />
		</logger>
	</Loggers>
</Configuration>
  • Database Appender does consider BurstFilter while console Appender doesn’t.

    Database Appender不会考虑BurstFilter,而控制台Appender不会考虑。
  • While using of Console logger would lead you for full log events to be logged, database Appender wouldn’t do that as BurstFilter will deny some of them from proceeding into.

    虽然使用Console logger会导致您记录完整的日志事件,但是数据库Appender不会这样做,因为BurstFilter会拒绝其中的一些继续进行。
  • This LogEvents denial is achieved even that the Loggers used is the candidate for handling the LogEvents. This is so reasonable as shown in the JournalDevServlet below.

    即使使用的记录器是处理LogEvent的候选对象,也可以实现此LogEvents拒绝。 如下面的JournalDevServlet所示,这是如此合理。
package com.journaldev;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class JournalDevServlet extends HttpServlet{
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		Logger logger = LogManager.getLogger(JournalDevServlet.class);
		for(int i = 0 ; i < 1000 ; i++){
			logger.trace("Index :: "+i+" :: JournalDev Database Logging Message !");
			LogManager.getRootLogger().error("Index :: "+i+" :: JournalDev Database Logging Message !");
		}
	}
}

Even that those LoggerConfigs are the candidate for handling Log Events thrown there, but the Filter has prevented some of them from being handled and then logged. You may add this for Logging Space concept to get the whole concept of logging.

即使那些LoggerConfigs都是处理扔在那里的Log Events的候选对象,但是Filter阻止了其中的某些事件被处理然后记录下来。 您可以将其添加到Logging Space概念中,以获得整个日志概念。

Log4j2布局 (Log4j2 Layouts)

Due to different Appenders that consume Log Events and nature of each appender, the layouts are made to form the LogEvent in the format that meets the needs of whoever will be consuming the log event.

由于使用日志事件的Appender不同,并且每个追加程序的性质也不同,因此采用布局形式形成LogEvent的格式可以满足使用日志事件的人的需求。

In Log4j 1.x and Logback APIs, the layout transformation of Log Events was into a String, while Log4j2 layouts have considered a different way of transformation; and that’s by transforming the LogEvent into the array of bytes.

在Log4j 1.x和Logback API中,Log Events的布局转换为字符串,而Log4j2布局考虑了另一种转换方式。 那是通过将LogEvent转换为字节数组。

This new type of transformation would enforce you configuring the Charset to ensure that byte array contains the correct values. It’s highly recommended to return back into Apache Log4j2 official site and see more about Layout and different types that Log4j2 provides.

这种新的转换类型将强制您配置字符集,以确保字节数组包含正确的值。 强烈建议返回Apache Log4j2官方站点,并详细了解Log4j2提供的布局和不同类型。

In this section, we will consider the most famous Layout that is always used by most of our developers and for sure you may hear about it; it’s PatternLayout.

在本节中,我们将考虑大多数开发人员始终使用的最著名的Layout,可以肯定的是您会听到的; 它是PatternLayout

Log4j2 PatternLayout (Log4j2 PatternLayout)

Pattern layout is a configurable, flexible String pattern aimed to format the LogEvent. This kind of formatting is dependent on the conversion pattern concept. This section will depict you the most important features pattern layout provides.

模式布局是一种可配置的,灵活的String模式,旨在格式化LogEvent。 这种格式取决于转换模式的概念。 本节将描述模式布局提供的最重要的功能。

Conversion pattern is related to the conversion pattern that printf in language C provides. Generally, the conversion pattern is composed of literal text and format control Expressions called conversion specifiers.

转换模式与语言C中的printf提供的转换模式有关。 Generally, the conversion pattern is composed of literal text and format control Expressions called conversion specifiers.

Figure below depicts you what parts the conversion pattern composed from:

Figure below depicts you what parts the conversion pattern composed from:

This figure above is a trial to simplify the Conversion Pattern, but for sure it’s better for you to refer Apache Log4j2 documentation for further details about Layouts and Pattern Layout specifically. Also, you may refer above for log events and see at every time what’s Conversion Pattern it is used for format the messages.

This figure above is a trial to simplify the Conversion Pattern, but for sure it's better for you to refer Apache Log4j2 documentation for further details about Layouts and Pattern Layout specifically. Also, you may refer above for log events and see at every time what's Conversion Pattern it is used for format the messages.

Which Log4j2 Level should you use (Which Log4j2 Level should you use)

The biggest question that you may ask yourself is when specific Log Event level should be used. In the development field, it’s normal to use DEBUG log event whereas in production we should INFO or WARN level.

The biggest question that you may ask yourself is when specific Log Event level should be used. In the development field, it's normal to use DEBUG log event whereas in production we should INFO or WARN level.

This table below should guide you on which log4j2 level should be used in which case.

This table below should guide you on which log4j2 level should be used in which case.

Log Event LevelWhen It Should Be Used
OFFWhen no events will be logged
FATALWhen a severe error will prevent the application from continuing
ERRORWhen an error in the application, possibly recoverable
WARNWhen an event that might possible lead to an error
INFOWhen an event for informational purposes
DEBUGWhen a general debugging event required
TRACEWhen a fine grained debug message, typically capturing the flow through the application
ALLWhen all events should be logged
Log Event Level When It Should Be Used
When no events will be logged
FATAL When a severe error will prevent the application from continuing
错误 When an error in the application, possibly recoverable
警告 When an event that might possible lead to an error
信息 When an event for informational purposes
DEBUG When a general debugging event required
TRACE When a fine grained debug message, typically capturing the flow through the application
所有 When all events should be logged

Log4j2 Tutorial Summary (Log4j2 Tutorial Summary)

Log4j2 is revamped version of Apache Logging framework. Log4j2 has provided a set of new features and performance enhancements from Log4j1.x. This log4j2 tutorial is aimed to help you get it all in one location.

Log4j2 is revamped version of Apache Logging framework. Log4j2 has provided a set of new features and performance enhancements from Log4j1.x. This log4j2 tutorial is aimed to help you get it all in one location.

Since some of these concepts aren’t so easy to cover them all at once, we’re decided to enclose our efforts in explaining the concept and using some samples for more clarification. Appenders, Filters, layouts, and lookups are subject to this rule.

Since some of these concepts aren't so easy to cover them all at once, we're decided to enclose our efforts in explaining the concept and using some samples for more clarification. Appenders, Filters, layouts, and lookups are subject to this rule.

Some important points
To make sure you’re able to get the below application running and to avoid any obstacles, verify the below:

Some important points
To make sure you're able to get the below application running and to avoid any obstacles, verify the below:

  • Your Eclipse IDE is maven enabled.

    Your Eclipse IDE is maven enabled.
  • Your Apache Tomcat has a mysql-connector JAR inside your Apache Home lib folder.

    Your Apache Tomcat has a mysql-connector JAR inside your Apache Home lib folder.
  • You are aware of how to use Maven.

    You are aware of how to use Maven.

That’s all for the log4j2 tutorial, I hope most of the important points are covered to get you started using Log4j2 in your application.

That's all for the log4j2 tutorial, I hope most of the important points are covered to get you started using Log4j2 in your application.

翻译自: https://www.journaldev.com/7128/log4j2-example-tutorial-configuration-levels-appenders

log4j 配置文件示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值