SpringBoot-监听Nacos动态修改日志级别

目录

一、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;
		}
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/216454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机与CFD模拟仿真:技术的融合与应用

计算机与CFD模拟仿真:技术的融合与应用 引言 随着科技的不断发展,计算机技术与计算流体力学(CFD)模拟仿真在各个领域的应用越来越广泛。本文将详细介绍计算机技术与CFD模拟仿真在各领域中的应用,包括航空航天、汽车设计、能源电力、环境工程等。通过深入探讨计算机技术与…

matplotlib可视化PCA后的重建图像及重建误差

代码 import numpy as np import matplotlib.pyplot as plt from sklearn.decomposition import PCA from sklearn.datasets import fetch_olivetti_faces# 加载Olivetti人脸数据集 data fetch_olivetti_faces() X data.data images data.images# 设置不同的PCA组件数 comp…

ENVI植被指数阈值法

植被指数阈值法提取纯净像元 首先用ENVI打开无人机遥感影像 1. 假彩色显示 打开数据管理工具&#xff0c;无人机的4波段为红边波段 2. 波段计算 打开band math&#xff0c;输入 float(b1-b2)/(b1b2) 选择对应波段 3. 阈值筛选 阈值按经验值选的0.7&#xff0c;ndvi…

Linux:dockerfile编写搭建mysql练习(10)

搭建了httpyum仓库 Dockerfile 主要文件 基于centos基础镜像 centos.repo yum仓库 db_init.sh mysql初始化脚本 run.sh 启动脚本 vim Dockerfile写入FROM centosMAINTAINER teacher lyRUN mkdir /etc/yum.repos.d/bak ; mv /etc/yu…

一个可用于临床的食管癌远处转移预测模型(shiny APP)

一个可用于临床的食管癌远处转移预测模型&#xff08;APP&#xff09; 最近将之前构建的一个预测食管癌远处转移模型制作成了APP&#xff08;地址见文末&#xff09;&#xff0c;有一些思考&#xff0c;和大家分享如下&#xff1a; 1. 充分的说明 首先&#xff0c;对模型的…

Nacos与Eureka的区别

Nacos的服务实例分为两种l类型&#xff1a; 临时实例&#xff1a;如果实例宕机超过一定时间&#xff0c;会从服务列表剔除&#xff0c;默认的类型。非临时实例&#xff1a;如果实例宕机&#xff0c;不会从服务列表剔除&#xff0c;也可以叫永久实例。 配置一个服务实例为永久…

翻硬币(第四届蓝桥杯省赛C++B组)(java版)

//翻硬币,每次都会改变两个硬币的状态 //因此我们可以从前往后枚举,s1[i] 与 s2[i] 状态不同就改变它的状态 //同时s1[i 1] 与 s2[i 1] 的状态会因此改变 // 所以继续往下枚举s1[i 1] 与 s2[i 1] //因为题目有说必须有解,因此枚举到 n - 1位的时候&#xff0c;两个字符串的…

从印刷机到数据库:自动化如何提高生产力和改善生活

一文了解从自动化到数据库的前世今生。 作者&#xff1a;Kevin Kline 本文来源&#xff1a;https://www.dbta.com/&#xff0c;爱可生开源社区翻译。 本文约 2200 字&#xff0c;预计阅读需要 8 分钟。 自动化的历史 人类长期以来一直梦想着自动化的前景。我们最早的祖先将其想…

【C语言学习疑难杂症】第6期:C语言中如何打印一些特殊字符,比如打印扩展ascii码字符

