欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Log4j-配置信息详解

程序员文章站 2022-05-24 15:29:13
...

log4j的初始化

  log4j的初始化方式如下:

private static final Logger log = Logger.getLogger(Log4jTest.class);

  该Logger类是继承自Category类,实现的是AppenderAttachable接口,如下:

Log4j-配置信息详解

  而Category类又继承自java.lang.Object,如下就是官方文档中的介绍:

java.lang.Object
  -- extended by org.apache.log4j.Category
      -- extended by org.apache.log4j.Logger

  而在Log4j初始化时,是在Logger类中完成对log4j的获取,如下:

    public static Logger getLogger(Class clazz) {
        return LogManager.getLogger(clazz.getName());
    }

  在LogManager中完成对log4j静态配置资源的加载,该加载方式是通过静态代码块来实现的,如下:

static {
        Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
        repositorySelector = new DefaultRepositorySelector(h);
        String override = OptionConverter.getSystemProperty("log4j.defaultInitOverride", (String)null);
        if (override != null && !"false".equalsIgnoreCase(override)) {
            LogLog.debug("Default initialization of overridden by log4j.defaultInitOverrideproperty.");
        } else {
            String configurationOptionStr = OptionConverter.getSystemProperty("log4j.configuration", (String)null);
            String configuratorClassName = OptionConverter.getSystemProperty("log4j.configuratorClass", (String)null);
            URL url = null;
            if (configurationOptionStr == null) {
                url = Loader.getResource("log4j.xml");
                if (url == null) {
                    url = Loader.getResource("log4j.properties");
                }
            } else {
                try {
                    url = new URL(configurationOptionStr);
                } catch (MalformedURLException var7) {
                    url = Loader.getResource(configurationOptionStr);
                }
            }

            if (url != null) {
                LogLog.debug("Using URL [" + url + "] for automatic log4j configuration.");

                try {
                    OptionConverter.selectAndConfigure(url, configuratorClassName, getLoggerRepository());
                } catch (NoClassDefFoundError var6) {
                    LogLog.warn("Error during default initialization", var6);
                }
            } else {
                LogLog.debug("Could not find resource: [" + configurationOptionStr + "].");
            }
        }

    }

  在加载完静态资源后,直接调用getLogger()方法完成初始化操作。

    public static Logger getLogger(String name) {
        return getLoggerRepository().getLogger(name);
    }

  该操作最终返回的是一个NOPLogger对象,如下:

    public Logger getLogger(String name) {
        return new NOPLogger(this, name);
    }

Log4j的日志记录级别

  通用日志包把消息分为6个级别:FATAL、ERROR、WARN、INFO、DEBUG和TRACE。其中FATAL级别最高,TRACE级别最低。其级别的定义是在Priority类中进行的,部分源码如下:

    public static final Level OFF = new Level(2147483647, "OFF", 0);
    public static final Level FATAL = new Level(50000, "FATAL", 0);
    public static final Level ERROR = new Level(40000, "ERROR", 3);
    public static final Level WARN = new Level(30000, "WARN", 4);
    public static final Level INFO = new Level(20000, "INFO", 6);
    public static final Level DEBUG = new Level(10000, "DEBUG", 7);
    public static final Level TRACE = new Level(5000, "TRACE", 7);
    public static final Level ALL = new Level(-2147483648, "ALL", 7);

  通过如上信息我们不难看出,log4j通过在构造函数中为level参数赋值,然后在后面比较大小来判断日志的所属级别的,基本上level参数值越大,日志相应的级别就越高。

    protected Level(int level, String levelStr, int syslogEquivalent) {
        super(level, levelStr, syslogEquivalent);
    }

  其调用的接口如下:

log4j接口 说明(只有当输出日志的级别大于或等于为日志配置器配置的日志级别时,这个方法才会执行)
off 最高等级的,用于关闭所有日志记录。
fatal(Object message) 输出FATAL级别的消息。
error(Object message) 输出ERROR级别的消息。
warn(Object message) 输出WARN级别的消息。
info(Object message) 输出INFO级别的消息。
debug(Object message) 输出DEBUG级别的消息。
trace(Object message) 输出TRACE级别的消息。
all 最低等级的,用于打开所有日志记录

