Log4J/Logback

slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。slf4j译为简单日志门面(The Simple Logging Facade for Java ),是日志框架的抽象。而log4j和logback是众多日志框架中的几种。也就是说我们在具体开发中,需要绑定一个日志框架,才能正常的使用slf4j。
而log4j和logback就是两个受欢迎的日志框架。

  • log4j是apache实现的一个开源日志组件。(Wrapped implementations)
  • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现。(Native implementations)

log4j例子:
pom.xml中添加:

<!-- log4j support -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

添加log4j.properties:
对于Java app, log4j.properties文件放在 project/classes/ 目录。
对于Java web applications, log4j.properties文件放在 WEB-INF/classes/或src/main/resource/ 目录。
1.根日志的级别定义为 DEBUG,并将名为 stdout,D,E 的 appender 添加其上。

log4j.rootLogger = debug,stdout,D,E

2.将名为 stdout,D,E 的 appender 设置为合法的 appender。

log4j.appender.stdout = org.apache.log4j.ConsoleAppender

3.设置 appender stdout,D,E 的 layout。

完整例子:

 ### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=/home/duqi/logs/debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = /home/duqi/logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=/home/admin/logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =/home/admin/logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

使用:
日志分别记录到了控制台(三条),debug.log(两条)和error.log(一条)。

public class Log4JTest {
    private static final Logger logger = LoggerFactory.getLogger(Log4JTest.class);

    public static void main(String[] args) {
        // 记录debug级别的信息
        logger.debug("This is debug message.");
        // 记录info级别的信息
        logger.info("This is info message.");
        // 记录error级别的信息
        logger.error("This is error message.");
        /*try{
              obj.divide();
          }catch(ArithmeticException ex){
              logger.error("Sorry, something wrong!", ex);
        }*/
    }

配置文件:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
日志级别从低到高为:ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL。比如定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。如果不在appender中过滤自己的level(大于等于root level),默认使用rootLogger的level。

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
Log4j提供的appender有以下几种:

  • org.apache.log4j.ConsoleAppender(控制台),
  • org.apache.log4j.FileAppender(文件),
  • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
  • org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
  • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

log4j.appender.D.layout = org.apache.log4j.PatternLayout
Appender的layout有以下几种:

  • org.apache.log4j.HTMLLayout(以HTML表格形式布局),
  • org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

其他参数

记录Mybatis语句:
如果你的应用部署在一个包含Commons Logging的环境(如:Tomcat,Websphere), 而你又想用其他的日志框架,你可以通过在MyBatis的配置文件mybatis-config.xml里面添加一项setting(配置)来选择一个不同的日志实现。
在ApplicationConetxt.xml中:

<configuration>  
    <properties>  
        <property name="dialect" value="mysql" />  
    </properties>  
    <settings>  
        <setting name="logImpl" value="LOG4J" />    
    </settings>  
</configuration> 

log4j.properties:

log4j.rootLogger=info,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] -%m%n  
# 打印sql语句:debug; 执行结果:trace
## 指定mapper配置文件中的namespace
log4j.logger.MyMapperNS =TRACE

mapper的配置文件:

<mapper namespace="MyMapperNS.user">
    <select id="selectUser" parameterType="int" resultType="User">  
        <![CDATA[  
            select * from user where id = #{id}  
        ]]>
    </select>
</mapper>  

你也可以只记录一个方法:log4j.logger.org.mybatis.example.BlogMapper.user.selectUser=TRACE
与此相对,可以对一组mapper接口记录日志,只要对mapper接口所在的包开启日志功能即可:

log4j.logger.MyMapperNS=TRACE

某些查询可能会返回大量的数据,只想记录其执行的SQL语句该怎么办?为此,Mybatis中SQL语 句的日志级别被设为DEBUG(JDK Logging中为FINE),结果日志的级别为TRACE(JDK Logging中为FINER)。所以,只要将日志级别调整为DEBUG即可达到目的:

log4j.logger.MyMapperNS=DEBUG

logback例子:
pom.xml添加依赖

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.13</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.1.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.7</version>
    </dependency>

