`
zl378837964
  • 浏览: 189678 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

升级log4j 2.x版本 缓存异步化配置解读

    博客分类:
  • java
阅读更多

 转载请注明出处:http://zl378837964.iteye.com/blog/2359382

 

现在最新的Log4j 2 是V2.8版本,使用2.x版本需要引入jar如下:

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.5</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>2.5</version>
</dependency>

 下面两个分别是兼容V1.x 和 实现异步化需要的jar:

(Disruptor它是开源的并发框架,能够在无锁的情况下实现网络的Queue并发操作。)

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-1.2-api</artifactId>
	<version>2.5</version>
</dependency>
(注意:require disruptor-3.3.3.jar or higher)
<dependency>
	<groupId>com.lmax</groupId>
	<artifactId>disruptor</artifactId>
	<version>3.3.4</version>
</dependency>

     

        V2.x版本的配置方式,除了编码式的写入,还有XML, JSON, YAML 和 Properties(注意这个是V2.4之后重新支持的,配置方式类似XML和 JSON不同于以往V1.x版本) 配置文件 on the classpath 即可实现,还有定义变量,过滤设置,定时删除日志,支持JDK8的Lambda等新特性;还能兼容 Log4j 1.2, SLF4J, Commons Logging 和 java.util.logging (JUL) APIs等各个日志工具;也可以定时重载配置文件,只需简单添加如下:

<Configuration monitorInterval="30" status="INFO">

... 单位是s,最小间隔5s

... 共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF

</Configuration>

 

 

若想使用YAML格式,需要引入格式化工具如下:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.8.5</version>
</dependency>

 若想使用JSON格式,需要引入格式化工具如下:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.8.5</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.8.5</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.8.5</version>
</dependency>

 

### Log4j2最突出即支持高效低延迟的异步化写日志 ###

 

Asynchronous Loggers是一个新增特性在Log4j 2 ,可以实现完全异步也可以和同步混合使用,还可以只异步化Appender,以提升系统性能,官方数据显示混合没有完全异步化效果好(下图)。

多情况对比

1、完全异步化XML配置+参数如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
    <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
      </PatternLayout>
    </RandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="info" includeLocation="false">
      <AppenderRef ref="RandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

 注意啦,注意啦!配置参数!

A.想要loggers完全异步化一定不要忘记设置启动参数: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector 

B.或者,建立log4j2.component.properties文件放classpath下面,log4j2会在启动时自动加载,然后日志输出就变成异步输出。

文件内容:Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

 

2、Mixed同步和异步,由于使用了disruptor,标签化实现不再需要设置启动参数(关于Log4jContextSelector);

<asyncRoot> 或 <asyncLogger>可以和<root> 或 <logger>混合使用。

混合使用的xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- No need to set system property "Log4jContextSelector" to any value when using <asyncLogger> or <asyncRoot>. -->
<Configuration status="WARN">
  <Appenders>
    <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
    <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
              immediateFlush="false" append="false">
      <PatternLayout>
        <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
      </PatternLayout>
    </RandomAccessFile>
  </Appenders>
  <Loggers>
    <!-- pattern layout actually uses location, so we need to include it -->
    <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
      <AppenderRef ref="RandomAccessFile"/>
    </AsyncLogger>
    <Root level="info" includeLocation="true">
      <AppenderRef ref="RandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

eg.一个完整项目XML配置实例如下: 

 

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
    <Properties>
        <Property name="baseDir">/Users/chocolate/logs</Property>
        <Property name="filename">/Users/chocolate/logs/baseCollection.log</Property>
        <Property name="filenameError">/Users/chocolate/logs/baseCollectionError.log</Property>
    </Properties>

    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
        </Console>
        <RollingFile name="RollingFile" fileName="${filename}"
                     filePattern="${baseDir}/${date:yyyy-MM}/baseCollection-%d{yyyy-MM-dd-HH-mm}.log.gz">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy interval="10" modulate="true"/>
            </Policies>
            <!--自动删除超过120天的日志压缩文件-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/baseCollection-*.log.gz"/>
                    <IfLastModified age="20d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <!--错误日志入文件-->
        <RollingFile name="RollingFileError" fileName="${filenameError}"
                     filePattern="${baseDir}/${date:yyyy-MM}/baseCollectionError-%d{yyyy-MM-dd-HH}.log">
            <PatternLayout pattern="%d %-5level [%t]%l - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200 MB"/>
                <TimeBasedTriggeringPolicy interval="24" modulate="true"/>
            </Policies>
            <!--自动删除超过120天的日志压缩文件-->
            <DefaultRolloverStrategy>
                <Delete basePath="${baseDir}" maxDepth="2">
                    <IfFileName glob="*/baseCollectionError-*.log"/>
                    <IfLastModified age="30d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!--采用异步输出日志-->
        <AsyncLogger name="com.choco" level="info">
            <!--写入info级别-->
            <AppenderRef ref="RollingFile"/>
            <!--写入error级别-->
            <AppenderRef ref="RollingFileError" level="error"/>
        </AsyncLogger>
        <Root level="debug">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

 注意点:

<I>

有时候会出现同一日志文件中log4j日志打印重复,这是因为如下配置中 Console 被设置成logger和root的appender了,

此时只需要设置additivity="false"即可解决。(the appender associated with logger com.foo.Bar is first used, which writes the first instance to the Console. Next, the parent of com.foo.Bar, which in this case is the root logger, is referenced. The event is then passed to its appender, which is also writes to the Console, resulting in the second instance.)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <!--控制输出trace,不继承-->
    <Logger name="com.foo.Bar" level="trace" additivity="false">
      <!--控制台打印指定包路径下面的info以上-->
      <AppenderRef ref="Console" level="info"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

 

<II> 

Log4jV1.x升级V2.x需注意,原项目用的是log4j或者self4j,获取logger方式不同:

Log4j实例:

import org.apache.log4j.Logger;

private static final Logger LOGGER = Logger.getLogger(X.class);

Slf4j实例: 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(X.class);

Log4j2的使用: 

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

private static final Logger logger = LogManager.getLogger(X.class);

Log4j V2.x基于上面不同提供了转换包,只需要导入几个转换包就可以透明的使用Log4j2配置,从而避免大工程中的代码修改,耶耶耶!

但是,官方出来几个限制条件:

  1. They must not access methods and classes internal to the Log4j 1.x implementation such as Appenders, LoggerRepository or Category's callAppenders method.
  2. They must not programmatically configure Log4j.
  3. They must not configure by calling the classes DOMConfigurator or PropertyConfigurator.

<III> 

 log4j输出缓存日志以8K为单位,磁盘的一个block为8K,这样可以减少碎片;也就是说假设你设置缓存为20K,log4j在16K(8K*2)的时候就会输出),而不是20K。

 

附录A:

Appenders 官方文档:http://logging.apache.org/log4j/2.x/manual/appenders.html(23种应有尽有)

Async Low-Latency Loggers 官方文档:http://logging.apache.org/log4j/2.x/manual/async.html

log4j 2 官方配置:http://logging.apache.org/log4j/2.x/manual/configuration.html

 

附录B:

Properties configuration files support the advertiser, monitorInterval, name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest attrbutes. See Configuration Syntax for the definitions of these attributes.(Props方式在V2.x不通用于各个版本,不建议使用)

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.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
 
appender.list.type = List
appender.list.name = List
appender.list.filter.threshold.type = ThresholdFilter
appender.list.filter.threshold.level = error
 
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

 

1
0
分享到:
评论

相关推荐

    基于SpringBoot2.6.4的电商系统源码.zip

    12. **日志管理**:使用Logback或Log4j记录系统日志,便于问题排查。 三、技术栈解读 1. **Spring Cloud**:如果项目采用微服务架构,可能会引入Spring Cloud,实现服务发现、负载均衡、配置中心等功能。 2. **...

    Node.js v0.10.35 Manual & Documentation.pdf

    4. **require.cache**:缓存已经加载的模块,防止重复加载。 5. **require.extensions**:用于配置文件扩展名与加载方法之间的关联。 ### Timers(定时器) 1. **setTimeout**, **clearTimeout**:分别用于设置和...

    nginx全局说明.doc

    - **热部署与不间断服务**:Nginx 支持热部署,即可以在不停止服务的情况下更新配置文件或升级软件版本,这极大地方便了运维人员进行维护和管理。 #### 二、Nginx 的特点 - **高并发处理能力**:得益于其高效的...

    java oa系统

    10. Log4j或SLF4J:日志管理,用于问题排查和性能优化。 本案例中的“OA2”可能是该OA系统的某个版本或者特定模块的名称,具体功能和结构需要根据实际项目代码来解读。在进一步探索之前,开发者需要具备扎实的Java...

    resin源码解读

    ### Resin源码解读知识点概览 #### 一、引言 Resin是一款高性能的Java应用服务器和Web容器,以其轻量级、高效的特点而受到众多开发者的青睐。本篇文章将对Resin的部分核心功能进行深入解读,包括但不限于启动日志...

    kafka使用手册

    2. **异步发送**: 利用异步发送功能提高性能。 3. **错误处理**: 处理发送过程中可能出现的错误情况。 #### 九、Kafka Consumer 的使用 **Consumer API** 使消费者能够订阅主题并消费消息。正确配置和使用 ...

    Apache RocketMQ开发者指南.pdf

    1. **LogAppender样例**:提供在RocketMQ中如何集成不同日志框架(如log4j、logback)的示例代码。 2. **OpenMessaging样例**:展示了如何在RocketMQ中实现OpenMessaging接口,这使得RocketMQ可以与其他消息系统...

    Shypost企业网站管理系统源码

    9. **日志和监控**:系统可能集成了Log4j、SLF4J等日志框架和Prometheus、Grafana等监控工具,这些都是保障系统稳定运行的关键。 10. **设计模式**:源码中可能运用了单例、工厂、观察者、装饰者等设计模式,有助于...

    zswin后台管理框架.7z

    同时,日志记录功能也必不可少,如Log4j或SLF4J,便于调试和追踪问题。 6. **单元测试与集成测试**:为了保证代码质量,框架可能会集成JUnit或其他测试工具,支持单元测试和集成测试的编写。 7. **性能优化**:...

    2021最新版运维面试题.pdf

    由于文件内容较多,这里选择部分重要知识点进行详细解读: 1. LVS负载均衡策略: LVS(Linux Virtual Server)是一个开源的负载均衡软件。其负载均衡策略包括: - 轮询调度(Round Robin):按请求顺序依次分配给...

    jquery帮助文档解析

    ### 2. DOM操作 jQuery提供了丰富的DOM操作方法,包括添加、删除和修改元素。例如,`$(selector).append(content)`在选定元素后添加内容,`$(selector).remove()`移除选定元素,而`$(selector).html(newHTML)`则...

    Java开发典型模块大全(仅含程序源码)-20个Java项目

    13. **日志管理**:如Log4j、SLF4J和Logback,理解日志记录的重要性及其实现。 14. **安全**:涉及密码加密、身份验证、权限控制等,学习如何保护应用的安全性。 15. **数据缓存**:如Redis、Memcached,了解如何...

    安卓Android商品销售管理系统源码.zip

    本篇文章将详细解读一个基于Android平台的商品销售管理系统的源码,帮助读者深入理解Android应用开发的核心技术以及在实际业务场景中的应用。 一、系统架构 Android商品销售管理系统通常采用MVC(Model-View-...

    CSDN 小秘书 源码下载

    源码中的异常捕获和日志系统,如使用log4j、Logcat或Swift的print语句,能帮助开发者追踪程序运行状态。 最后,作为一个持续更新的项目,CSDN小秘书的源码管理也非常重要。版本控制工具如Git的应用,可以确保代码的...

    MySQL后端面试题汇总.zip

    除了MySQL,描述中还提到了其他技术,如MongoDB(非关系型数据库)、Python(后端编程语言)、Go(高性能编程语言)、数据结构与算法(基础编程能力)、中间件(如消息队列,缓存系统)等,这些也是后端开发者应具备...

    一个RESTful的文件下载方法

    - 使用`log.info()`记录了方法的开始和结束,以及传递进来的文件ID。 - 这有助于调试和维护,便于追踪程序执行流程。 2. **实体获取**: - 通过`em.find(Resume.class, id)`获取数据库中的`Resume`实体,其中`id...

    关于h5中的fetch方法解读(小结)

    其核心优势在于能够更好地配合Service Workers,从而实现缓存策略优化和离线访问。例如,通过Service Workers和浏览器的IndexedDB结合,可以在客户端存储大量数据,使得网页在离线状态下仍能提供服务。然而,这种...

    java图像压缩源码-Volley:Volley框架,添加注释,方便解读和学习

    JSON,图像等的异步下载; 网络请求的排序(scheduling); 网络请求的优先级处理; 缓存; 多级别取消请求; 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求). json请求: mQueue = Volley....

    Mysql性能优化教程

    - 索引查询效率接近二分查找,复杂度约为O(log N)。 - 在某些极端场景下,可以使用单向有序序列代替索引来进一步提升查询效率。 - **如何理解数据索引的结构**: - 默认采用B树索引,内存表可能会使用哈希索引。 ...

    go代码-teaService

    `teaService`的`main.go`文件可能包含了服务的初始化、配置加载、路由设置以及服务的启动逻辑。 3. **结构体与接口**: Go语言支持面向对象编程,通过结构体和接口实现。在`teaService`中,可能会定义一些结构体来...

Global site tag (gtag.js) - Google Analytics