Appenders

  Log4j日志系统允许把日志输出到不同的地方,如控制台(Console)、文件(Files)、根据天数或者文件大小产生新的文件、以流的形式发送到其它地方等等。

输出方式 说明(注意,该下面的信息比较全,但是由于版本不同,可能有些并不能使用)
AsyncAppender 接受对其他应用程序的引用,并在一个单独的线程上为它们编写日志事件。
CassandraAppender 将日志信息输出到Apache Cassandra数据库中
ConsoleAppender 将日志信息输出到控制台
FailoverAppender 如果主应用程序失败了,次级应用程序将会被尝试直到一个成功,或者没有更多的辅助程序来尝试。
FileAppender 将日志信息输出到文件
FlumeAppender Apache Flume是一个分布式、可靠和可用的系统,可以有效地收集、聚集和将大量的日志数据从许多不同的数据源转移到集中的数据存储中。FlumeAppender将LogEvents发送给一个Flume代理,作为序列化的Avro事件用于消费。
JDBCAppender 使用标准JDBC将日志事件写入到关系数据库表中。
JMS Appender 将格式化的日志事件发送到一个JMS目的地。
JPAAppender 使用Java Persistence API 2.1将日志事件写到一个关系数据库表中。
HttpAppender 通过HTTP发送日志事件。
KafkaAppender 将事件记录到Apache Kafka的主题中。
MemoryMappedFileAppender 将指定文件的一部分映射到内存中,并将日志事件写入到该内存中,这依赖于操作系统的虚拟内存管理器来将更改同步到存储设备。
NoSQLAppender 使用内部的轻量级提供程序接口将日志事件写到NoSQL数据库中。目前存在MongoDB和Apache CouchDB的提供者实现,并且编写一个自定义提供程序非常简单。
OutputStreamAppender 为许多其他应用程序提供了基础,比如将事件写入输出流的文件和套接字应用程序。但它不能被直接配置。
RandomAccessFileAppender 随机accessfileappender与标准的FileAppender类似,但它总是被缓冲(这不能被关闭),在内部它使用ByteBuffer+随机访问文件,而不是一个BufferedOutputStream。
RewriteAppender 允许LogEvent在被另一个Appender处理之前进行操作。这可以用来屏蔽诸如密码之类的敏感信息,或者在每个事件中注入信息。
RewritePolicy RewritePolicy是一个接口,它允许实现在将日志事件传递给Appender之前进行检查和修改。
RollingFileAppender 文件大小到达指定尺寸的时候产生一个新的文件
RollingRandomAccessFileAppender 类似于标准RollingFileAppender除了它总是缓冲(这不能关闭)以及它使用一个内部ByteBuffer + RandomAccessFile BufferedOutputStream。
RoutingAppender 评估LogEvents,然后将它们路由到一个附属的Appender。
SMTPAppender 在特定的日志记录事件发生时发送电子邮件,通常是在errors或fatal errors上。
SocketAppender 是一个OutputStreamAppender,它将输出写到一个由主机和端口指定的远程目的地。数据可以通过TCP或UDP发送,可以以任何格式发送。您可以选择使用SSL来保护通信。
SyslogAppender 是一个SocketAppender,它将其输出写到一个由主机和端口指定的远程目的地,其格式与BSD Syslog格式或RFC 5424格式一致。数据可以通过TCP或UDP发送。
ZeroMQ/JeroMQ Appender ZeroMQ appender使用JeroMQ库将日志事件发送到一个或多个ZeroMQ端点。
DailyRollingFileAppender 每天产生一个日志文件
WriterAppender 将日志信息以流格式发送到任意指定的地方

Layouts

  有时用户希望根据自己的喜好格式化自己的日志输出。Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供了 四种日志输出样式,如根据HTML样式、*指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式等等。