用法和slf4j+logback一致:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    public class SimpleDemo {

        private static final Logger logger = LoggerFactory.getLogger(SimpleDemo.class);

        public static void main(String[] args) {
            logger.info("111");
            logger.debug("222");
            logger.error("3333");
            logger.trace("4444");
        }
    }

配置文件logback.xml。文件须放下在 resources 根目录下,文件名不能修改:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 根标签 -->
    <!-- 三个属性 
         scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
        scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
        debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 
    -->
    <configuration scan="true" scanPeriod="30 seconds">

        <!-- 用来全局定义变量值,它有两个属性name和value,通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量 -->
        <!-- 日志文件保存路径 -->
        <property name="logPath" value="d:\\log"/>


        <!-- 子节点<appender>:负责写日志的组件,它有两个必要属性name和class。name指定appender名称,class指定appender的全限定名-->
       <!-- ConsoleAppender 把日志输出到控制台,有以下子节点:  -->

        <!-- 控制台输出 -->
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>

        <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。有以下子节点:
          <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
          <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。    
          <rollingPolicy>:当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类-->
         <!-- 记录日志文件 -->
        <appender name="testLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${logPath}/test.log</file>
            <append>true</append>
            <!-- class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy": 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:
                <fileNamePattern>:必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。
                如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
                如果没设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。     
            -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--日志文件输出的文件名-->
                <FileNamePattern>${logPath}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
                <!-- <maxHistory>可选节点,
                    控制保留的归档文件的最大数量,超出数量就删除旧文件。
                    假设设置每个月滚动,且<maxHistory>是6,则只保存最近6个月的文件,删除之前的旧文件。
                    注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
                 -->
                <!--日志文件保留天数-->
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <!-- 
                <encoder>:对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。
                PatternLayoutEncoder 是唯一有用的且默认的encoder ,
                有一个<pattern>节点,用来设置日志的输入格式。使用“%”加“转换符”方式,如果要输出“%”,则必须用“\”对“\%”进行转义。
             -->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
            <!--日志文件最大的大小-->
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>10MB</MaxFileSize>
            </triggeringPolicy>
        </appender>

        <!-- 
            子节点<loger>:用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>。
            <loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
            可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger
            name: 用来指定受此loger约束的某一个包或者具体的某一个类。
            level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前loger将会继承上级的级别。
            addtivity: 是否向上级loger传递打印信息。默认是true。同<loger>一样,可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。
         -->
        <logger name="testLog" additivity="false" level="INFO">
            <appender-ref ref="STDOUT" />//大小写敏感,和appender的name一致
            <appender-ref ref="testLogAppender" />
        </logger>

        <!-- 
            子节点<root>:它也是<loger>元素,但是它是根loger,是所有<loger>的上级。
            只有一个level属性,因为name已经被命名为"root",且已经是最上级了。
            level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,
            不能设置为INHERITED或者同义词NULL。 默认是DEBUG。    
         -->
        <!-- 日志输出级别 -->
        <root level="INFO">
            <appender-ref ref="STDOUT" />
        </root>
    </configuration>

其他:
避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false。additivity默认为true,即通过该logger输出的日志会同时输出到root logger,如果还为该logger指定了独立的appender,就会导致这部分日志重复输出。

异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字throws往上抛出。
正例:

    logger.error(各类参数或者对象toString + "_" + e.getMessage(), e);             

记录异常日志的常见错误:

    logger.error(e);
    logger.error(e.getMessage());
    logger.error("上下文"+e.getMessage());        

上面这几种都是错的!请确保使用的是两个入参的API,如error(String s, Throwable t)。


参考:
https://mengkang.net/594.html
http://www.jianshu.com/p/c6c543e4975e
http://wiki.jikexueyuan.com/project/log4j/logging-files.html
https://www.mkyong.com/logging/log4j-hello-world-example/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,939评论 1 13
  • 写Java也有一段时间了,一直都有用slf4j log4j输出日志的习惯。但是始终都是抱着“拿来主义”的态度,复制...
    Minimumy阅读 1,372评论 1 7
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,957评论 0 6
  • 一、Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layo...
    默默守护阅读 1,897评论 2 8
  • from:https://www.cnblogs.com/ITtangtang/p/3926665.html一、L...
    enshunyan阅读 3,274评论 0 0