一、背景


最近由于项目需要开始捣鼓项目组日志系统,日志系统中日志打印采用的是log4j2,同时需要支持公司日志采集需求,所以也会用到公司扩展的appender。之前做过的项目有有日志打印的功能也是采用log4j2组件。这篇文章主要是对这个组件的各个属性进行下总结,同时介绍下如何基于log4j2的Appender自定义Appender,满足项目需求。后边也会陆续的对log4j2的原理、性能等进行分析......

二、log4j2日志组件属性介绍


1.关于配置文件的名称以及在项目中的存放位置

log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn"。

系统选择配置文件的优先级(从先到后)如下:

(1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件。

(2).classpath下的名为log4j2-test.xml的文件。

(3).classpath下名为log4j2.json 或者log4j2.jsn的文件。

(4).classpath下名为log4j2.xml的文件。

我们一般默认使用log4j2.xml进行命名。如果本地要测试,可以把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml即可。

2.缺省默认配置文件

3.配置文件节点解析

(1). 根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger)。

status用来指定log4j本身的打印日志的级别。monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s,例如:monitorInterval=”600” 指log4j2每隔600秒(10分钟),自动监控该配置文件是否有变化,如果变化,则自动根据文件内容重新配置。

(2).Appenders节点,常见的有三种子节点:Console、RollingFile、File。

Console节点用来定义输出到控制台的Appender。

name:指定Appender的名字。

target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT。

PatternLayout:输出格式,不设置默认为:%m%n。

如:

RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender。

name:指定Appender的名字。

fileName:指定输出日志的目的文件带全路径的文件名。

PatternLayout:输出格式,不设置默认为:%m%n。

filePattern:指定新建日志文件的名称格式。

Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志。

TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am。

SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小。

DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。

如:

File节点用来定义输出到指定位置的文件的Appender。

name:指定Appender的名字。

fileName:指定输出日志的目的文件带全路径的文件名。

PatternLayout:输出格式,不设置默认为:%m%n。

相对RollingFile来说File在项目中用的比较少。

(3).Loggers节点,常见的有两种:Root和Logger。

Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender。

Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点。

AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root。如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。

(4).关于日志level

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

All:最低等级的,用于打开所有日志记录.

Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出。

Debug:指出细粒度信息事件对调试应用程序是非常有帮助的。

Info:消息在粗粒度级别上突出强调应用程序的运行过程。

Warn:输出警告及warn以下级别的日志。

Error:输出错误信息日志。

Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志。

OFF:最高等级的,用于关闭所有日志记录。

程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少

4.比较完整的log4j2.xml配置模板

三、自定义Appender

虽然log4j2自带了很多种Appender,通过这些Appender可以将日志输出到文件、DB、ES,但是有时候需要自定义Appender来满足业务需求,将日志输出到指定的位置。例如log4j2就没有为Scribe添加appender。

自定义Appender,继承 AbstractAppender 只需要覆盖自已想要的方法即可。

构建自定义的Appender需要注意以下几个点:

- @Plugin..注解:这个注解,是为了在之后配置log4j2.xml时,指定的Appender Tag。
- 构造函数:除了使用父类的以外,也可以增加一些自己的配置。
- 重写append()方法:这里面需要实现具体的逻辑,日志的去向。
- createAppender()方法:主要是接收log4j2.xml中的配置项。

先借用下大牛的代码:https://github.com/hawkingfoo/log-demo

贴一下实例分析下:

package logger;

import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;

import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * Created by hawkingfoo on 2017/6/29 0029.
 */
/*name就是在配置文件中要用到的标签<FileAppender/>*/
@Plugin(name = "FileAppender", category = "Core", elementType = "appender", printObject = true)
public class FileAppender extends AbstractAppender {
    private String fileName;

/* 构造函数,除了实现父类需要的参数以外,还可以自定义需要的参数 */
    public FileAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, String fileName) {
        super(name, filter, layout, ignoreExceptions);
        this.fileName = fileName;
    }

/* 覆盖append方法,实现自定义功能,比如将日志写入文件或者发送到日志收集中心等 */
    @Override
    public void append(LogEvent event) {
        final byte[] bytes = getLayout().toByteArray(event);
        writerFile(bytes);

}

/* 接收配置文件中的参数 */
    @PluginFactory
    public static FileAppender createAppender(@PluginAttribute("name") String name,
                                              @PluginAttribute("fileName") String fileName,
                                              @PluginElement("Filter") final Filter filter,
                                              @PluginElement("Layout") Layout<? extends Serializable> layout,
                                              @PluginAttribute("ignoreExceptions") boolean ignoreExceptions) {
        if (name == null) {
            LOGGER.error("no name defined in conf.");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        // 创建文件
        if (!createFile(fileName)) {
            return null;
        }
        return new FileAppender(name, filter, layout, ignoreExceptions, fileName);
    }

private static boolean createFile(String fileName) {
        Path filePath = Paths.get(fileName);
        try {
            // 每次都重新写文件,不追加
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }
            Files.createFile(filePath);
        } catch (IOException e) {
            LOGGER.error("create file exception", e);
            return false;
        }
        return true;
    }

