日志框架:Log4j、Log4j2、Slf4j、JDKLog、Logback等
log4j
1.log4j优先级
log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
ALL 最低等级的,用于打开所有日志记录。
?
TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。
?
DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
?
INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
?
WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。
?
ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
?
FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
?
OFF 最高等级的,用于关闭所有日志记录。
如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
2.spring使用log4j
spring使用log4j,可以有2种方法。
1、properties配置文件
在web.xml里不做任何配置。
log4j.properties放在classpath根目录下,
这时候生成的日志文件就没有相对路径,如果写相对路径,则会生成在安
log4j.rootCategory=DEBUG, stdout
# 将等级为INFO及以上的日志信息输出到stdout和R这两个目的地
?
# 优先级从高到低OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL
# 如果配置为INFO这样只显示INFO、WARN、ERROR的log信息,而DEBUG信息不会被显示
#ALL:打印所有的日志,OFF:关闭所有的日志输出。
?
log4j.appender.stdout=org.apache.log4j.FileAppender
# 定义名为stdout的输出端是哪种类型 输出到控制台
?
#org.apache.log4j.ConsoleAppender(控制台),
#org.apache.log4j.FileAppender(文件),
#org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
#org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
#org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
?
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 定义名为stdout的输出端的layout(布局方式)是哪种类型
#org.apache.log4j.HTMLLayout(以HTML表格形式布局),
#org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
#org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
#org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
?
log4j.appender.stdout.layout.ConversionPattern=[QC] %d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %C.%M(%L) | %m%n
# 如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:
# %m 输出代码中指定的消息;
# %M 输出打印该条日志的方法名;
# %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL; 可能被允许输出多个级别的消息,如:INFO,WARN,ERROR,FATAL等消息都会输出。哪到底每条消息是哪个级别呢?%p就是输出该条消息的级别。
# %r 输出自应用启动到输出该log信息耗费的毫秒数;
# %c 输出所属的类目,通常就是所在类的全名;
# %t 输出产生该日志事件的线程名;
# %n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
# %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2002-10-18 22:10:28,921;
# %l 输出日志事件的发生位置,及在代码中的行数;
# [QC]是log信息的开头,可以为任意字符,一般为项目简称。
# 输出的信息
# [TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean 'MyAutoProxy'
?
#log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
#定义名为R的输出端的类型为每天产生一个日志文件。
?
log4j.appender.stdout.File=C:\\Users\\Administrator\\Desktop\\log4jtext.txt
#定义名为R的输出端的文件名为D:\\Tomcat 5.5\\logs\\qc.log可以自行修改。
log4j.appender.stdout.Append = true
#默认值是true,将日志追加到文件的最后,false是指将新的日志消息覆盖文件原有的内容
log4j.appender.stdout.Threshold = DEBUG
#指定日志输出的最低层次
filter.F=org.apache.log4j.varia.LevelRangeFilter
#这个是对Threshold的一个补充
?
filter.F.LevelMin=DEBUG
filter.F.LevelMax=DEBUG
#这两句表示只能记录debug
#log4j.appender.R.layout=org.apache.log4j.PatternLayout
#定义名为R的输出端的layout是哪种类型
?
#log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
# 如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern
?
log4j.logger.com.neusoft=DEBUG
#指定com.neusoft包下的所有类的等级为DEBUG。
#可以把com.neusoft改为自己项目所用的包名。
?
log4j.logger.com.opensymphony.oscache=ERROR
log4j.logger.net.sf.navigator=ERROR
#这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。
?
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.apache.struts=WARN
#这两句是struts的包。
?
log4j.logger.org.displaytag=ERROR
#这句是displaytag的包。(QC问题列表页面所用)
?
log4j.logger.org.springframework=DEBUG
#此句为Spring的包。
?
log4j.logger.com.mybatis.db=WARN、
#此句为mybatis的包。
log4j.lo
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/classes/log4j.properties</param-value>
</context-param>
?
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myappfuse.root</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
aram-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions><!-- 去掉springboot默认配置 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <!-- 引入log4j2依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
?
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-web -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.1</version>
</dependency>
?
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
repository.com/artifact/org.apache.logging.log4j/log4j-web -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.1</version>
</dependency>
?
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
log4j2也是一款日志组件,是log4j1.x升级版本,并且log4j2和log4j是同一个作者,但是log4j2是重新架构的。
Log4j 1.x 在高并发情况下出现死锁导致cpu使用率异常飙升,而Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback(官方数据是10倍以上)。
1.关于配置文件的名称以及在项目中的存放位置
log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn".
系统选择配置文件的优先级(从先到后)如下:
(1).classpath下的名为log4j2-te
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
log4j2_dev.xml是你创建的log4j2的配置文件名,放在resources下,如放在其他路径则对应修改。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
iguration>
3.配置文件节点解析
(1).根节点Configuration
有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger).
status用来指定log4j本身的打印日志的级别.
monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.
(2).Appenders节点
常见的有三种子节点:Console、RollingFile、File.
Console
用来定义输出到控制台的Appender.
name:指定Appender的名字.
target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
PatternLayout:输出格式,不设置默认为:%m%n.
File
用来定义输出到指定位置的文件的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
RollingFile
用来定义超过指定大小自动删除旧的创建新的的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
filePattern:指定新建日志文件的名称格式。如${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd HH}_%i.log.gz
Policies
指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am。interval属性中值的单位由时间粒度决定,如: yyyy-MM-dd HH:时间粒度为hour ,yyyy-MM-dd:时间粒度为day。
SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.
DefaultRolloverStrategy
用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。
1)DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件。
2)max与filePattern中的计数器%i配合起作用的,如果没有%i,则max不起作用。
3)每次rollover时,文件重命名时的计数器将每次加1(初始值为1),若达到max的值,将删除旧的文件, ? 文件名发生变化的话,计数器清零,从1开始。
DeleteAction
DefaultRolloverStrategy制定了默认的rollover策略,通过max参数可控制一定时间范围内归档的日志文
件的最大个数。Log4j 2.5 引入了DeleteAction,使用户可以自己控制删除哪些文件,而不仅仅是通过
DefaultRolloverStrategy的默认策略。
注意:通过DeleteAction可以删除任何文件,而不仅仅像DefaultRolloverStrategy那样,删除最旧的文件,
所以使用的时候需要谨慎!
`<?``xml` `version``=``"1.0"` `encoding``=``"UTF-8"``?>``<``Configuration` `status``=``"warn"` `name``=``"MyApp"` `packages``=``""``>`` ``<``Properties``>`` ``<``Property` `name``=``"baseDir"``>logs</``Property``>`` ``</``Properties``>`` ``<``Appenders``>`` ``<``RollingFile` `name``=``"RollingFile"` `fileName``=``"${baseDir}/app.log"`` ``filePattern``=``"${baseDir}/app-%d{yyyy-MM-dd}.log.gz"``>`` ``<``PatternLayout` `pattern``=``"%d %p %c{1.} [%t] %m%n"` `/>`` ``<``CronTriggeringPolicy` `schedule``=``"0 0 0 * * ?"``/>`` ``<``DefaultRolloverStrategy``>`` ``<``Delete` `basePath``=``"${baseDir}"` `maxDepth``=``"2"``>`` ``<``IfFileName` `glob``=``"*/app-*.log.gz"` `/>`` ``<``IfLastModified` `age``=``"60d"` `/>`` ``</``Delete``>`` ``</``DefaultRolloverStrategy``>`` ``</``RollingFile``>`` ``</``Appenders``>`` ``<``Loggers``>`` ``<``Root` `level``=``"error"``>`` ``<``AppenderRef` `ref``=``"RollingFile"``/>`` ``</``Root``>`` ``</``Loggers``>``</``Configuration``>`
上述配置文件中,Delete部分便是配置DeleteAction的删除策略,指定了当触发rollover时,删除baseDir文
件夹或其子文件下面的文件名符合app-*.log.gz且距离最后的修改日期超过60天的文件。其中,basePath指定了
扫描开始路径,为baseDir文件夹。maxDepth指定了目录扫描深度,为2表示扫描baseDir文件夹及其子文件夹。
IfFileName指定了文件名需满足的条件,IfLastModified指定了文件修改时间需要满足的条件。
(3).Loggers节点
Loggers节点,常见的有两种:Root和Logger.
Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace <
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
<File name="log" fileName="log/test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--Filter:过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之 一。返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤 器过接着处理日志;返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。
控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20
max与filePattern中的计数器%i配合起作用的,如果没有%i,则max不起作用
每次rollover时,文件重命名时的计数器将每次加1(初始值为1),若达到max的值,将删除旧的文件
文件名发生变化的话,计数器清零,从1开始-->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.springframework" level="INFO"></logger>
<logger name="org.mybatis" level="INFO"></logger>
<root level="all">
<appender-ref ref="Console"/>
<appen
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conve
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<finalName>${artifactId}-${env}-${version}</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>xxx.yyyy.zzz.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" />
</transformers>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.6.1</version>
pendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
ce.ServicesResourceTransformer"/>
<transformer
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan 配置文件如果发生改变,将会被重新加载 scanPeriod 检测间隔时间-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>zlyPay-log</contextName>
<!-- info 地址 -->
<property name="log.path" value="D:\\log\\" />
<property name="log.file" value="D:\\log\\logback.log" />
?
<!-- errr,错误路径 -->
<property name="log.path.error" value="D:\\log\\error\\" />
<property name="log.file.error" value="D:\\log\\error\\logback-error.log" />
?
<include resource="org/springframework/boot/logging/logback/base.xml"/>
?
<!-- 普通日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.file}</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志命名:单个文件大于128MB 按照时间+自增i 生成log文件 -->
<fileNamePattern>${log.path}zlyPay-log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>512MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 最大保存时间:30天-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 显示所有的日志记录
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter> -->
</appender>
?
<!-- 错误日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.file.error}</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志命名:单个文件大于2MB 按照时间+自增i 生成log文件 -->
<fileNamePattern>${log.path.error}zlyPay-log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>128MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 最大保存时间:180天-->
<maxHistory>180</maxHistory>
</rollingPolicy>
<append>true</append>
<!-- 日志格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 日志级别过滤器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
?
<!-- 控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- 只有这个日志权限才能看,sql语句 -->
<level>DEBUG</level>
</filter>
</appender>
?
<!-- 输出sql日志 -->
<logger name="com.cltx.mapper" level="DEBUG"></logger>
?
<!-- additivity 避免执行2次 -->
<logger name="com.cltx" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</logger>
?
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="INFO_FILE"
>
?
<!-- 控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志格式 -->
<encoder>
<pattern>%d{yyyy
gback.core.ConsoleAppender">
<!-- 日志格式 -->
<encoder>
<pattern>%d{yyyy
private static final Logger logger = LoggerFactory.getLogger(当前类类名.class);
package com.qf.controller;
?
import com.qf.domain.Shops;
import com.qf.service.ShopsService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
?
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
?
import javax.annotation.Resource;
?
@RestController
public class ShopController {
?
@Resource
private ShopsService shopsService;
?
private static final Logger logger = LoggerFactory.getLogger(ShopController.class);
?
@RequestMapping(value = "findById/{shopId}",method = RequestMethod.GET)
public Shops findById(@PathVariable int shopId){
logger.info("查询,id:[{}]",shopId); //{}用于存储参数,不可省略
return shopsService.findByShopId(shopId);
}
解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志System.
实际上,SLF4J所提供的核心API是一些接口以及一个LoggerFactory的工厂类。从某种程度上,SLF4J有点类似JDBC,不过比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。如同使用JDBC基本不用考虑具体数据库一样,SLF4J提供了统一的记录日志的接口,只要按照其提供的方
private static final Logger logger = LoggerFactory.getLogger(当前类类名.class);
package com.qf.controller;
?
import com.qf.domain.Shops;
import com.qf.service.ShopsService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
?
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
?
import javax.annotation.Resource;
?
@RestController
public class ShopController {
?
@Resource
private ShopsService shopsService;
?
private static final Logger logger = LoggerFactory.getLogger(ShopController.class);
?
@RequestMapping(value = "findById/{shopId}",method = RequestMethod.GET)
public Shops findById(@PathVariable int shopId){
logger.info("查询,id:[{}]",shopId); //{}用于存储参数,不可省略
return shopsService.findByShopId(sho
logger.info("查询,id:[{}]",shopId); //{}用于存储参数,不可省略
return shopsService.findByShopId(shopId);
}
shopId);
}