美文网首页
为什么用log4j代替System.out.println

为什么用log4j代替System.out.println

作者: Grasse | 来源:发表于2017-09-05 23:29 被阅读0次

    1.背景介绍

    记录日志可以作为日后处理问题的一个追溯,方便开发者根据日志来统计查询处理问题。此外,查阅日志内容可以了解项目的运行状况,发现项目存在的一些隐藏的bug。

    2.知识剖析

    Log4j是什么?

    Log4j 是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

    此外,通过Log4j其他语言接口,您可以在 C、C++、.Net、PL/SQL程序中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。

    3.常见问题

    Log4j的特点

    可以轻松的控制log信息是否显示、log信息的输出端类型、输出方式、输出格式,更加细致地控制日志的生成过程,而其通过配置文件可以灵活的进行配置而不需要大量的更改代码。

    4.解决方案

    为什么要用Log4j来替代System.out.println

    1.  Log4j就是帮助开发人员进行日志输出管理的API类库。它最重要的特点就可以配置文件灵活的设置日志信息的优先级、日志信息的输出目的地以及日志信息的输出格式。

    2.  Log4j除了可以记录程序运行日志信息外还有一重要的功能就是用来显示调试信息。

    3.  程序员经常会遇到脱离java ide环境调试程序的情况,这时大多数人会选择使用System.out.println语句输出某个变量值的方法进行调试。这样会带来一个非常麻烦的问题:一旦哪天程序员决定不要显示这些System.out.println的东西了就只能一行行的把这些垃圾语句注释掉。若哪天又需调试变量值,则只能再一行行去掉这些注释恢复System.out.println语句。

    使用log4j可以很好的处理类似情况。

    5.编码实战

    在这里就先看下log4j的一般配置

    对于配置文件的具体介绍,推荐一个网址,很详细,我觉得复制过来就没必要了。       http://www.cnblogs.com/ITtangtang/p/3926665.html

    6.思维拓展

    从占用资源的角度,我写了一个小测试来看看log4j和System.out.println的差别

    很奇怪,结果却是system.out明显优于log

    重新思考占用资源的问题,实际上是大量的io操作导致资源的占用,log4j可以通过设置配置文件来控制输出减少io操作,而system.out在代码中却是必须的输出,除非注释/删除代码。因此,这或许是system.out更占资源的原因吧?

    然后张鑫师兄的观点可能更加的专业化一点吧

    是这么说的  a、日志输出的目的地,输出到控制台的速度比输出到文件系统的速度要慢。

    b、日志输出格式不一样对性能也会有影响,如简单输出布局(SimpleLayout)比格式化输出布局(PatternLayout)输出速度要快。可以根据需要尽量采用简单输出布局格式输出日志信息。

    c、日志级别越低输出的日志内容就越多,对系统系能影响很大。

    d、日志输出方式的不同,对系统系能也是有一定影响的,采用异步输出方式比同步输出方式性能要高。

    e、每次接收到日志输出事件就打印一条日志内容比当日志内容达到一定大小时打印系能要低。

    然后就是讨论了下日常中在项目里我们常用打日志的语句

    方法1

    方法2

    方法3

    最后讨论的结果还是使用第一种方法更好  这个在视频里有讲  第二种方法如果想只打印某个类或者包中的日志  打不出来

    第三种方法需要获取logger时传入class,也就是需要写成当前类。很容易像我上面贴的例子一样犯错。

    然后今天就是老大提出了一个点,是我没有想到也没有查到的一点,我觉得在以后做项目的时候可以注意的一点

    就比如在日志等级设为info的时候,系统不会显示debug级别,但是会运行debug,当代码量很大的时候就很占用空间,所以需要一个方法不输出debug也可以在后台不运行debug

    当然同等类型的还有几类可以选择

    7.深度思考讨论

    1.李亚衡

    几台机器日志输出到一个地方是指?

    答:就是假如我有几个服务器,然后每个服务器上都有一个日志输出,但是可能输出的地方在服务器本地,这个时候为了方便查看日志,需要将这几台服务器的日志都指向同一个日志文件,便于查看。

    2.韦杰

    我们在类里面要打印日志的时候都会用下面的方式先声明一个日志实例:

    public static Logger logger = Logger.getLogger("xxx.class");

    但是给这个日志实例起名“xxx.class”有什么意义,或者说这样有什么用?

    答:把这个类的class传进去,才能创建对应class的日志对象

    3.张鑫

    如何将指定类或包的日志输出到特定的文件中?

    将指定类或包的日志输出到特定的文件中

    配置如下:

    appender定义了一个日志文件输出源。category的name字段指定了要单独大日志的包或类的路径,子字段的appender-ref则定义了这个包用哪几个日志文件输出源。

    4.王蒙

    log4j 的stdout是什么?还有其他的选择吗?

    答:stdout为标准输出,还可以自定义输出,在后面加即可

    5.甘乐

    对一个项目中的不同类,输出不同级别的日志文件,实现方法怎样?

    答:以一个例子来说

    private static Log logger = LogFactory.getLog(Test.class);

    然后在log4j.properties中加入:

    log4j.logger.cn.com.Test= DEBUG,test

    log4j.appender.test=org.apache.log4j.FileAppender

    log4j.appender.test.File=${myweb.root}/WEB-INF/log/test.log

    log4j.appender.test.layout=org.apache.log4j.PatternLayout

    log4j.appender.test.layout.ConversionPattern=%d %p [%c] - %m%n

    也就是让cn.com.Test中的logger使用log4j.appender.test所做的配置。

    6.程凯

    如何做到在任何地方输出log4j日志?

    答:实现思路就是做一个自己的Appender用于处理日志, 这本身就是log4j的运作/扩展原理

    关键点在于实现append方法

    public void append(LoggingEvent event) {

    super.append(event);

    // 所有通过log4j输出的日志都最终会到这里

    // 因此这里可以任意地处理你的日志

    System.out.println(this.layout.format(event))

    }

    7.王玉琛

    log4j2与log4j相比,特性或者说那些功能有了更好的改进?

    答:API分离

    Log4j 2的API与实现是分离的,在保证向前兼容的前提下,这让开发人员使用其类和方法时更加直观清晰。同时也让Log4j开发团队能够以一种兼容的方式更加安全地改进实现类。

    性能提升

    Log4j 2使用了下一代的异步Logger,它基于LMAX Disruptor库(一个基于环形缓冲区的高性能进程间消息库)。在多线程情景中,异步Logger比Log4j 1.x和Logback的吞吐量高了18倍,延迟也低了很多个数量级。具体的数据请看异步日志性能。Log4j 2完胜Log4j 1.x、Logback以及java.util.logging,特别是在多线程应用中,详细信息请看性能。

    支持多种API

    Log4j 2 API在提供了最佳性能的同时,还提供了对Log4j 1.2、SLF4J、Commons Logging 和 java.util.logging (JUL) API的支持(需要适配器)。

    避免封锁

    通过使用 log4j-to-slf4j 适配器,使用Log4j 2 API编写的应用通常可以选择使用任何SLF4J标准库作为logger的实现。

    自动重新加载配置文件

    和Logback类似,当配置文件被修改时Log4j 2将自动重新加载。但与Logback不同的是,在重新加载过程中它不会丢失掉日志事件。

    插件架构

    Log4j使用插件模式来配置组件,这么以来你就不用手写代码来创建并配置Appender、Layout、Pattern转换器了。当配置文件引用了某个插件时,Log4j将自动识别并使用之。

    支持属性替换

    你可以在配置文件中引用属性,Log4j会直接替换掉它们或是将其传递给底层组件来动态解析之。属性值可以来自于配置文本、系统属性、环境变量、 ThreadContext Map和事件中的数据。用户还可通过添加自己的Lookup插件来进一步定制属性提供者。

    支持Java 8 Lambda表达式

    此前,当一个日志消息需要花费比较大的代价来创建时,你通常需要先显式地检查日志级别是否允许输出。现在基于Java 8的应用可以享受Log4j Lambda表达式支持的便利,因为Lambda表达式会被延迟执行,详见示例。

    定制日志级别

    在Log4j 2中,日志级别可以通过代码或是配置文件轻松定义,无需子类化。

    不产生垃圾

    在稳定打印日志时, Log4j 2不会在单机应用中产生垃圾,在web应用中仅产生少量的垃圾。这降低了垃圾收集器的压力,同时提供了更好的响应性能。

    8.视频解析


    为什么要用Log4j_腾讯视频

    技能树.IT修真院

    “我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

    这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧~

    直接点击此链接:http://www.jnshu.com/login/1/13516932

    相关文章

      网友评论

          本文标题:为什么用log4j代替System.out.println

          本文链接:https://www.haomeiwen.com/subject/vvvpjxtx.html