首先我们来看下ascii表和ascii拓展表: ascii表中的字符只有128个,是从0-127,而拓展ascii表的内容是128-255。拓展表中它们都是一些特殊的字符,如果我们想答应ascii拓展码中的一些字符应该要怎么操作呢? 比如下面的代码: unsigned char a = 176, b = 219;printf("%…

音频/视频、信息和通信技术设备安全标准UL62368-1

UL 62368-1&#xff0c;第 3 版&#xff0c;2019 年 12 月 13 日- UL 音频/视频、信息和通信技术设备安全标准 - 第 1 部分&#xff1a;安全要求 IEC 62368 的这一部分适用于该领域内电气和电子设备的安全音频、视频、信息和通信技术&#xff0c;以及额定电压不超过 600 V 的商…

select选择框里填充图片,下拉选项带图片

遇到一个需求&#xff0c;选择下拉框选取图标&#xff0c;填充到框里 1、效果展示 2、代码 <el-form-item label"工种图标" class"Form_icon Form_label"><el-select ref"select" :value"formLabelAlign.icon" placeholder&…

2023.12.3 关于 Spring 拦截器 和 过滤器

目录 引言 Spring 拦截器实现 实例理解 Spring 过滤器实现 实例理解 拦截器和过滤器的区别 出身不同 触发时机不同 底层实现不同 支持的项目类型不同 使用场景不同 引言 原生 Spring AOP 实现统一拦截有两个难点难点一&#xff1a;定义拦截规则表达式 难点二&#…

双12取消!淘宝年终好价节对商家有何影响?电商直播到底怎么玩差异化?

&#xfeff;据淘宝商家服务大厅显示&#xff0c;今年“双12”活动取消&#xff0c;并更改为平台大型活动“淘宝年终好价节”。淘宝“双12”一直以来都是除了“双11”和“618”之外很重要的电商促销活动&#xff0c;该活动于2012年首次推出&#xff0c;至今已经持续进行了10年。…

数实融合!低代码推动工业数字化转型走“深”向“实”

当下&#xff0c;“数字化、智能化”已经不再是新鲜词。毕竟&#xff0c;在早几年前就已经有企业喊出大举进军数字化的口号&#xff0c;轰轰烈烈的数字化转型运动也持续了很长一段时间&#xff0c;有一些业内人士甚至判断“如今的企业数字化已经走过了成熟期&#xff0c;来到了…

数字与数学基础问题

关卡名 数字与数学基础问题 我会了✔️ 内容 1.数字里统计的处理技巧 ✔️ 2.必须熟练掌握溢的处理方法 ✔️ 3.掌握进制的处理方法 ✔️ 1. 数字统计专题 统计一下特定场景下的符号&#xff0c;或者数字个数等是一类非常常见的问题 。如果按照正常方式强行统计&#xf…

蓝桥杯物联网竞赛_STM32L071_9_按键矩阵扩展模块

原理图&#xff1a; 矩阵按键原理图&#xff1a; 实验板接口原理图&#xff1a; 得到对应图&#xff1a; 扫描按键原理&#xff1a; 按键的COLUMN1、2、3分别制0&#xff0c;每次只允许其中一个为0其他都是1&#xff08;POW1和POW2正常状况为上拉&#xff09;&#xff0c;当有…

S32K116新建工程Debug可以运行,冷启动无法运行问题分析

S32K116使用IAR建立工程后&#xff0c;软件debug可以运行&#xff0c;断电冷启动无法运行。 这种现象基本上都是RAM未初始化导致&#xff0c;由于Debug时&#xff0c;调试器会自动初始化芯片&#xff0c;很多问题都不会暴露处理。 大家可以开一下Startup的汇编文件&#xff0c;…

LInux组管理及拓展

目录 一、Linux组管理 &#xff08;一&#xff09;、组的概述 1.概述 2.作用 &#xff08;二&#xff09;、组操作 1.创建 2.修改 3.删除 4.添加用户 二、用户信息查看 &#xff08;一&#xff09;、id &#xff08;二&#xff09;、finger &#xff08;三&#x…

Go 语言中的函数调用。

更好的观看体验&#xff0c;请点击——函数调用 | YinKais Blog 本文将从函数的调用惯例和参数传递方法两个方面分别介绍函数执行的过程。 1、调用惯例 对于不同的编程语言&#xff0c; 它们在调用函数的时候往往都使用相同的语法&#xff1a; somefunction(arg0, arg1) 虽…

你离高级开发只差这些IntelliJ IDEA Debug使用技巧

目录 引言 IntelliJ IDEA&#xff0c;由JetBrains&#xff08;捷克共和国&#xff09;开发的一款强大的Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;因其丰富的功能、智能的代码辅助以及用户友好的界面设计&#xff0c;在全球范围内广受Java开发者的喜爱&#xf…