springboot03-日志功能
日志框架
- 日志框架分为日志门面和日志实现.
- 使用时要选择一个日志门面作为抽象层, 再选一日志实现来作为其实现.
- 下图列出了常用的日志框架.
- SpringBoot底层是Spring框架, 而Spring框架默认使用JCL, 故SpringBoot在框架内容部分也使用JCL.
- 但是spring-boot-starter-logging采用了slf4j+logback的形式.
- 当然, springboot也能自动适配(jul, log4j2)等日志, 并简化配置.
SLF4j
在系统中使用slf4j
- 首先要知道, 以后开发时, 日志记录方法的调用, 不应该直接调用日志的实现类, 而是调用日志抽象层里的方法.
- 给系统里面导入slf4j的jar包和和logback的jar包
- slf4j的使用演示
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("hello world"); } }
- 虽说使用了slf4j, 但配置文件还是做成日志实现框架自己本身的配置文件.
- 适配层可以帮助我们解决slf4j和日志框架不匹配的问题
遗留问题
- 众所周知, Spring使用commons-logging, Hibernate使用Jboss-logging, ....
- 使用的日志框架, 太多太杂, 所以我们需要统一日志记录, 即使别的框架也要一起使用slf4j.
- 那么如何让系统中所有的日志都统一到slf4j上? 三步
- 将系统中其他日志框架排除出去.
- 用对应的中间包替换原有的日志框架.
- 导入slf4j的具体实现.
SpringBoot的日志关系
- SpringBoot使用它来做日志功能
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency>
- 其底层依赖关系
- 如图, SpringBoot底层使用slf4j+logback的方式进行日志记录.
- SpringBoot把其他日志也都转成了slf4j
- 看一下中间替换包, 实际上和原本的包名类名都没变.
- 但是这里是用SLF4J的方式创建的, 以LogFactory为例
public abstract class LogFactory { static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j"; static LogFactory logFactory = new SLF4JLogFactory(); ......
- springBoot能自动适配所有日志, 如果我们要引入其他框架, 一定要把这个框架的默认日志依赖移除掉!
- 举例: Spring框架底层用commons-logging, 但SpringBoot一上来就排除了它
<dependency> <groupId>org.springframework</groupId> <artifactId>spring‐core</artifactId> <exclusions> <exclusion> <groupId>commons‐logging</groupId> <artifactId>commons‐logging</artifactId> </exclusion> </exclusions> </dependency>
- 举例: Spring框架底层用commons-logging, 但SpringBoot一上来就排除了它
日志的使用
默认配置
- SpringBoot已经默认帮我们配置好了日志, 可以直接使用
@RunWith(SpringRunner.class) @SpringBootTest public class SpringBootLoggingApplicationTests { //记录器 Logger logger = LoggerFactory.getLogger(getClass()); @Test public void contextLoads() { logger.trace("这是trace日志..."); logger.debug("这是debug日志..."); logger.info("这是info日志..."); logger.warn("这是warn日志..."); logger.error("这是error日志..."); } }
- 代码讲解
- 日志级别, 从低到高: trace, debug, info, warn, error
- 可以调整输出日志的级别, 日志只会在这个级别及更高级别生效.
- 若没有指定级别, 那么就是用SpringBoot的默认级别: info.
- 在配置文件中修改日志的默认配置
#修改日志级别 logging.level.包名=trace/debug/... #注意, logging.file.path和logging.path只能二选一 #不指定路径, 则logging.file.path在当前项目下生成日志文件 #logging.file.path=springboot.log #也可以指定完整路径 logging.file.path=D:/springboot.log #在控制台指定输出日志的格式 logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n #指定文件中日志的输出格式 logging.pattern.file=%d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n
- 日志输出格式
- %d表日期
- %thread表示线程名
- %‐5level:级别从左显示5个字符宽度
- %logger{50} 表示logger名字长50个字符, 否则按照句点分割.
- %msg: 日志消息
- %n: 换行符.
指定配置
- 在resources下放上每个日志框架的配置文件, SpringBoot就不会用默认配置了, 而用我们写的配置.
- Logback的配置文件名一定要写成: logback.xml或logback-spring.xml.
- 如果用logback.xml为名: 它会直接被日志框架识别, 绕过了SpringBoot.
- 如果用logback-spring.xml为名, 则日志框架不能直接加载日志的配置项, 而由SpringBoot加载, 这样我们就能使用springProfile功能了.
- SpringProfile功能举例
<layout class="ch.qos.logback.classic.PatternLayout"> <!-- 指定什么环境使用什么模式 --> <!-- dev模式 --> <springProfile name="dev"> <pattern> %d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %‐5level %logger{50} ‐ %msg%n </pattern> </springProfile> <!-- 非dev模式 --> <springProfile name="!dev"> <pattern> %d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level %logger{50} ‐ %msg%n </pattern> </springProfile> </layout>
- 注意: 如果使用logback.xml作为文件名, 但还要使用profile功能, 会报错
- Java.lang.IllegalStateException: Logback configuration error detected:
- no applicable action for [springProfile]