我的目标是授人以渔,而不是授人以鱼,我相信你仔细看完这篇文章,玩转log4j不成问题

先来一个log4j最简单的例子

public class MyApp {
    static Logger logger = Logger.getLogger(MyApp.class.getName());

    public static void main(String[] args) {
        logger.info("Entering application.");
        Bar bar = new Bar();
        bar.doIt();
        logger.info("Exiting application.");
    }
}
public class Bar {
    static Logger logger = Logger.getLogger(Bar.class);

    public void doIt() {
        logger.debug("Did it again!");
    }
}

在类路径(src目录下)创建log4j的配置文件log4j.properties,里面的内容

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.SimpleLayout

运行一下,你会看到控制台有输出,这就是一个最简单的log4j配置的例子

来解释一下这3行配置

第一行:设置了根记录器,值的格式为: 日志级别, appender1, appender2...

log4j从低到高有这么几个日志级别 DEBUG < INFO < WARN < ERROR < FATAL. 配置成DEBUG就会把所有级别的日志都打印出来,反之配置成FATAL就只会打印FATAL级别的日志

appender1, appender2就是第二行配置的

第二行:表示输出到控制台,那除了ConsoleAppender就没有别的Appender了么,答案当然是有的,如图

只要实现了Appender接口的都可以,所以可以看到第一行里面的A1是在第二行定义的一个ConsoleAppender

第三行:log4j.appender.stdout一直到这里都知道,这就是第二行的appender,那么后面为什么要接一个layout呢?

里面是不是有一个属性还是什么呢?我们打开搜索一下,如图

可以看到里面有一个继承自AppenderSkeleton的layout属性,那么A1后面接的layout就是这个layout属性么?

从第三行看到赋了一个SimpleLayout给layout,看起来一切合理,但是我想说的是第三行里面的layout不是这个layout属性,而是继承自AppenderSkeleton里面的setLayout方法的layout,我曾经在配置spring的时候也思考过这样的问题,后来证明spring配置里面的属性配置是setXxx方法的Xxx,所以我99%的肯定这里的layout是setLayout的layout,要想验证也简单,自己把ConsoleAppender到AppenderSkeleton所经过的类(并不是直接继承)复制下来,然后把setLayout方法改一个名字,比如setLayout1,然后再用你自己的类配置,就知道这里的layout到底还是layout1了,也就是到底是属性还是setter方法里面的,我没有测试,如果有哪位同学测试得到了和我说的不一样的结果,欢迎告诉我。

ConsoleAppender的setLayout是继承自AppenderSkeleton的,而AppenderSkeleton是重写的Appender接口里面的setLayout方法,也就是所有的appender都需要配置layout

所有的appender都继承自AppenderSkeleton,来看一下这个类里面有哪些setter方法

可以看到有一个setThreshold方法,这个是配置日志级别的,也就是说每个appender都可以配置自己的日志级别,而不必使用统一的日志级别

基于我的这个结果,也就是说只要类里面有setter方法,都可以注入值,我们发现ConsoleAppender里面有一个setTarget(String value)

所以这个target也是可以配置的,像这样

log4j.appender.A1.target=System.out

填什么值还是要看一下api,从api可以看出,target有2个值,分别是System.out和System.err,默认是System.out
target表示输出的目标,System.err只输出错误信息,System.out输出所有信息

如果第三行配置成下面的

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

表示可以自定义的灵活布局,里面有一个setConversionPattern方法,传入转换模式就可以得到自定义的输出布局,可以看到setConversionPattern这个方法是PatternLayout独有的,其他的layout没有的,这是因为其他的layout的布局是固定的

如第三行的SimpleLayout表示简单布局,仅打印日志级别和日志信息,如DEBUG - Hello world

而PatternLayout的布局是需要自己定义的,所以需要加上一行转换默认的配置,比如可以这样配置

log4j.appender.A1.Layout.conversionPattern=%d{ABSOLUTE} %-4p [%t] %c{5} - %m%n

这一行表示什么意思呢?我们来看一下,可以看一下官方的说明

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html

