ssm框架使用slf4j+logback进行日志记录

这几天使用使用ssm搭建项目框架时,开始使用log4j作为日志框架,但是springmvc已经不支持使用org.springframework.web.util.Log4jConfigListeners这个监听器,上网搜索了一番,果断采用了slf4j+logback进行日志记录,首先对他们做一个对比,slf4j是java的一个日志门面,实现了日志框架一些通用的api,log4j和logback是具体的日志框架。
他们可以单独的使用,也可以绑定slf4j一起使用。
单独使用。分别调用框架自己的方法来输出日志信息。
绑定slf4j一起使用。调用slf4j的api来输入日志信息,具体使用与底层日志框架无关(需要底层框架的配置文件),具体关系如图

使用slf4j绑定日志系统的优势
软件工程的角度。抽象,解耦,便于维护
语法设计角度。slf4j有{}占位符,而log4j需要用“+”来连接字符串,既不利于阅读,同时消耗了内存(heap memory)。

  • log4j与logback
    logback的优势:
  • 更快的执行速度
  • 充分的测试
  • logback-classic 非常自然的实现了SLF4J
  • 丰富的扩展文档
  • 可以使用使用XML配置文件或者Groovy
  • 自动重新载入配置文件
  • 优雅地从I/O错误中恢复
  • 自动清除旧的日志归档文件
  • 自动压缩归档日志文件

好了下面进行详细的配置

开发环境:

  • jdk1.8
  • maven3
  • idea2017
  • spring 4.3.9

导入ssm所需jar包,此处不再进行叙述,
日志管理所需jar包

      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.11</version>
    </dependency>
    <dependency>
      <groupId>org.logback-extensions</groupId>
      <artifactId>logback-ext-spring</artifactId>
      <version>0.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.7.25</version>
    </dependency>
  • 第一个logback-classic包含了logback本身所需的slf4j-api.jar、logback-core.jar及logback-classsic.jar
  • 第二个logback-ext-spring是由官方提供的对Spring的支持,它的作用就相当于log4j中的Log4jConfigListener;这个listener,网上大多都是用的自己实现的,原因在于这个插件似乎并没有出现在官方文档的显要位置导致大多数人并不知道它的存在
  • 第三个jcl-over-slf4j是用来把Spring源代码中大量使用到的commons-logging替换成slf4j,只有在添加了这个依赖之后才能看到Spring框架本身打印的日志,否则只能看到开发者自己打印的日志

配置logback.xml

使用maven,放置在resources目录下

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同,以下配置参数在pom.xml里 -->
    <property name="log.root.level" value="${log.root.level}" /> <!-- 日志级别 -->
    <property name="log.other.level" value="${log.other.level}" /> <!-- 其他日志级别 -->
    <property name="log.base" value="${log.base}" /> <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到eclipse的安装目录下,如果部署到linux上的tomcat下,会输出到tomcat/bin目录 下 -->
    <property name="log.moduleName" value="${log.moduleName}" />  <!-- 模块名称, 影响日志配置名,日志文件名 -->
    <property name="log.max.size" value="100MB" /> <!-- 日志文件大小,超过这个大小将被压缩 -->

    <!--控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method\(\):%L -%msg%n</Pattern>
        </encoder>
    </appender>

    <!-- 用来保存输出所有级别的日志 -->
    <appender name="file.all" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${log.base}/${log.moduleName}.log</File><!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 
            是web项目会保存到Tomcat的bin目录 下 -->
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/archive/${log.moduleName}_all_%d{yyyy-MM-dd}.%i.log.zip
            </FileNamePattern>
            <!-- 文件输出日志 (文件大小策略进行文件输出,超过指定大小对文件备份) -->
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 日志输出的文件的格式 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method\(\):%L -%msg%n</pattern>
        </layout>
    </appender>
    
    <!-- 这也是用来保存输出所有级别的日志 -->
    <appender name="file.all.other" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${log.base}/${log.moduleName}_other.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/archive/${log.moduleName}_other_%d{yyyy-MM-dd}.%i.log.zip
            </FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{56}.%method\(\):%L -%msg%n</pattern>
        </layout>
    </appender>

    <!-- 只用保存输出error级别的日志 -->
    <appender name="file.error"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${log.base}/${log.moduleName}_err.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.base}/archive/${log.moduleName}_err_%d{yyyy-MM-dd}.%i.log.zip
            </FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${log.max.size}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{56}.%method\(\):%L - %msg%n</pattern>
        </layout>
        <!-- 下面为配置只输出error级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

   <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <!-- 添加附加的appender,最多只能添加一个 -->
    <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <includeCallerData>true</includeCallerData>
        <appender-ref ref="file.all" />
    </appender>

    <appender name="file.async.other" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>256</queueSize>
        <includeCallerData>true</includeCallerData>
        <appender-ref ref="file.all.other" />
    </appender>

    <!-- 为某个包下的所有类的指定Appender 这里也可以指定类名称例如:com.aa.bb.ClassName -->
    <logger name="com.yyt" additivity="false">
        <level value="${log.root.level}" />
        <appender-ref ref="stdout" /> 
        <appender-ref ref="file.async" /><!-- 即com.li包下级别为 ${log.root.level}的才会使用file.async来打印 -->
        <appender-ref ref="file.error" />
    </logger>
    <logger name="org.apache.ibatis" level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </logger>

    <logger name="java.sql" level="debug">
        <appender-ref ref="STDOUT"/>
    </logger>
    <!-- root将级别为${log.root.level}及大于${log.root.level}的日志信息交给已经配置好的名为“Console”的appender处理,“Console”appender将信息打印到Console,其它同理 -->
    <root level="${log.root.level}">
        <appender-ref ref="stdout" /> <!--  标识这个appender将会添加到这个logger -->
        <appender-ref ref="file.async.other" />
        <appender-ref ref="file.error" />
    </root>
</configuration>

注意mybatis日志管理
logback.xml 中配置

<logger name="java.sql" level="debug">
        <appender-ref ref="STDOUT"/>
    </logger>

mybatis.xml中配置

    <!-- 设置日志打印 -->
    <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

最后配置web.xml

<!-- 日志记录,要配置在ContextLoaderListener之前 -->

  <context-param>
    <param-name>logbackConfigLocation</param-name>
    <param-value>classpath:log/logback.xml</param-value>
  </context-param>
  <listener>
    <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
  </listener>

到这里,我们的配置已经完成了,可以使用了。

 private static final Logger logger = LoggerFactory.getLogger(监听的类.class);

然后可以打印各个级别的日志信息了。

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

推荐阅读更多精彩内容