如何正确使用log4j?

关键字: 如何正确使用log4j?

Java Web开发的过程中,通过会采用输出log的方式来进行调试,产品上线之后,也通常使用log来记录系统的运行状态。最简单的输出log的方式就是使用System.out.println(String msg)和System.err.println(String msg),然而这种方式的弊端是显而易见的,例如:
1. 调试期输出log的代码,在上线运行前需要注释掉,否则可能会影响系统性能或者造成日志文件过于庞大。当出现问题需要跟踪的时候,又需要修改代码,删除注释符以打开这些debug的log,非常不方便;
2. 所有的业务的log都会输出到一个文件中去,查看起来很不方便。
 
    多亏apache开源社区为所有Java开发者提供了Log4j这个非常弓虽大的log工具,把我们从 维护log的繁重工作中解脱了出来。Log4j可能通过配置文件实现多logger,每个logger可以有不同的输出文件、输出格式和log级别,具体 细节我就不再赘述,不了解的同学可以参考相关的文档或者示例代码。
 
    这里主要总结几点Log4j使用过程中的常见问题和注意事项,阅读一下内容之前,下面的文章将假设你已经有一定的Log4j使用经验了。
 
  • 1. 获取Logger实例的方法:
protected static final Logger logger = Logger.getLogger("logger_name");
private static final Logger logger = Logger.getLogger("logger_name");
 
还有一个获取Logger的方法:
Logger.getLogger(Class clazz);
 
1.1 为什么要加“static”?
    因为同一个logger name对应唯一的Logger实例,而Logger.getLogger方法在从logger容器中取logger的过程中,有一个步骤被加了同步锁, 这就造成了如果在多线程的竞争环境中频繁地调用getLogger操作,有可能会造成堵塞。而且这种操作是没有价值的,所以使用static来保证需要需 用Logger的类所有的对象共享一个Logger的引用,并且只获取一次就可以了。
1.2 为什么要加“final”
    防止多logger同时使用时,Logger引用不小心被赋值,这是一个良好的编程习惯。
1.3 Logger.getLogger(String loggerName)与Logger.getLogger(Class clazz)有什么区别?
    本质上是一样的,Logger.getLogger(Class clazz)方法实际上是调用了Logger.getLogger(clazz.getName())来获取Logger的。
1.4 log4j配置文件中没有配置logger_name对应的logger怎么办?
    如果没有logger_name对应的配置,则Logger.getLogger方法返回默认的logger。
 
  •  2. Logger共有6个log级别,按优先级由低到高排序分别是:
    TRACE < DEBUG < INFO < WARN < ERROR < FATAL
    他们分别对应Logger的trace, debug, info, warn, error和fatal方法进行输出,但是我们通常只使用debug、info和error这三个最常用的级别。运行时的log输出级别可以通过更改log4j配置文件来进行配置,就免去了注释掉debug代码的尴尬。
 
  • 3. 输出log的正确方式:
    if (logger.isInfoEnabled()) {
        logger.info("User " + userId + " is using app " + appId);
    }
3.1 为什么要加上logger.isInfoEnabled()?
    直接使用logger.info("User " + userId + " is using app " + appId)来输出log,也能够达到log级别为INFO或在INFO以下时才输出:("User " + userId + " is using app " + appId),因为logger.info方法内部有判断输出级别的代码。但是在进入logger.info函数之前,("User " + userId + " is using app " + appId) 这个表达式已经通过运算拼接成了一个字符串;而如果事先使用 if (logger.isInfoEnabled())进行判断,那么当log级别在INFO以上时,就能省去上述的字符串操作,在高并发和复杂log信息拼 接的情况下,使用这种标准的方法输出log能够省去不小的系统开销。另外,如果构造log信息的过程需要大量字符串操作,建议使用 StringBuilder来完成字符串拼接。
3.2 ERROR及其以上级别的log信息是一定会被输出的,所以只有logger.isDebugEnabled和logger.isInfoEnabled方法,而没有logger.isErrorEnabled方法。
 
  • 4. debug、info、error等输出log的方法是线程安全的,请放心使用。
 
  • 5. log有风险,输出需谨慎!由于输出log过程需要进行磁盘操作,且log4j为了保证log输出过程的线程安全性而使用同步锁,就使得输出log成为很耗时的操作,所以log信息一定要言简意赅,不要输出一些无用的log。
 
    以上为我个人的使用经验,欢迎大家指教和补充。
 
    最后,祝愿log4j给大家带来更加愉快的开发体验。

