参见log4j官网:https://logging.apache.org/log4j/2.x
注意:log4j2官网展现的是最新版的内容。因此有的内容变更参见ChangeLog:
https://logging.apache.org/log4j/2.x/changes-report.html

注意:

type在非strict xml中不识别,会报错

<Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
一般会不被识别,报出语法错误,使用下面的语句。
<MarkerFilter marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>

<Appender type="Console" name="STDOUT">
转变为
<Console name="STDOUT">

使用script,不能使用return,添加var变量,将结果赋值给变量即可。

Quick-Starter

maven依赖:

点击查看代码
<dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.17.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.17.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>2.17.1</version>
    </dependency>

Resources下创建log4j2.xml文件

点击查看代码
<Configuration status="trace" monitorInterval="5">
    <Appenders>
        <Console name="Out" target="SYSTEM_OUT">
            <PatternLayout pattern="%m%n"/>
        </Console>

    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Out"/>
        </Root>
    </Loggers>
</Configuration>

应用引入Logger使用

点击查看代码
    private static final Logger log = LoggerFactory.getLogger(App.class);

    public static void main( String[] args ) {
        log.info("1232132131");
    }

Configuration

Automatic Configuration

log4j会自动查找其配置文件,查找顺序:

  1. 系统属性指定:log4j2.configurationFile 如下所示:

System.setProperty("log4j2.configurationFile", "classpath:log4j2-aaa.xml");

但是在spring中因采用logging-starter驱动,application.properties中配置为

logging.config = classpath:log4j2-aaa.xml

  1. log4j2-test.properties > log4j2-test.yaml > log4j2-test.json > log4j2-test.xml
  2. log4j2.properties > log4j2.yaml > log4j2.json > log4j2.xml

Arbiter 仲裁 2.15.0+

代码处添加:
static {
System.setProperty("env", "uat");
}

SystemPropertyArbiter
        <SystemPropertyArbiter propertyName="env" propertyValue="dev">
            <Console name="Out">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
            </Console>
        </SystemPropertyArbiter>
        <SystemPropertyArbiter propertyName="env" propertyValue="prod">
            <Console name="Out">
                <PatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss.SSS} %m%n"/>
            </Console>
        </SystemPropertyArbiter>
Select - DefaultArbiter
        <Select>
        <SystemPropertyArbiter propertyName="env" propertyValue="dev">
            <Console name="Out">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
            </Console>
        </SystemPropertyArbiter>
        <SystemPropertyArbiter propertyName="env" propertyValue="prod">
            <Console name="Out">
                <PatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss.SSS} %m%n"/>
            </Console>
        </SystemPropertyArbiter>
            <DefaultArbiter>
                <Console name="Out">
                    <PatternLayout pattern="%d{HH:mm:ss.SSS} %m%n"/>
                </Console>
            </DefaultArbiter>
        </Select>

Additivity

additivity默认为true,例如以下的配置,目的是对于org.example包下的日志level级别是ERROR,如果有满足要求的内容,输出依托Root的AppenderRef。

        <Logger name="org.example" level="ERROR" />
        <Root level="INFO">
            <AppenderRef ref="Out"/>
        </Root>

再比如以下的配置,目的是对于org.example包下输出的内容,采用Out2的AppenderRef,和Root区分开,多用于error文件的单独输出。此时,需要添加additivity="false",不然会在Root中也会输出一遍。

        <Logger name="org.example" level="ERROR" additivity="false">
            <AppenderRef ref="Out2"/>
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="Out"/>
        </Root>

maven Testing

java testUsing
@Rule
    public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml");
 
    @Test
    public void testSomeAwesomeFeature() {
        final LoggerContext ctx = init.getLoggerContext();
        final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger");
        final Configuration cfg = init.getConfiguration();
        final ListAppender app = init.getListAppender("List");
        logger.warn("Test message");
        final List<LogEvent> events = app.getEvents();
        // etc.
    }

System Properties

log4j2的Configuration,MessageFactory都可以通过变量形式配置:
环境变量 <- log4j2.component.properties <- SystemProperties 可配置项参照官方文档。

※注意: 其中漏洞问题:log4j2.formatMsgNoLookups已在2.15.0+版本移除,变为默认关闭。可使用%m{lookups} 或 %m{nolookups}。

LookUps

所有的LookUps都必须实现StrLookup类,因此可参见StrLookup的实现类了解各自用途。
由于部分lookUp是直接静态化可直接使用,部分从properties获取信息。不可随便new出来。
参见:Interpolator类100行strLookup的创建加载过程。

Context Map Lookup

在PatternLayout中用 %X{}或${ctx:}表示。

java代码:
ThreadContext.put("loginId", "zhangsan");
或者  
MDC.put("loginId", "zhangsan");

log4j2.xml代码:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} ${ctx:loginId} %X{loginId} %m%n"/>

Kubernetes Lookup 2.13.0+

Docker Lookup 2.12.0+

Main Arguments Lookup

启动命令,其中[]:
java -jar  ****.jar  [main0]  [main1]  
例:java -jar  ****.jar  name 张三

main方法中:
MainMapLookup.setMainArguments(args);

log4j2.xml配置:
<PatternLayout pattern="${main:1} ${main:name} %d{yyyy-MM-dd HH:mm:ss.SSS}  %m%n"/>

Map Lookup

MapLookup默认从properties中获取属性。因此,采用new的方式不能传导到configuration中。但是mapLookup内容来自于properties中。