日志输出样式(Log4j的输出样式) 说明
CSV Layouts 这个布局创建逗号分隔值(CSV)记录,并需要Apache Commons CSV 1.4。
GELF Layout 在 Graylog Extended Log Format (GELF) 1.1中列出。如果日志事件数据大于1024字节(压缩阈值),那么这个布局将JSON压缩到GZIP或ZLIB(压缩类型)。此布局不实现分块。
HTML Layout 生成一个HTML页面,并将每个LogEvent添加到表中的一行中。
JSON Layout 将一系列JSON事件作为字符串序列化为字节。
Pattern Layout 一个可配置模式字符串的灵活的布局。这个类的目标是格式化一个LogEvent并返回结果。结果的格式取决于转换模式。
RFC5424 Layout 顾名思义,Rfc5424Layout格式与RFC 5424一致,这是增强的Syslog规范。
Serialized Layout 序列化的布局只是使用Java序列化将LogEvent序列化为一个字节数组。序列化的布局不接受任何参数。
Syslog Layout 将LogEvent格式化为与Log4j 1.2所使用的相同格式的BSD Syslog记录。
XML Layout 在log4j.dtd中定义了一系列事件元素。
YAML Layout 将一系列的YAML事件作为字节序列化。


  使用方式:

    log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN

Patterns

  为log4j提供自定义的日志输出格式。

符号(log4j提供的符号) 说明
-X号 X信息输出时左对齐
%p 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出日志信息所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%l 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
%x 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中
%% 输出一个”%”字符
%F 输出日志消息产生时所在的文件名称
%L 输出代码中的行号
%m 输出代码中指定的消息,产生的日志具体信息
%n 输出一个回车换行符,Windows平台为”/r/n”,Unix平台为”/n”


  应用举例:

符号 说明
%20c 指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
%-20c 指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,”-“号指定左对齐。
%.30c 指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
%20.30c 如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉。
%d{yyyy-MM-dd HH:mm:ss} %5p %t %-5l - %m%n 输出的格式为:“2018-01-20 16:11:04 INFO main com.lyc.log4j.Log4jTest.testConsole(Log4jTest.java:13) - 这里是在控制台中输出的信息。”

Log4J的使用

建立Logger实例

  语法表示:

public static Logger getLogger( String name)

  实际使用:

static Logger logger =Logger.getLogger(ServerWithLog4j.class.getName ());

读取配置文件

语法 说明
BasicConfigurator.configure() 自动快速地使用缺省Log4j环境。
PropertyConfigurator.configure(String configFilename) 读取使用Java的特性文件编写的配置文件。
DOMConfigurator.configure(String filename) 读取XML形式的配置文件。
配置文件放在工程的根目录 无需手写调用方法,程序会自动找到配置文件。

插入日志信息

调用方法 说明
Logger.debug(Object message); 调试信息
Logger.info(Object message) 一般信息
Logger.warn(Object message) 警告信息
Logger.error(Object message) 错误信息
Logger.fatal(Object message) 致命错误信息

log4j配置文件

配置根Logger

  其语法为:

log4j.rootLogger = [ level ] , appenderName1,appenderName2, …

  level是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定 义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。

  appenderName:就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。例如:

log4j.rootLogger=info,A1,B2,C3

配置日志信息输出目的地

  其语法为:

log4j.appender.appenderName =fully.qualified.name.of.appender.class

  可配置参数,例如ConsoleAppender:

ConsoleAppender(参数) 说明
Threshold=WARN 指定日志消息的输出最低层次
ImmediateFlush=true 默认值是true,意谓着所有的消息都会被立即输出。
Target=System.err 默认情况下是:System.out,指定输出控制台

Log4J对应用性能的影响

  如果在程序运行中输出大量日志,显然会对应用的性能造成一定的影响。Log4J对性能的影响取决于以下因素:

  • 日志输出目的地:输出到控制台的速度和输出到文件系统的速度是不一样的。
  • 日志输出格式:格式简单,速度也更快。
  • 日志级别:日志级别设置的越低,输出的日志内容越多,对性能的影响也越大。
相关标签: log4j