private void writerFile(byte[] log) {
        try {
            Files.write(Paths.get(fileName), log, StandardOpenOption.APPEND);
        } catch (IOException e) {
            LOGGER.error("write file exception", e);
        }
    }
}

参考资料

https://my.oschina.net/kkrgwbj/blog/734530

http://www.cnblogs.com/hafiz/p/6170702.html

http://blog.csdn.net/z69183787/article/details/52403027

http://blog.csdn.net/heyutao007/article/details/72773077

http://blog.csdn.net/u010201484/article/details/51723455

http://m.blog.csdn.net/f59130/article/details/74014729

log4j2配置详解及自定义Appender相关推荐

  1. Log4j2配置详解

    一.背景 最近由于项目的需要,需要将日志全部迁移成 log4j2 版本,之前对于项目日志的配置总是似懂非懂,最近详细整理了下知识点,本文就作为一个记录来详细记录一下 log4j2 配置的相关知识点. ...

  2. log4j2 配置详解及使用范例

    最近项目需求需要将log4j1.2 升级到log4j2,摸索了好久,得出一点经验给大家分享. 1.log4j2 官网下载最新jar包(目前log2j2都是beta版) 导入入log4j-api-2.0 ...

  3. SpringBoot整合Log4j2以及配置详解

    文章目录 标题SpringBoot整合Log4j2以及配置详解 1.加入依赖 2.在src.java.main.resources目录下创建log4j2.xml文件 log4j2.xml文件内容如下: ...

  4. log4j2的使用及配置详解

    前言 众所周知,最近log4j被测出了漏洞,先是log4j2被测出了漏洞,漏洞影响范围为Log4j2.x <= 2.14.1:后来又被测出log4j1.X也有漏洞,范围为整个1.X版本.我们项目 ...

  5. Log4j介绍,log4j.properties配置详解

    http://www.cnblogs.com/simle/archive/2011/09/29/2195341.html本文主要解释log4j的配置文件各个配置项的含义,内容是从网上转载的 1.Log ...

  6. SpringBoot—整合log4j2入门和log4j2.xml配置详解

    关注微信公众号:CodingTechWork,一起学习进步. 引言   对于一个线上程序或者服务而言,重要的是要有日志输出,这样才能方便运维.而日志的输出需要有一定的规划,如日志命名.日志大小,日志分 ...

  7. Log4j日志配置详解(Log4j2)

    Log4j日志配置详解 一.Log4j升级Log4j2 首先来说一下日志升级,log4j配置的变化,配置文件从log4j.xml变成了log4j2.xml,配置文件的内容也有很大不同,log file ...

  8. logback 常用配置详解(二) appender

    详细整理了logback常用配置 不是官网手册的翻译版,而是使用总结,旨在更快更透彻的理解其配置 logback 简介 logback常用配置详解(一)<configuration> an ...

  9. logback 常用配置详解appender

    logback 常用配置详解 <appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的 ...

  10. SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解

    1.预置演示环境 这个演示环境继续沿用 SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境. 2.自定义配置类 ...

最新文章

  1. TIOBE 1 月编程语言:Python 摘得 2020 年度编程语言!
  2. FreeImage加速保存图像
  3. SAP云平台cf push命令报错的解决方法
  4. 作者:马浚诚(1987-),男,中国农业科学院农业环境与可持续发展研究所助理研究员。...
  5. 转录组+微生物组联合解密困扰50年的丛枝菌根共生“自我调节”中枢分子网络机制...
  6. 为什么 Go 的泛型一拖再拖?(转)
  7. Spring IOC知识点一网打尽!
  8. [洛谷U22157]刷水题(数位dp)(hash)
  9. 精仿B站播放器外加弹幕库源码-带后台
  10. 互联网大厂的薪资和职级一览
  11. Matlab功率驱动,matlab 驱动 电机问题
  12. Python编辑器你选哪个?我选PyCharm
  13. 网赚项目 - 利用社区广告牌,空手赚钱创业项目
  14. 点击劫持(clickjacking)
  15. 幼儿园计算机认识键盘上课教案,认识键盘教案
  16. 高中数学,向量高考真题解题技巧(快速口算)
  17. vue分类筛选方法,filer
  18. Anchor-based 与 Anchor-free
  19. 数据库工程师考点2023
  20. 小小拷贝-strcpy洒洒水啦

热门文章

  1. upload上传, 取各类文件的名字
  2. win11开机音效设置的方法
  3. java类加载器不同导致SPI 报错 not a subtype
  4. 设计一图书信息管理系统,实现以下功能:系统以菜单方式工作,图书信息录入功能(图书信息用文件保存) ;
  5. Qt QLabel的修改形状显示圆形
  6. 可以讨论HTML5的QQ群有哪些,QQ群有哪些种类你都知道吗?
  7. 开篇一:基于ESP8266的电子墨水屏万年历
  8. 教师计算机基础培训心得,教师集中培训心得体会
  9. Vue 事件修饰符(stop、prevent、self、capture、once、passive)
  10. dede 表单必填_dede自定义表单“必填项”设置方法