目录
一、pom文件
二、项目配置文件
三、日志配置文件
四、日志监听类
五、日志动态修改服务类
线上系统的日志级别一般都是 INFO 级别,有时候需要查看 WARN 级别的日志,所以需要动态修改日志级别。微服务项目中使用 Nacos 作为注册中心,我们可以监听 Nacos 配置,修改日志级别。
一、pom文件
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.4.0</version>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.0.4.0</version>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
二、项目配置文件增加如下内容
nacos:
config:
# 配置文件
filename: nacos-provider-log-level.json
# 配置GROUP
group: DEFAULT_GROUP
# 配置项key
log:
level: log.level
三、日志配置文件
{
"log.level":"info"
}
四、日志监听类
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.meng.backend.service.LogLevelChangeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.Properties;
import java.util.concurrent.Executor;
/**
* @Author: meng
* @Description: 监听Nacos
* @Date: 2023/6/5 9:52
* @Version: 1.0
*/
@Slf4j
@Configuration
public class LoggerConfigListener {
/**
* 配置中心地址
*/
@Value("${spring.cloud.nacos.discovery.server-addr}")
private String serverAddr;
/**
* 命名空间ID
*/
// @Value("${nacos.config.namespace}")
// private String namespace;
/**
* 配置文件
*/
@Value("${nacos.config.filename}")
private String dataId;
/**
* 配置GROUP
*/
@Value("${nacos.config.group}")
private String group;
/**
* 配置项key
*/
@Value("${nacos.config.log.level}")
private String logLevelName;
@Autowired
private LogLevelChangeService logLevelChangeService;
/**
* 动态修改日志级别
*/
@PostConstruct
public void init() {
try {
log.info("init NacosConfigListener start...");
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
// properties.put(PropertyKeyConst.NAMESPACE, namespace);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
if (StrUtil.isBlank(content)) {
log.info("log config is empty");
return;
}
log.info("log config is :{}", content);
configService.addListener(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
try {
JSONObject jsonObject = JSONObject.parseObject(configInfo);
Object levelObj = jsonObject.get(logLevelName);
if (levelObj != null) {
logLevelChangeService.changeLogLevel(levelObj.toString());
}
}
catch (Exception e) {
log.error("receiveConfigInfo exception:", e);
}
}
@Override
public Executor getExecutor() {
return null;
}
});
log.info("init NacosConfigListener end...");
}
catch (NacosException e) {
log.error("NacosConfigListener exception:{}", e.getMessage());
}
}
}
五、日志动态修改服务类
/**
* @Author: meng
* @Description: 动态调整日志级别
* @Date: 2023/6/5 9:56
* @Version: 1.0
*/
public interface LogLevelChangeService {
boolean changeLogLevel(String level);
}
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import com.meng.backend.service.LogLevelChangeService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* @Author: meng
* @Description: 动态调整日志级别
* @Date: 2023/6/5 9:56
* @Version: 1.0
*/
@Slf4j
@Service
public class LogLevelChangeServiceImpl implements LogLevelChangeService {
@Override
public boolean changeLogLevel(String level) {
try {
log.info("level:{}", level);
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = loggerContext.getLogger("ROOT");
switch (level) {
case "trace":
logger.setLevel(Level.TRACE);
break;
case "debug":
logger.setLevel(Level.DEBUG);
break;
case "info":
logger.setLevel(Level.INFO);
break;
case "warn":
logger.setLevel(Level.WARN);
break;
case "error":
logger.setLevel(Level.ERROR);
break;
default:
break;
}
return true;
}
catch (Exception e) {
log.error("changeLogLevel exception:", e);
return false;
}
}
}