java代码:
LoggerContext.getContext(false).getConfiguration().getProperties().put("name","王麻子");

log4j2.xml:
    <Properties>
        <property name="myname" value="周星星"></property>
    </Properties>

<PatternLayout pattern="${map:myname} ${map:name} %d{yyyy-MM-dd HH:mm:ss.SSS}  %m%n"/>

MarkerLookup

MarkerLookup 采用 MarkerManager中的数据,因此使用MarkerFactory构造Marker。

 private static final Marker TEST = MarkerFactory.getMarker("TEST");

 log.error(TEST, "1232132131");
 log.error("abcdddd");

可用于filter,routers路由分流log信息到不同的文件。
<MarkerFilter marker="SQL" onMatch="ACCEPT" onMismatch="DENY"/>

Structured Data Lookup

sd需要采用StructuredDataMessage 才可以其效果。${sd:***}

Appenders

Routing 路由

大多用于Marker的数据分流写入文件

log4j2.xml写法
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="2 %d %-5level %m%n" />
        </Console>
        <RollingFile name="RollingFileInfo" fileName="log/info.log"
                     filePattern="/log/info-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <PatternLayout pattern="%m%n"/>
           <!-- <Filters>
                <MarkerFilter marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>-->
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy同一文件夹下15个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <Routing name="routing">
            <Routes>
                <Script name="RoutingInit" language="JavaScript"><![CDATA[
                        var result = '';  //赋初值没有用
                        if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("TEST")) {
                             result =  'RollingFile';
                        }else{
                            result = 'CONSOLE';
                        }
                        ]]>
                </Script>
                <Route ref="console" key="CONSOLE"/>
                <Route ref="RollingFileInfo" key="RollingFile"/>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="routing"/>
        </Root>
    </Loggers>

java部分代码:

private static final Marker TEST = MarkerFactory.getMarker("TEST");
log.error(TEST, "1232132131");

Layout

PatternLayout

类型 说明 注意
%d 时间 %date等同
%d 格式化时间
%c 类名 %logger %C %class 等同
%c Short类名 数值越大,类名越长
%M 方法名 %method等同,注意是大写,小写是message
%L %line等同,行号 注意%l为location
%l %location等同,位置 注意%L为line,示例:org.example.App.main(App.java:39)
%m 消息 %msg %message等同
%m message内部解析 默认不解析信息:%m
%t 线程名 %tn, %thread,%threadName
%T 线程ID %tn, %tid,%threadId
%highlight{pattern} 高亮
%p 日志级别 %level等同
%n 换行 常常放在末尾
%5 左padding5位 用于对齐,示例:%5c
%-5 右padding5位 用于右对齐,示例:%-5level
%maxLen{%m} 用于限制method最多输出20个字符
%throwable 异常抛出设置 等同于%xEx,%xEx{none} or %xEx{0} or %xEx{short} 值范围:["none"

Filters

过滤器可以在任何地方添加。在Configuration下添加的默认会控制所有。
也可自定义自己的过滤器,参照:扩展Filter
在Appender下添加的Filter控制当前的Appender,在Logger中添加的Filter控制当前的Filter。

BurstFilter

用于限流,控制秒级的输出量。用的不多。

CompositeFilter

复合过滤器其实就是Filter集合,用于对多条数据进行过滤,如果Deny直接拒绝,Accept直接接收,后面的过滤器不用考虑,NEUTRAL中立,不管由后面的过滤器决定。

<Filters>
    ....//FilterA
    ....//FilterB
</Filters>

DynamicThresholdFilter

The DynamicThresholdFilter allows filtering by log level based on specific attributes。需要结合ThreadContext Map.
不同的ThreadContext使用不同的level级别。实用性不强。

<DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
                          onMatch="ACCEPT" onMismatch="NEUTRAL">
    <KeyValuePair key="User1" value="DEBUG"/>
  </DynamicThresholdFilter>

MapFilter

实用性不强。

<MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
    <KeyValuePair key="eventId" value="Login"/>
    <KeyValuePair key="eventId" value="Logout"/>
</MapFilter>

MarkerFilter

根据Marker标记,来区分过滤数据。对业务中有部分特殊代码记录可这样用。比如发送对方信息,本地存证并保存数据,防止对方要求重发。

NoMarkerFilter

RegexFilter

正则匹配,太损耗性能,一般不用。

ThresholdFilter

这个比较实用,通过level区分,比如将error单独创建一个文件保留。

TimeFilter

将部分时间段的日志分离出来。不常有用。

Asynchronous Loggers

可通过系统配置直接生效。

抑或:
->
->

※注意:async 默认没有记录location信息,因此class,method,line 为空。需要设置 includeLocation="true".
※注意:异步日志依赖jar包:disruptor-3.3.4.jar

变量

  1. 因log4j2.xml在应用启动时就会加载进来,因此一般要使用环境变量或者系统变量。
${sys:value:-defaultValue}
${env:value:-defaultValue}

其中 value表示当前值,defaultValue表示默认值,注意默认值前要有-,不然会被当成一个字符串。

  1. 文本中定义的变量,需要提前在 Properties 中定义后,可直接使用。
${value}
  1. 如果数据有部分来自于maven,比如应用名称,版本等,可通过mvn的变量模式
@project.name@
@project.version@

但此种模式需要在maven的build中定义resources.

        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
posted on 2022-09-30 11:29  zhaoqiang1980  阅读(324)  评论(0编辑  收藏  举报