日志级别有高到低;
fatal(致命) :直接程序报错
error
info
debug
trace(堆栈)
日志级别为fatal只会输出 fatal 错误
日志级别为error会输出 error 错误,fatal错误
........
日志框架:
根据日志门面和日志实现来划分日志框架:
日志门面有:JCL, Slf4j,jboss-logging
日志实现有:log4j,log4j2,logback,JUL。
对于JCL(commons-logging):spring框架日志是以他作为门面的,本身没有实现真正的日志能力,它依赖其他的日志系统如log4j或者java本身的java.util.logging。可以通过配置文件来设定最终使用log4j还是java.util.logging。没有配置log4j的时候就会调用java.util.logging包。一旦程序中检测 log4j在classpath,Commons Logging将会使用log4j作为底层实现。
SpringMVC日志
原来的spring框架中以JCL为日志接口,java.util.logging为日志实现的,网上说如果spring识别到 log4j配置在classpath,Commons Logging将会使用log4j作为底层实现。如果需要改变spring框架的日志接口。参考spring Boot的日志。
我们自己应用可以用slf4j为日志接口(调用slf4j的api),log4j为日志实现,可以不用管spring的日志。
1、配置
在pom.xml添加(https://mvnrepository.com/artifact/log4j/log4j)
适配器:目的将log4j和slf4j进行绑定,原本log4j框架被开发根本没有想到slf4j(之后才出来的),所以他没有按照slf4j定义的样式开发,后来又开发出新的日志框架logback,slf4j才被开发出来,让所有的日志类实现这个slf4j。
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency>
在 src/main/resources
目录下创建名为 log4j.properties
的属性配置文件
log4j.rootLogger=INFO, console, file log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=logs/log.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.A3.MaxFileSize=1024KB log4j.appender.A3.MaxBackupIndex=10 log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n
日志配置相关说明:
log4j.rootLogger
:根日志,配置了日志级别为INFO
,预定义了名称为console
、file
两种附加器log4j.appender.console
:console 附加器,日志输出位置在控制台log4j.appender.console.layout
:console 附加器,采用匹配器布局模式log4j.appender.console.layout.ConversionPattern
:console 附加器,日志输出格式为:日期 日志级别 [类名] - 消息换行符
log4j.appender.file
:file 附加器,每天产生一个日志文件log4j.appender.file.File
:file 附加器,日志文件输出位置logs/log.log
log4j.appender.file.layout
:file 附加器,采用匹配器布局模式log4j.appender.A3.MaxFileSize
:日志文件最大值log4j.appender.A3.MaxBackupIndex
:最多纪录文件数log4j.appender.file.layout.ConversionPattern
:file 附加器,日志输出格式为:日期 日志级别 [类名] - 消息换行符
如果上面的配置不行,使用下面的
log4j.rootCategory=debug, console, file //如果配置的是info,那么在输出日志的时候,logger.debug("xx")就不会打印,info比debug级别高 #log4j.logger.com.zy.servlet=debug,console,file //表示局部的日志输出(如果配置了全局了,就不用写了) log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=${catalina.home}/logs/log.log //${catalina.home}这个在tomcat服务器下,或者直接配合绝对路径,不可以用相对路径(测试过) log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.A3.MaxFileSize=1024KB log4j.appender.A3.MaxBackupIndex=10 log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n
2、使用
注意使用占位符:减少内存开销
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Test { private static final Logger logger = LoggerFactory.getLogger(Test.class); public static void main(String[] args) { String test1 = "测试"; String test2 = "测试2"; logger.info("{} {}",test1,test2); } }
Spring Boot日志(内部使用logback作为日志实现)
spring boot让系统中所有的日志都统一到slf4j,这是如何实现的呢?
1、将系统中其他日志框架先排除出去,防止jar包冲突
2、用中间包来替换原有的日志框架;
3、我们导入slf4]其他的实现
以spring boot 1.x 版本看,它排除了commons-logging,映入了代替他的包 jcl-over-slf4j,jar(注意这个包里面是包含comons-logging中的class的,不然spring找不到响应的class,就会报错,他本质上还是调用自己的接口,只是这个接口由中的方法不一样了),但是spring boot2.x 又改动了
使用
1、配置
参考:https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/boot-features-logging.html
1、在application.properties配置
##指定目录 #logging.level.com.zy.springbootproject.SpringbootProjectApplicationTests=trace ##全局配置 ##logging.level.root=debug # ##如果不指定目录,只要文件名,就会在当前项目下生成一个日志文件 ##logging.file=springBoot.log ##如果指定了目录,就在当前目录下生成配置文件(项目下不会生成配置文件了) ##logging.file=D:/logs/springboot.log # ##在当前磁盘的根路径下创建spring文件夹,使用spring.log作为默认文件 #logging.path=/spring # ##在控制台输出的日志格式 #logging.pattern.console==%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread]%-5level %logger{50}-%msg%n
1、或者创建 logback.xml,最好将名字改为logback-spring.xml,原因配置文件中有解释(参考)
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒,当scan为true时,此属性生效。默认的时间间隔为1分钟。 debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="false" scanPeriod="60 seconds" debug="false"> <!--解析配置文件的时间戳--> <timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/> <!--上下文名称,默认名称为"default"--> <contextNmae>${time}</contextName> <!-- 定义日志的根目录 --> <property name="LOG_HOME" value="/var/log"/> <!-- 定义日志文件名称 --> <property name="appName" value="spring"></property> <!-- SpringBoot的特性,与property类似,只是并不是直接指定给name一个value值, 而是通过source从环境中获取值,并且可以设置一个默认值 --> <springProperty scope = "context" name = "hostName" source = "host.name" defaultValue = "localhost"/> <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 --> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <!-- 日志输出格式: %d表示日期时间, %thread表示线程名, %-5level:级别从左显示5个字符宽度 %logger{50} 表示logger名字最长50个字符,否则按照句点分割 %msg:日志消息 %n是换行符 --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </layout> </appender> <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 --> <appender name="fileLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 指定日志文件的名称 --> <file>${LOG_HOME}/${appName}.log</file> <!-- 当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名 TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责触发滚动。 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动 %i:当文件大小超过maxFileSize时,按照i进行文件滚动 --> <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动, 且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是, 那些为了归档而创建的目录也会被删除。 --> <MaxHistory>365</MaxHistory> <!-- 当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 日志输出格式: --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender> <!-- logger主要用于存放日志对象,也可以定义日志类型、级别 name:表示匹配的logger类型前缀,也就是包的前半部分 level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出, false:表示只用当前logger的appender-ref true:表示当前logger的appender-ref和rootLogger的appender-ref都有效 --> <!-- hibernate logger --> <logger name="com.yt" level="debug" /> <!-- Spring framework logger --> <logger name="org.springframework" level="debug" additivity="false"> <!--指定appender,如果没有指定则继承root--> <appender-ref ref="stdout" /> </logger> <!--springProfile是SpringBoot的特性,日志配置文件名必须是*-spring.xml(比如将logback.xml改为logback-spring.xml) 用于指定不同的profile,可以使用在configuration标签内任意位置 --> <springProfile name="prod,!dev"> <!-- root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应, 要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。 --> <root level="info"> <appender-ref ref="stdout" /> <appender-ref ref="fileLogAppender" /> </root> </springProfile> <springProfile name="dev"> <root level="debug"> <appender-ref ref="stdout" /> <appender-ref ref="fileLogAppender" /> </root> </springProfile> </configuration>
1、或者 创建 logback.xml(参考)
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="E:logs" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%line:行号,%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n</pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/system/sysWeb-%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- show parameters for hibernate sql 专为 Hibernate 定制 --> <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" /> <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" /> <logger name="org.hibernate.SQL" level="DEBUG" /> <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <!-- 日志输出级别 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> <!--分包输出日志,分包配置--> <appender name="serviceAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/service/Service-%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <appender name="controllerAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/controller/Controller-%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--分包输出日志,分包指向--> <logger name="com.example.demo" level="DEBUG" additivity="false"> <appender-ref ref="controllerAppender" /> </logger> </configuration>
2、使用
@RunWith(SpringRunner.class) @SpringBootTest public class SpringbootProjectApplicationTests { @Test public void test(){ Logger logger = LoggerFactory.getLogger(SpringbootProjectApplicationTests.class); logger.info("xxx"); } }
Spring Boot日志切换框架(了解)
如果需要使用log4j
1.首先根据排除原本框架的依赖
2、根据下面添加依赖
pom展示
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>log4j-to-slf4j</artifactId> <groupId>org.apache.logging.log4j</groupId> </exclusion> <exclusion> <artifactId>logback-classic</artifactId> <groupId>ch.qos.logback</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> </dependency>
3、添加配置,在resourcs下创建log4j.properities
登录日志
不管在前台还是后台用户登录,不管是本次登录成功还是失败,都需要记录登录的日志:登录的日志记录了本次登录的时间,ip,登录结果等信息:
登录日志可以有效的查看用户的登录记录。
从运营数据来说,通过前端用户的登承日志,可以分析出这个用户的粘度:可以用来分析整个网站的用户活跃度等内容:
从安全性来说,通过登录日志可以查看是否有人恶意登录或者恶意猜测用户密码的情况:可以用于系统前端或者后端的安全预警:
方式1:
1、建表和pojo对象(可以由表逆向生成)
保存用户登录时候的那些数据日志(是保存用户登录成功的信息,还是只要登录就保存日志)
2、controller
在用户登录的时候,就插入日志的操作。