如何正确使用log4j的更多相关文章

  1. Log4J使用笔记(转)

    转自:http://www.cnblogs.com/eflylab/archive/2007/01/11/618001.html Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程 ...

  2. java中Log4J的使用笔记

    使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格式,或通过定义每一条日志信息的级别,更加细致地控制日志的生成过程. Log ...

  3. Log4j基础知识

    Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格式,或通过定义每一条日 ...

  4. [ log4j ]-日志文件的使用

    在java文件中通过 log4j 输出日志信息 1,先引入 log4j-xx.x.jar 包 2,新建一个日志类 PrintLog4j.java: package com.stu.log4j; imp ...

  5. log4j每天,每小时产生一日志文件

    log4j每天,每小时产生一日志文件 2016年08月05日 14:14:33 阅读数:6254 一.之前的文章中有log4j的相关配置以及属性的介绍,下面我们先把配置列出来:   log4j.roo ...

  6. mybatis输出SQL

    1.导包 下载一个log4j-1.2.17.jar,放到WEB-INF的lib下,并加入build path 2.创建配置文件 在src下创建log4j.properties,填入以下内容: log4 ...

  7. Mybatis 后台SQL不输出

    在正确设置log4j.properties之后还是无法输出想要的SQL语句 经过搜索,发现是跟slf4j-api-1.6.1.jar这个jar包冲突了. 删掉之后就正常了, 但是这个包删掉的话acti ...

  8. log4j的正确使用姿势

    最近清明节,朋友公司的日志爆了,说控制台打得太满了,出了问题,早上4点多被喊去公司修改代码,他们把所有的日志全部在控制台打印了,结果就...我说日志这么做不可取啊,你们打印出来的内容太多啦,控制台没必 ...

  9. java日志组件介绍(common-logging,log4j,slf4j,logback )

    转自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging是apache提供的一个通用的日志 ...

随机推荐

  1. 让你的 CDN 费用省 50% 以上!图片瘦身的正确姿势

    七牛云新推出的图片瘦身功能是做什么的? 打开七牛云的「数据处理」中的「图片瘦身」功能,在图片受到访问时,能够实时对图片进行瘦身,在保证分辨率和画质不变的情况下,可以将图片最高缩小 80%.当「图片瘦身 ...

  2. /etc/fstab readyonly 解决办法

    阿里云主机切换地区强制升级后,“新的磁盘盘符识别为vdb1,但是在/etc/fstab中记录的挂载信息还是旧的xvdb1,导致磁盘挂载失败” 机子启动出错了. 按提示 输入 root的密码,进入以Re ...

  3. java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案

    Service层的接口中有一些比较常用方法,一次又一次的在新的Service层中被书写,所以懒惰的程序员又烦了,他们决定写个通用接口来解决这个问题. 有些项目中,实体类即承担接收表单数据的任务,又承担 ...

  4. CodeIgniter与Zend Acl结合实现轻量级权限控制

    CodeIgniter与Zend Acl结合实现轻量级权限控制 Tag :CodeIgniter Zend Acl 权限控制 1. Zend_Acl简介 Zend_Acl 为权限管理提供轻量并灵活的访 ...

  5. django学习之- session

    session和cookie关系:session依赖于cookie基于cookie做用户验证时,敏感信息不适合放在cookie中原理:cookie定义:保存在用户游览器端的键值对session定义:保 ...

  6. Oracle 用户表空间查看、修改大小、设置自增长等

      分类: Oracle 首先登入某个用户,查看某个用户在哪个表空间下: select username,default_tablespace from user_users; 查看该用户下所有的表: ...

  7. zmq.error.ZMQError: Address already in use

    1.如下代码,启动的时候python app.py会报如题的错误 app.py #!/user/bin python # -*- coding:utf-8 -*- import os from dat ...

  8. 多平台密码绕过及提权工具Kon-Boot的使用与防范

    在单用户的机器上密码可能没那么重要,但是一旦有多个用户可以使用这台机器,密码就显得十分必要了(比如有儿童账户的电脑).所以说为你的电脑增设一条防线的最常用,最简单的方法就是用密码将你的电脑保护起来,但 ...

  9. CentOS 5.11安装配置LAMP服务器(Apache+PHP5+MySQL)

    http://www.osyunwei.com/archives/8880.html 准备篇: CentOS 5.x系统安装配置图解教程 http://www.osyunwei.com/archive ...

  10. UILable怎样加入单击事件

    //初始化UILable UILabel *lable = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, 320, 40)]; //设置其能够接收用 ...