以下大部分内容转载整理自 https://blog.csdn.net/vbirdbest/article/details/71751835 ,感谢 vbirdbest 的相关知识分享
slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback),使用接口的好处是当项目需要更换日志框架的时候,只需要更换jar和配置,不需要更改相关java代码
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
-
public
class TestSlf4j {
-
-
// Logger和LoggerFactory导入的是org.slf4j包
-
private
final
static Logger logger = LoggerFactory.getLogger(TestSlf4j .class);
-
}
log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用
-
import org.apache.logging.log4j.LogManager;
-
import org.apache.logging.log4j.Logger;
-
-
public
class TestLog4j {
-
// Logger和LogManager导入的是org.apache.logging包
-
private
static
final Logger LOG = LogManager.getLogger(TestLog4j.class);
-
}
springboot项目中需导入
org.springframework.boot spring-boot-starter-log4j2
绕坑:如项目中有导入spring-boot-starter-web依赖包记得去掉spring自带的日志依赖spring-boot-starter-logging,如下:
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging
springboot方式:
application.properties中添加配置 logging.config=classpath:log4j2_dev.xml, log4j2_dev.xml是你创建的log4j2的配置文件名,放在resources下,如放在其他路径则对应修改
Web工程方式:
-
-
log4jConfiguration
-
/WEB-INF/conf/log4j2.xml
-
-
-
-
class>org.apache.logging.log4j.web.Log4jServletContextListenerlistener-class>
-
listener>
纯Java方式:
-
public static void main(String[] args) throws IOException {
-
File file =
new File(
"D:/log4j2.xml");
-
BufferedInputStream in =
new BufferedInputStream(
new FileInputStream(file));
-
final ConfigurationSource source =
new ConfigurationSource(in);
-
Configurator.initialize(
null, source);
-
-
Logger logger = LogManager.getLogger(
"myLogger");
-
}
配置文件的格式:log2j配置文件可以是xml格式的,也可以是json格式的,
配置文件的位置:log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台,也可以对配置文件自定义位置(需要在web.xml中配置),一般放置在src/main/resources根目录下即可
贴上log4j2_dev.properties的配置再来讲解
-
xml version="1.0" encoding="UTF-8"?>
-
<Configuration status="WARN">
-
<properties>
-
<property name="LOG_HOME">D:/logs
property>
-
<property name="FILE_NAME">mylog
property>
-
<property name="log.sql.level">info
property>
-
properties>
-
-
-
<Appenders>
-
<Console name="Console" target="SYSTEM_OUT">
-
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n" />
-
Console>
-
-
<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
-
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
-
<Policies>
-
<TimeBasedTriggeringPolicy interval="1"/>
-
<SizeBasedTriggeringPolicy size="10 MB"/>
-
Policies>
-
<DefaultRolloverStrategy max="20"/>
-
RollingRandomAccessFile>
-
Appenders>
-
-
<Loggers>
-
<Root level="info">
-
<AppenderRef ref="Console" />
-
<AppenderRef ref="RollingRandomAccessFile" />
-
Root>
-
-
<Logger name="com.mengdee.dao" level="${log.sql.level}" additivity="false">
-
<AppenderRef ref="Console" />
-
Logger>
-
Loggers>
-
Configuration>
log4j2.xml文件的配置大致如下:
- properties
- Appenders
- Console
- PatternLayout
- File
- RollingRandomAccessFile
- Async
- Loggers
- Logger
- Root
- AppenderRef
Configuration:为根节点,有status和monitorInterval等多个属性
- status的值有 “trace”, “debug”, “info”, “warn”, “error” and “fatal”,用于控制log4j2日志框架本身的日志级别,如果将stratus设置为较低的级别就会看到很多关于log4j2本身的日志,如加载log4j2配置文件的路径等信息
- monitorInterval,含义是每隔多少秒重新读取配置文件,可以不重启应用的情况下修改配置
Appenders:输出源,用于定义日志输出的地方
log4j2支持的输出源有很多,有控制台Console、文件File、RollingRandomAccessFile、MongoDB、Flume 等
Console:控制台输出源是将日志打印到控制台上,开发的时候一般都会配置,以便调试
File:文件输出源,用于将日志写入到指定的文件,需要配置输入到哪个位置(例如:D:/logs/mylog.log)
RollingRandomAccessFile: 该输出源也是写入到文件,不同的是比File更加强大,可以指定当文件达到一定大小(如20MB)时,另起一个文件继续写入日志,另起一个文件就涉及到新文件的名字命名规则,因此需要配置文件命名规则
这种方式更加实用,因为你不可能一直往一个文件中写,如果一直写,文件过大,打开就会卡死,也不便于查找日志。
NoSql:MongoDb, 输出到MongDb数据库中
Flume:输出到Apache Flume(Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。)
Async:异步,需要通过AppenderRef来指定要对哪种输出源进行异步(一般用于配置RollingRandomAccessFile)
PatternLayout:控制台或文件输出源(Console、File、RollingRandomAccessFile)都必须包含一个PatternLayout节点,用于指定输出文件的格式(如 日志输出的时间 文件 方法 行数 等格式),例如 pattern=”%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n”
- %d{HH:mm:ss.SSS} 表示输出到毫秒的时间
- %t 输出当前线程名称
- %-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
- %logger 输出logger名称,因为Root Logger没有名称,所以没有输出
- %msg 日志文本
- %n 换行
-
- 其他常用的占位符有:
- %F 输出所在的类文件名,如Log4j2Test.java
- %L 输出行号
- %M 输出所在方法名
- %l 输出语句所在的行数, 包括类名、方法名、文件名、行数
Loggers:日志器
日志器分根日志器Root和自定义日志器,当根据日志名字获取不到指定的日志器时就使用Root作为默认的日志器,自定义时需要指定每个Logger的名称name(对于命名可以以包名作为日志的名字,不同的包配置不同的级别等),日志级别level,相加性additivity(是否继承下面配置的日志器), 对于一般的日志器(如Console、File、RollingRandomAccessFile)一般需要配置一个或多个输出源AppenderRef;
每个logger可以指定一个level(TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF),不指定时level默认为ERROR
additivity指定是否同时输出log到父类的appender,缺省为true。
-
<Logger name="rollingRandomAccessFileLogger" level="trace" additivity="true">
-
<AppenderRef ref="RollingRandomAccessFile" />
-
Logger>
以下为练习写的excel数据存入数据库的controller层代码,其中加入Log4j2
-
import cn.tbj.service.ExcelService;
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.web.bind.annotation.PostMapping;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestParam;
-
import org.springframework.web.bind.annotation.RestController;
-
import org.springframework.web.multipart.MultipartFile;
-
-
-
@RestController
-
@RequestMapping(
"/user")
-
public
class UserController {
-
-
public
final
static Logger logger = LoggerFactory.getLogger(UserController.class);
-
-
@Autowired
-
private ExcelService excelService;
-
-
@PostMapping(
"/import")
-
public boolean addUser(@RequestParam("file") MultipartFile file) {
-
boolean a =
false;
-
String filename = file.getOriginalFilename();
-
System.out.println(
"++++++++++++文件名++++++++"+filename);
-
-
logger.trace(
"trace level");
-
logger.debug(
"debug level");
-
logger.info(
"info level");
-
logger.warn(
"warn level");
-
logger.error(
"error level");
-
-
long beginTime = System.currentTimeMillis();
-
logger.info(
"请求处理结束,耗时:{}毫秒", (System.currentTimeMillis() - beginTime));
//第一种用法
-
logger.info(
"请求处理结束,耗时:" + (System.currentTimeMillis() - beginTime) +
"毫秒");
//第二种用法
-
-
try {
-
a = excelService.batchImport(filename, file);
-
}
catch (Exception e) {
-
e.printStackTrace();
-
}
-
return a ;
-
}
-
}
尝试一些正常和错误的操作,以下为反馈的日志信息