不懂的自行有道翻译,还是翻译的不错的,至少我是翻译的,哈哈哈。。。
我取一些讲一下,每个转换字符都要用%开头,而且是区分大小写的,不要弄错了
%c  类的全路径,可以加参数使用,如果类路径是a.b.c.Test,那么%c{2}得到的结果是c.Test,表示只保留后面的2项
%C 和%c的作用是一样的,而且性能较差,所以我不知道为什么还要弄这个出来
%d  格式化时间,可以这样用%d{HH:mm:ss,SSS} or %d{dd MMM yyyy HH:mm:ss,SSS},这样是最终调用了SimpleDateFormat,
       这样性能不好,所以应该这样用%d{ISO8601} or %d{ABSOLUTE} or %d{DATE},这3种出来的格式分别是
       %d{ISO8601}: 2018-03-26 17:18:38,207
       %d{ABSOLUTE}: 17:19:06,630
       %d{DATE}: 26 三月 2018 17:13:12,056
%F 发出日志请求的文件名, 不推荐使用
%l   位置信息,不推荐使用
%m 日志信息
%n  换行
%p  日志级别
%r   从布局构建到日志记录事件创建的毫秒数
%t   线程
%x   用于输出与生成日志事件的线程关联的NDC(嵌套诊断上下文)
%%  输出一个%

敲黑板,敲黑板。重要的来了
在%和转换字符之间还可以配置对齐方式、最小字符宽度和最大字符宽度
  默认右对齐,负号-表示左对齐
  数字指定最小字符宽度,如果小于最小字符宽度则依据对齐规则在左边或右边添加空格
 . 数字(点号接数字)表示最大字符宽度,如果大于最大字符宽度,则保留后面的最大字符宽度的字符

看几个例子
%20c        右对齐最小宽度20的类路径
%-20c       左对齐最小宽度20的类路径
%.30c       最大宽度为30的类路径,因为总是没有多余的空间,所以没有对齐方式,表现出来的对齐方式是左对齐
%20.30c   右对齐最小宽度为20,最大宽度为30的类路径
%-20.30c  左对齐最小宽度为20,最大宽度为30的类路径

现在知道上面例子中%-4p的意思了:左对齐最小宽度为4的日志级别

如果想让特定的包下的类或特定的类输出指定级别的日志,可以像这样配置
log4j.logger.com.foo=WARN
说明:log4j.logger.是固定的
com.foo是你要指定日志级别的包或类,这样com.foo包下的所有类(或com.foo类)的日志级别就是WARN,其他包或类不受影响

来看一下其他常用的Appener

DailyRollingFileAppender(日常翻滚文件Appender):以时间来翻滚的appender

就把里面的一个setDatePattern方法讲一下,其他的setter方法就不说了,可以直接配置的

DailyRollingFileAppender默认是每天创建一个新的日志文件,通过setDatePattern方法可以设置为每个月,每个星期,每个小时设置每分钟创建一个新的日志文件

RollingFileAppender(翻滚文件appender):以日志文件大小来翻滚

默认翻滚大小是10M,翻滚个数是1个,这都是可以通过里面里面的setter方法来设置的,就不再多说了

最后给一个2个appender的配置文件示例

log4j.rootLogger=DEBUG, A1, A2
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.SimpleLayout

log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.datePattern='.'yyyy-MM-dd HH-mm
log4j.appender.A2.file=test.log
log4j.appender.A2.encoding=utf-8
#log4j.appender.A2.append=true
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.conversionPattern=%r [%t] %-5p (%.30c) [%x] - %m%n

