应用小记:LOG4J2 完整配置多参考示例详解
liuian 2024-12-08 16:20 22 浏览
导语
如果你想在项目中达到按需对日志进行过滤,那现在的Log4j2绝对是满足你的各种口味的。简单比较了比较流行的sl4j,觉得还是log4j2更深一筹。下面是官方的测试结果:
配置语法
从版本2.9开始,出于安全原因,Log4j不会在XML文件中处理DTD。如果要将配置拆分为多个文件,请使用XInclude或 Composite Configuration。
正如之前的例子所描述,Log4j允许您轻松地重新定义日志记录行为,而无需修改您的应用程序。可以禁用应用程序的某些部分的日志记录,只有在满足特定条件时才进行日志记录,如针对特定用户执行的操作、将输出传递到日志报告系统等。需要理解配置文件的语法后方能做到上述操作。
XML文件中的配置元素接受几个属性:
Logger配置
在尝试配置它们之前,我们先了解Log4j中的logger是如何工作的。如果需要更多信息,请参考Log4j 体系结构。在不理解这些概念的情况下尝试配置Log4j会遇到很多挫折。
LoggerConfig是使用logger元素配置的。该logger元素必须指定name属性,通常情况下会指定一个level的属性,也可以指定一个additivity属性。级别可以配置为TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF之一。如果没有指定级别,则默认为ERROR。可以为addability属性赋值true或false。如果该属性被省略,则将使用默认值true。
LoggerConfig(包括根LoggerConfig)可以配置属性,这些属性将被添加到从ThreadContextMap复制的属性中。这些属性可以从Appenders,Filters,Layouts等引用,就像它们是ThreadContext Map的一部分一样。 属性可以包含将在解析配置时解析的变量,或者在记录每个事件时动态解析的变量。 有关使用变量的更多信息,请参阅Property Substitution。
LoggerConfig也可以配置一个或多个AppenderRef元素。 每个引用的appender都将与指定的LoggerConfig关联。如果在LoggerConfig上配置了多个appender,则在处理日志记录事件时会调用它们中的每一个。
每个Log4j整体配置都必须有根记录器(root logger)。 如果没有配置默认根LoggerConfig,默认使用级别为ERROR并且连接了一个控制台appender的根LoggerConfig。根记录器和其他记录器之间的主要区别是
根记录器没有名称属性。
根记录器不支持可加性属性,因为它没有父级。
Appender配置
appender配置使用 特定的appender插件的名称 或 类型属性值为appender插件的名称的appender元素。另外,每个appender必须有一个名字属性,指定一个在appender集合中唯一的值。logger将使用该名称来引用appender,如前一节所述。
<Appenders>
<!-- 类型属性值为appender插件的名称的appender元素 -->
<appender type="Console" name="OUT"/>
<!-- 使用特定的appender插件的名称 -->
<Console name="STDOUT">
<PatternLayout pattern="%m MDC%X%n"/>
</Console>
</Appenders>
大多数appender还支持要配置的布局(也可以使用特定布局插件的名称作为元素或者使用“layout”作为元素名称以及包含布局插件名称的type属性来指定布局)。各种appender将包含其正确运行所需的其他属性或元素。
Filter配置
Log4j允许在4个地方中指定一个Filter:
- 与appenders,loggers和属性元素相同的级别。这些filter可以在传递给LoggerConfig之前接受或拒绝事件。
- 在一个logger元素内。这些filter可以接受或拒绝特定记录器的事件。
- 在一个appender元素内。这些filter可以防止或引起appender处理事件。
- 在appender引用元素中。这些filter用于确定logger是否应该将事件路由到appender。
尽管只能配置一个filter元素,但该元素可能是代表CompositeFilter 的filters元素。filters元素允许任何数量的filter元素配置在内。以下示例显示了如何在ConsoleAppender上配置多个filter。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<ThresholdFilter level="trace"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m MDC%X%n"/>
</Console>
<Console name="FLOW">
<!-- this pattern outputs class name and line number -->
<PatternLayout pattern="%C{1}.%M %m %ex%n"/>
<filters>
<MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
</Console>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<Property name="user">${sys:user.name}</Property>
<AppenderRef ref="File">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
</AppenderRef>
<AppenderRef ref="STDOUT" level="error"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Layout配置
Appender使用Layout将LogEvent格式化为满足处理日志事件需求的表单。在Log4j 1.x和Logback Layouts中,是将一个事件转换成一个String。在Log4j中,Layout返回一个字节数组。这可以使布局的结果在更多类型的Appender中有用。但是,这意味着您需要使用Charset配置大多数布局,以确保字节数组包含正确的值。
使用Charset的布局的根类是org.apache.logging.log4j.core.layout.AbstractStringLayout ,其中缺省值是UTF-8。每个扩展AbstractStringLayout的Layout都可以提供自己的默认值。
Log4j 2.4.1为ISO-8859-1和US-ASCII字符集添加了一个自定义字符编码器,将Java 8内置的一些性能改进功能添加到Log4j中,以便在Java 7上使用。对于仅记录日志的应用程序,指定ISO-8859-1字符集将显着提高性能。
Log4j提供的转换模式
- %m 输出代码中指定的消息
- %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
- %r 输出自应用启动到输出该log信息耗费的毫秒数
- %c 输出所属的类目,通常就是所在类的全名
- %t 输出产生该日志事件的线程名
- %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
- %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式
- 如:%d{dd MMM yyyy HH:mm:ss,SSS},输出类似:02 Nov 2012 14:34:02,781
- %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数
- 如:Testlog.main(TestLog.java:10)
- %F 输出日志消息产生时所在的文件名称
- %L 输出代码中的行号
- %x 输出和当前线程相关联的NDC(嵌套诊断环境),像java servlets多客户多线程的应用中
- %% 输出一个"%"字符
更多转换模式详见官方文档
配置方式
XML配置
Log4j可以使用两种XML风格进行配置:简洁和严谨。简洁的格式使配置变得非常简单,因为元素名称与它们所代表的组件相匹配,但无法用XML模式进行验证。例如,ConsoleAppender是通过在其父appenders元素下声明一个名为Console的XML元素来配置的。但是,元素和属性名称不区分大小写。另外,可以将属性指定为XML属性,也可以将其指定为不具有属性且具有文本值的XML元素。所以
<PatternLayout pattern = “%m%n” />
和
<PatternLayout>
<Pattern>%m%n</Pattern>
</PatternLayout>
是等同的。
下面的文件表示XML配置的结构,但是请注意,下面标注中的元素表示简洁的元素名称。
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<filter ... /> <!-- 简洁 -->
<Appenders>
<appender ... > <!-- 简洁 -->
<filter ... /> <!-- 简洁 -->
</appender> <!-- 简洁 -->
...
</Appenders>
<Loggers>
<Logger name="name1">
<filter ... /> <!-- 简洁 -->
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
查看本页面上的许多示例,了解appender,filter和logger的配置声明。
严格XML配置
除上述简洁的XML格式之外,Log4j允许以更“常规”的XML方式指定配置,可使用XML模式进行验证。这是通过用它们的对象类型替换上面的友好元素名来完成的,如下所示。例如,不是使用名为Console的元素来配置ConsoleAppender,而是将其配置为具有包含“Console”的类型属性的appender元素。
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<Filter type="type" ... />
<Appenders>
<Appender type="type" name="name">
<Filter type="type" ... />
</Appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<Filter type="type" ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
以下是使用严格格式的示例配置。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest"
packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="trace"/>
<Appenders>
<Appender type="Console" name="STDOUT">
<Layout type="PatternLayout" pattern="%m MDC%X%n"/>
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
</Filters>
</Appender>
<Appender type="Console" name="FLOW">
<Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</Appender>
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</Layout>
</Appender>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<Filter type="ThreadContextMapFilter">
<KeyValuePair key="test" value="123"/>
</Filter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<AppenderRef ref="File"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
JSON配置
除了XML之外,还可以使用JSON配置Log4j。JSON格式与简洁的XML格式非常相似。每个键表示插件的名称,而与其关联的键/值对是其属性。如果一个键所包含的不仅仅是一个简单的值,它本身就是一个从属插件。在下面的示例中,ThresholdFilter,Console和PatternLayout都是插件,而Console插件将为其name属性分配一个STDOUT值,并且将为ThresholdFilter分配一个调试级别。
{ "configuration": { "status": "error", "name": "RoutingTest",
"packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename",
"value" : "target/rolling1/rollingtest-${sd:type}.log" }
},
"ThresholdFilter": { "level": "debug" },
"appenders": {
"Console": { "name": "STDOUT",
"PatternLayout": { "pattern": "%m%n" },
"ThresholdFilter": { "level": "debug" }
},
"Routing": { "name": "Routing",
"Routes": { "pattern": "${sd:type}",
"Route": [
{
"RollingFile": {
"name": "Rolling-${sd:type}", "fileName": "${filename}",
"filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
"PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
"SizeBasedTriggeringPolicy": { "size": "500" }
}
},
{ "AppenderRef": "STDOUT", "key": "Audit"}
]
}
}
},
"loggers": {
"logger": { "name": "EventLogger", "level": "info", "additivity": "false",
"AppenderRef": { "ref": "Routing" }},
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
}
}
请注意,在RoutingAppender中,Route元素已被声明为一个数组。这是有效的,因为每个数组元素将是一个Route组件。这对于诸如appender和filter之类的元素不起作用,其中每个元素具有不同的简洁格式的名称。Appender和Filter可以定义为数组元素,如果每个appender或filter声明一个名为“type”的属性包含appender的类型。
以下示例说明了这一点以及如何将多个logger声明为数组。
{ "configuration": { "status": "debug", "name": "RoutingTest",
"packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename",
"value" : "target/rolling1/rollingtest-${sd:type}.log" }
},
"ThresholdFilter": { "level": "debug" },
"appenders": {
"appender": [
{ "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }},
{ "type": "Routing", "name": "Routing",
"Routes": { "pattern": "${sd:type}",
"Route": [
{
"RollingFile": {
"name": "Rolling-${sd:type}", "fileName": "${filename}",
"filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
"PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
"SizeBasedTriggeringPolicy": { "size": "500" }
}
},
{ "AppenderRef": "STDOUT", "key": "Audit"}
]
}
}
]
},
"loggers": {
"logger": [
{ "name": "EventLogger", "level": "info", "additivity": "false",
"AppenderRef": { "ref": "Routing" }},
{ "name": "com.foo.bar", "level": "error", "additivity": "false",
"AppenderRef": { "ref": "STDOUT" }}
],
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
}
}
注:使用JSON配置文件需要额外的运行时依赖的jar包,详见runtime-dependencies。
Properties配置
从版本2.4开始,Log4j现在支持通过属性文件进行配置。请注意,属性语法与Log4j 1中使用的语法不同。与XML和JSON配置类似,属性配置也是根据插件名和属性定义插件。
在版本2.6之前,属性配置要求您在带有这些名称的属性的逗号分隔列表中列出appender,filter和logger的标识符。然后,这些组件中的每一个都将被定义在以组件.<.identifier>.开头的属性集中。标识符不必与正在定义的组件的名称相匹配,但必须是属于该组件的所有属性和子组件的唯一标识。如果标识符列表不存在,标识符不能包含“.”。每个单独的组件必须有一个指定的“type”属性来标识组件的插件类型。
从版本2.6开始,这个标识符列表不再需要,因为名字是在第一次使用时推断的,但是如果你想使用更复杂的标识符,你仍然必须使用列表。如果列表存在,它将被使用。
与基本组件不同,创建子组件时,不能指定包含标识符列表的元素。相反,您必须按照下面代码中定义滚动文件appender的策略一样,定义所示的类型定义封装元素。然后定义封装元素下面的每个子组件,如同TimeBasedTriggeringPolicy和SizeBasedTriggeringPolicy在下面代码定义一样。
属性配置文件支持advertiser, monitorInterval, name, packages, shutdownHook, shutdownTimeout, status, verbose, 和 dest属性。有关这些属性的定义,请参阅配置语法。
status = error
dest = err
name = PropertiesConfig
property.filename = target/rolling/rollingtest.log
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = error
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5
logger.rolling.name = com.example.my.app
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT
详细配置例子
下列例子均使用严格XML格式的方式配置Log4j,因其可读性和规范性均较高。不同的Appender决定日志输出的最终目的地。
ConsoleAppender(控制台)
正如人们所期望的那样,ConsoleAppender将其输出写入System.out或System.err,而默认目标是System.out。注意必须提供Layout来格式化LogEvent。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest">
<Appenders>
<!-- 类型名为Console,名称为必须属性 -->
<Appender type="Console" name="STDOUT">
<!-- 布局为PatternLayout的方式,
输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
</Appender>
</Appenders>
<Loggers>
<!-- 可加性为false -->
<Logger name="test" level="debug" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<!-- root loggerConfig设置 -->
<Root level="trace">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
FileAppender(文件)
FileAppender是一个OutputStreamAppender,它将输出写入fileName参数中指定的File。FileAppender使用FileManager(它扩展了OutputStreamManager)来实际执行文件I / O。虽然来自不同配置的FileAppender不能共享,但如果Manager可以访问,FileManagers可以共享。例如,一个servlet容器中的两个web应用程序可以拥有自己的配置,并且如果Log4j处于两个公共的ClassLoader中,则可以安全地将输出写入相同的文件。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="debug"/>
<Appenders>
<!-- 类型名为File,名称为必须属性,
fileName为生成文件的名称(此处使用Properties中定义的变量) -->
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
</Appender>
</Appenders>
<Loggers>
<!-- root loggerConfig设置 -->
<Root level="debug">
<AppenderRef ref="File" />
</Root>
</Loggers>
</Configuration>
RollingFileAppender(滚动文件)
RollingFileAppender是一个OutputStreamAppender,它将输出写入fileName参数中指定的File,并根据TriggeringPolicy和RolloverPolicy将文件滚动。RollingFileAppender使用RollingFileManager(它扩展了OutputStreamManager)来实际执行文件I / O并执行翻转。虽然来自不同配置的RolloverFileAppender不能共享,但如果Manager可以访问,RollingFileManagers可以共享。例如,一个servlet容器中的两个web应用程序可以拥有自己的配置,并且如果Log4j处于两个公共的ClassLoader中,则可以安全地将输出写入相同的文件。
RollingFileAppender需要一个TriggeringPolicy和一个 RolloverStrategy。TriggeringPolicy决定是否应该执行翻转,而RolloverStrategy定义应该如何进行翻转。如果没有配置RolloverStrategy,RollingFileAppender将使用DefaultRolloverStrategy。log4j-2.5版本以后,可以在DefaultRolloverStrategy中配置自定义删除操作,以便在滚动时运行。2.8版本以后,如果没有配置文件名, 则将使用DirectWriteRolloverStrategy而不是DefaultRolloverStrategy。log4j-2.9版本以后,一个自定义的POSIX文件属性视图操可以在DefaultRolloverStrategy中配置为在滚动时运行,如果没有定义的话,将继承RollingFileAppender的POSIX文件属性视图。
注:RollingFileAppender不支持文件锁定。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest"
schema="Log4J-V2.10.xsd">
<Properties>
<Property name="filename">target/application.log</Property>
<Property name="filePattern">target/%d{yyyy-MM-dd}/application-%i.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="debug" />
<Appenders>
<!-- 类型名为RollingFile,名称为必须属性,
fileName为生成文件的名称(此处使用Properties中定义的变量) -->
<Appender type="RollingFile" name="RollingFile"
fileName="${filename}" filePattern="${filePattern}">
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
<!-- 定义文件最大大小 -->
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 KB" />
</Policies>
</Appender>
</Appenders>
<Loggers>
<!-- root loggerConfig设置 -->
<Root level="debug">
<AppenderRef ref="RollingFile" />
</Root>
</Loggers>
</Configuration>
JDBCAppender(关系数据库)
JDBCAppender使用标准JDBC将日志事件写入关系数据库表。可以将其配置为使用JNDI 数据源或自定义工厂方法获取JDBC连接。**无论采取哪种方法,都必须以连接池为后盾。**否则,记录日志的性能将受到很大的影响。
在配置JDBCAppender时,您必须指定Appender从中获取JDBC连接的ConnectionSource实现。您必须使用<Da??taSource> 或<ConnectionFactory>嵌套元素中的一个。
若已通过如spring bean注入等方式创建了DataSource,可通过所绑定的JNDI名称来配置日志系统,例子如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JDBC name="databaseAppender" tableName="dbo.application_log">
<!-- 通过与DataSource绑定的JNDI名称配置JDBCAppender -->
<DataSource jndiName="java:/comp/env/jdbc/LoggingDataSource" />
<Column name="eventDate" isEventTimestamp="true" />
<Column name="level" pattern="%level" />
<Column name="logger" pattern="%logger" />
<Column name="message" pattern="%message" />
<Column name="exception" pattern="%ex{full}" />
</JDBC>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender" />
</Root>
</Loggers>
</Configuration>
亦可通过Java代码创建ConnectionFactory以配置JDBCAppender,例子如下:
(此处使用单例以确保ConnectionFactory在多线程下安全)
package org.newday.demo;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
public class ConnectionFactory {
private static interface Singleton {
final ConnectionFactory INSTANCE = new ConnectionFactory();
}
private DataSource dataSource = null;
private ConnectionFactory() {
Properties properties = new Properties();
//从配置文件读取properties,亦可直接赋值至Properties实例中
//driverClassName,url,username,password为必须项
try (InputStream is = ConnectionFactory.class.getResourceAsStream("/jdbc.properties")){
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
try {
this.dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getDatabaseConnection() throws SQLException {
return Singleton.INSTANCE.dataSource.getConnection();
}
}
jdbc.properties配置:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true
username=root
password=root
XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JDBC name="databaseAppender" tableName="log">
<!-- 通过与自定义的ConnectionFactory配置JDBCAppender -->
<ConnectionFactory class="org.test.ConnectionFactory"
method="getDatabaseConnection" />
<!-- 配置日志输出到数据库时与列相对应的值 -->
<!-- literal为使用此属性在此列中插入文字值,可用于在ID列
中插入唯一的ID,若有自增主键时,可不使用literal-->
<Column name="EVENT_ID" literal="'new_log'" />
<Column name="EVENT_DATE" isEventTimestamp="true" />
<Column name="LEVEL" pattern="%level" />
<Column name="LOGGER" pattern="%logger" />
<Column name="MESSAGE" pattern="%message" />
<Column name="THROWABLE" pattern="%ex{full}" />
</JDBC>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="databaseAppender" />
</Root>
</Loggers>
</Configuration>
AsyncAppender(异步)
AsyncAppender接受对其他Appender的引用,并使用单独的线程将LogEvent记录在Appender中。请注意,将日志写入这些Appender时的异常将从应用程序中隐藏。AsyncAppender应该在它引用的appender配置完成后再进行配置,以确保它正常关闭。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="debug" />
<Appenders>
<!-- 类型名为File,名称为必须属性,
fileName为生成文件的名称(此处使用Properties中定义的变量) -->
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
</Appender>
<!-- 将FileAppe异步化 -->
<Appender type="Async" name="Async">
<AppenderRef ref="File" />
</Appender>
</Appenders>
<Loggers>
<!-- root loggerConfig设置 -->
<Root level="debug">
<AppenderRef ref="Async" />
</Root>
</Loggers>
</Configuration>
另外,需要注意Appenders包含以下标签
FileAppender 普通地输出到本地文件
FlumeAppender 将几个不同源的日志汇集、集中到一处
RewriteAppender 对日志事件进行掩码或注入信息
RollingFileAppender 对日志文件进行封存
RoutingAppender 在输出地之间进行筛选路由
SMTPAppender 将LogEvent发送到指定邮件列表
SocketAppender 将LogEvent以普通格式发送到远程主机
SyslogAppender 将LogEvent以RFC 5424格式发送到远程主机
AsynchAppender 将一个LogEvent异步地写入多个不同输出地
ConsoleAppender 将LogEvent输出到控制台
FailoverAppender 维护一个队列,系统将尝试向队列中的Appender依次输出LogEvent,直到有一个成功为止
详细参考示例
最后提供一个带有注释的参考示例,可酌情使用——
<?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--status="WARN" :用于设置log4j2自身内部日志的信息输出级别,默认是OFF--> <!--monitorInterval="30" :间隔秒数,自动检测配置文件的变更和重新配置本身--> <configuration status="WARN" monitorInterval="30"> <Properties> <!--自定义一些常量,之后使用${变量名}引用--> <Property name="logFilePath">log</Property> <Property name="logFileName">test.log</Property> </Properties> <!--appenders:定义输出内容,输出格式,输出方式,日志保存策略等,常用其下三种标签[console,File,RollingFile]--> <appenders> <!--console :控制台输出的配置--> <console name="Console" target="SYSTEM_OUT"> <!--PatternLayout :输出日志的格式,LOG4J2定义了输出代码,详见第二部分--> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> </console> <!--File :同步输出日志到本地文件--> <!--append="false" :根据其下日志策略,每次清空文件重新输入日志,可用于测试--> <File name="log" fileName="${logFilePath}/${logFileName}" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!--SMTP :邮件发送日志--> <SMTP name="Mail" subject="****SaaS系统正式版异常信息" to="message@message.info" from="message@lengjing.info" smtpUsername="message@message.info" smtpPassword="LENG****1234" smtpHost="mail.lengjing.info" smtpDebug="false" smtpPort="25" bufferSize="10"> <PatternLayout pattern="[%-5p]:%d{YYYY-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n" /> </SMTP> <!-- ${sys:user.home} :项目路径 --> <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> <!--ThresholdFilter :日志输出过滤--> <!--level="info" :日志级别,onMatch="ACCEPT" :级别在info之上则接受,onMismatch="DENY" :级别在info之下则拒绝--> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <!-- Policies :日志滚动策略--> <Policies> <!-- TimeBasedTriggeringPolicy :时间滚动策略,默认0点小时产生新的文件,interval="6" : 自定义文件滚动时间间隔,每隔6小时产生新文件, modulate="true" : 产生文件是否以0点偏移时间,即6点,12点,18点,0点--> <TimeBasedTriggeringPolicy interval="6" modulate="true"/> <!-- SizeBasedTriggeringPolicy :文件大小滚动策略--> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> <DefaultRolloverStrategy max="20"/> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log" filePattern="${sys:user.home}/logs/${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log" filePattern="${sys:user.home}/logs/${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> <!--Logger节点用来单独指定日志的形式,name为包路径,比如要为org.springframework包下所有日志指定为INFO级别等。 --> <logger name="org.springframework" level="INFO"></logger> <logger name="org.mybatis" level="INFO"></logger> <!-- Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出 --> <root level="all"> <appender-ref ref="Console"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> <!--AsyncLogger :异步日志,LOG4J有三种日志模式,全异步日志,混合模式,同步日志,性能从高到底,线程越多效率越高,也可以避免日志卡死线程情况发生--> <!--additivity="false" : additivity设置事件是否在root logger输出,为了避免重复输出,可以在Logger 标签下设置additivity为”false”--> <AsyncLogger name="AsyncLogger" level="trace" includeLocation="true" additivity="false"> <appender-ref ref="RollingFileError"/> </AsyncLogger> </loggers> </configuration>
收藏起,随时备查。
- 上一篇:从产品经理角度解说知识图谱
- 下一篇:你知道吗?5个基于JAVA开源NoSQL数据库
相关推荐
- 2023年最新微信小程序抓包教程(微信小程序 抓包)
-
声明:本公众号大部分文章来自作者日常学习笔记,部分文章经作者授权及其他公众号白名单转载。未经授权严禁转载。如需转载,请联系开百。请不要利用文章中的相关技术从事非法测试。由此产生的任何不良后果与文...
- 测试人员必看的软件测试面试文档(软件测试面试怎么说)
-
前言又到了毕业季,我们将会迎来许多需要面试的小伙伴,在这里呢笔者给从事软件测试的小伙伴准备了一份顶级的面试文档。1、什么是bug?bug由哪些字段(要素)组成?1)将在电脑系统或程序中,隐藏着的...
- 复活,视频号一键下载,有手就会,长期更新(2023-12-21)
-
视频号下载的话题,也算是流量密码了。但也是比较麻烦的问题,频频失效不说,使用方法也难以入手。今天,奶酪就来讲讲视频号下载的新方案,更关键的是,它们有手就会有用,最后一个方法万能。实测2023-12-...
- 新款HTTP代理抓包工具Proxyman(界面美观、功能强大)
-
不论是普通的前后端开发人员,还是做爬虫、逆向的爬虫工程师和安全逆向工程,必不可少会使用的一种工具就是HTTP抓包工具。说到抓包工具,脱口而出的肯定是浏览器F12开发者调试界面、Charles(青花瓷)...
- 使用Charles工具对手机进行HTTPS抓包
-
本次用到的工具:Charles、雷电模拟器。比较常用的抓包工具有fiddler和Charles,今天讲Charles如何对手机端的HTTS包进行抓包。fiddler抓包工具不做讲解,网上有很多fidd...
- 苹果手机下载 TikTok 旧版本安装包教程
-
目前苹果手机能在国内免拔卡使用的TikTok版本只有21.1.0版本,而AppStore是高于21.1.0版本,本次教程就是解决如何下载TikTok旧版本安装包。前期准备准备美区...
- 【0基础学爬虫】爬虫基础之抓包工具的使用
-
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学爬...
- 防止应用调试分析IP被扫描加固实战教程
-
防止应用调试分析IP被扫描加固实战教程一、概述在当今数字化时代,应用程序的安全性已成为开发者关注的焦点。特别是在应用调试过程中,保护应用的网络安全显得尤为重要。为了防止应用调试过程中IP被扫描和潜在的...
- 一文了解 Telerik Test Studio 测试神器
-
1.简介TelerikTestStudio(以下称TestStudio)是一个易于使用的自动化测试工具,可用于Web、WPF应用的界面功能测试,也可以用于API测试,以及负载和性能测试。Te...
- HLS实战之Wireshark抓包分析(wireshark抓包总结)
-
0.引言Wireshark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。Wireshark使用WinPCAP作为接口,直接...
- 信息安全之HTTPS协议详解(加密方式、证书原理、中间人攻击 )
-
HTTPS协议详解(加密方式、证书原理、中间人攻击)HTTPS协议的加密方式有哪些?HTTPS证书的原理是什么?如何防止中间人攻击?一:HTTPS基本介绍:1.HTTPS是什么:HTTPS也是一个...
- Fiddler 怎么抓取手机APP:抖音、小程序、小红书数据接口
-
使用Fiddler抓取移动应用程序(APP)的数据接口需要进行以下步骤:首先,确保手机与计算机连接在同一网络下。在计算机上安装Fiddler工具,并打开它。将手机的代理设置为Fiddler代理。具体方...
- python爬虫教程:教你通过 Fiddler 进行手机抓包
-
今天要说说怎么在我们的手机抓包有时候我们想对请求的数据或者响应的数据进行篡改怎么做呢?我们经常在用的手机手机里面的数据怎么对它抓包呢?那么...接下来就是学习python的正确姿势我们要用到一款强...
- Fiddler入门教程全家桶,建议收藏
-
学习Fiddler工具之前,我们先了解一下Fiddler工具的特点,Fiddler能做什么?如何使用Fidder捕获数据包、修改请求、模拟客户端向服务端发送请求、实施越权的安全性测试等相关知识。本章节...
- fiddler如何抓取https请求实现手机抓包(100%成功解决)
-
一、HTTP协议和HTTPS协议。(1)HTTPS协议=HTTP协议+SSL协议,默认端口:443(2)HTTP协议(HyperTextTransferProtocol):超文本传输协议。默认...
- 一周热门
-
-
Python实现人事自动打卡,再也不会被批评
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
python使用fitz模块提取pdf中的图片
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- table.render (33)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)