玩转log4j的更多相关文章

  1. 【转】玩转log4j

    原文链接:http://www.cnblogs.com/shenliang123/archive/2012/05/02/2479286.html 由于最近正在扩展卫生局考务系统,由于上一次使用过一次该 ...

  2. 玩转Spring MVC(五)----在spring中整合log4j

    在前边的基础上,本文主要总结一下如何在spring 中配置log4j,在本文末尾会给出完整项目的链接. 首先是web.xml中要新添加的代码: <!-- 6. 配置log4j --> &l ...

  3. 项目自动化建构工具gradle 入门2——log4j输出helloWorld

    上一章节呢,有一个能跑的程序了.但是对做工程的人来说,用日志输出感觉比用System.out要有档次一点.比如使用log4j.直接上例子: 1进入D:\work\gradle\log目录  ,您电脑没 ...

  4. 玩转Nodejs日志管理log4js(转)

    转自:http://blog.fens.me/nodejs-log4js/ 前言 日志对任何的应用来说都是至关重要的.在Nodejs中使用express框架并没有自带的日志模块,我们可以选择log4j ...

  5. 玩转mongodb(九):通过log4jmongo来实现分布式系统的日志统一管理

    背景 在分布式系统中,我们有多个web app,这些web app可能分别部署在不同的物理服务器上,并且有各自的日志输出.当生产问题来临时,很多时候都需要去各个日志文件中查找可能的异常,相当耗费人力. ...

  6. (转)log4j(一)——为什么要用log4j?

    1 试验环境 OS:win7 JDK:jdk7 Log4j:1.2.17(好尴尬,原本是想试验下log4j2的,结果阴差阳错用了这个版本,不过幸好,试验也不白试验,试验的作用是一样的) 2 先看两个简 ...

  7. log4j(一)——为什么要用log4j?

    一:试验环境 OS:win7 JDK:jdk7 Log4j:1.2.17(好尴尬,原本是想试验下log4j2的,结果阴差阳错用了这个版本,不过幸好,试验也不白试验,试验的作用是一样的) 二:先看两个简 ...

  8. Java logger组件:slf4j, jcl, jul, log4j, logback, log4j2

    先说结论 建议优先使用logback 或 log4j2.log4j2 不建议和 slf4j 配合使用,因为格式转换会浪费性能. 名词:jcl 和 jul 标题中的 jcl 是 apache Jakar ...

  9. log4j.xml——java日志处理组件配置简介

    (从一篇好文开始)log4j(一)——为什么要用log4j? 三:看完栗子后的感想 (1)很明显我们在编写代码的时候有各种需要打印日志的需求,比如:我们调试代码的时候:我们的应用出现了问题,我们分析. ...

随机推荐

  1. FusionCharts 2D柱状图和折线图的组合图

    1.设计思路 (1)了解组合图的特性以及用法,选用图的类型: (2)设计出两根柱子和两根折线,分开展示. 2.设计步骤 (1)设计页面 Column2DLine.html: <!DOCTYPE ...

  2. css文字居中、图片居中、div居中解决方案

    一.文字居中 若文字只有一行 <!--html代码--> <div class="box"> <p class="text"> ...

  3. freemarker处理map的数据(二十)

    1.简易说明 (1)map取值 (2)key取值 2.实现示例 <html> <head> <meta http-equiv="content-type&quo ...

  4. JQuery移动动画实现点击按钮切换图片--JQuery基础

    直接贴源码了哈,这些都是自己总结的……汗水几何?希望能帮到大家. <%@ Page Language="C#" AutoEventWireup="true" ...

  5. Rational Rose_2007的下载、安装与破解--UML建模软件

    一.下载Rational.Rose_2007安装包与破解文件 对于Rational.Rose_2007,您可以到我的百度网盘计算机相关专业所用软件---百度云链接下载下载,另外附上安装需要的通行证(破 ...

  6. Python基础_如何用pip安装文件

    与其他语言相比,Python的一个很大的优势是由丰富的资源库,这就需我们按照自己的来安装文件和包.本节以在windows系统下安装pygame 为例来讲述一下安装步骤. 1. 检测python中有没有 ...

  7. linux命令类型及执行顺序

    一 为什么要使用命令行   当初级Linux用户面对缺乏图形界面的Linux时很多人都会抱怨:为何要死守命令行?为什么不采用人机互交好.更简单的图形界面呢?事实上,图形界面在某些任务方面确实高效而且简 ...

  8. 【Uoj34】多项式乘法(NTT,FFT)

    [Uoj34]多项式乘法(NTT,FFT) 题面 uoj 题解 首先多项式乘法用\(FFT\)是一个很久很久以前就写过的东西 直接贴一下代码吧.. #include<iostream> # ...

  9. 【BZOJ4650】【NOI2016】优秀的拆分(后缀数组)

    [BZOJ4650][NOI2016]优秀的拆分(后缀数组) 题面 BZOJ Uoj 题解 如果我们知道以某个位置为开始/结尾的\(AA\)串的个数 那就直接做一下乘法就好 这个怎么求? 枚举一个位置 ...

  10. iOS9 HTTP 网络访问问题

    今天升级Xcode 7.0 发现网络访问失败.输出错误信息 The resource could not be loaded because the App Transport Security po ...