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

news2024/11/16 1:38:58

目录

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

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是网络攻击?阿里云服务器可以避免被攻击吗?

网络攻击是指:损害网络系统安全属性的任何类型的进攻动作。进攻行为导致网络系统的机密性、完整性、可控性、真实性、抗抵赖性等受到不同程度的破坏。 网络攻击有很多种&#xff0c;网络上常见的攻击有DDOS攻击、CC攻击、SYN攻击、ARP攻击以及木马、病毒等等&#xff0c;所以再…

CTO对生活和工作一点感悟

陌生人&#xff0c;你好啊。 感谢CSDN平台让我们有了隔空认识&#xff0c;交流的机会。 我是谁&#xff1f; 我呢&#xff0c;毕业快11年&#xff0c;在网易做了几年云计算&#xff0c;后来追风赶上了大数据的浪潮&#xff0c;再到后来混迹在AI、智能推荐等领域。 因为有一颗…

SS8847T 双通道 H 桥驱动芯片 替代DRV8847

SS8847E是一款双桥电机驱动器&#xff0c;具有两个H桥驱动器&#xff0c;可以驱动两个直流有刷电机&#xff0c;一个双极步进电机&#xff0c;螺线管或其他感性负载。该器件的工作电压范围为 2.7V 至 15V&#xff0c;每通道可提供高达 1.0A 的负载电流。每个H桥的输出驱动器模块…

2023年安全员-A证证模拟考试题库及安全员-A证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年安全员-A证证模拟考试题库及安全员-A证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;安全员-A证证模拟考试题库是根据安全员-A证最新版教材&#xff0c;安全员-A证大纲整理而成&#xff08;含2023年…

navigator.clipboard is undefined in JavaScript issue [Fixed]

navigator.clipboard 在不安全的网站是无法访问的。 在本地开发使用localhost或127.0.0.1没有这个问题。因为它不是不安全网站。 在现实开发中&#xff0c;可能遇到测试环境为不安全网站。 遇到这个问题&#xff0c;就需要将不安全网站标记为非不安全网站即可。 外网提供了3…

python动态加载内容抓取问题的解决实例

问题背景 在网页抓取过程中&#xff0c;动态加载的内容通常无法通过传统的爬虫工具直接获取&#xff0c;这给爬虫程序的编写带来了一定的技术挑战。腾讯新闻&#xff08;https://news.qq.com/&#xff09;作为一个典型的动态网页&#xff0c;展现了这一挑战。 问题分析 动态…

【开源视频联动物联网平台】视频接入网关的用法

视频接入网关是一种功能强大的视频网关设备&#xff0c;能够解决各种视频接入、视频输出、视频转码和视频融合等问题。它可以在应急指挥、智慧融合等项目中发挥重要作用&#xff0c;与各种系统进行对接&#xff0c;解决视频能力跨系统集成的难题。 很多视频接入网关在接入协议…

Go 语言输出文本函数详解

Go语言拥有三个用于输出文本的函数&#xff1a; Print()Println()Printf() Print() 函数以其默认格式打印其参数。 示例 打印 i 和 j 的值&#xff1a; package mainimport "fmt"func main() {var i, j string "Hello", "World"fmt.Print(…

【力扣:526】优美的排列

状态压缩动态规划 原理如下&#xff1a; 遍历位图可以得到所有组合序列&#xff0c;将这些序列的每一位看作一个数&#xff0c;取序列中1总量的值作为每轮遍历的位&#xff0c;此时对每个这样的位都能和所有数进行匹配&#xff0c;因为一开始就取的是全排列&#xff0c;并且我们…

MySQL表的查询、更新、删除

查询 全列查询 指定列查询 查询字段并添加自定义表达式 自定义表达式重命名 查询指定列并去重 select distinct 列名 from 表名 where条件 查询列数据为null的 null与 (空串)是不同的&#xff01; 附&#xff1a;一般null不参与查询。 查询列数据不为null的 查询某列数据指定…

陈嘉庚慈善践行与卓顺发的大爱传承

陈嘉庚慈善践行&#xff0c;了解陈嘉庚后人与卓顺发的大爱传承。 2023年11月25日,卓顺发太平绅士以及陈家后人在分享他们对慈善领域见解的过程中,特别强调了慈善在促进社会和谐以及推动社会进步方面的关键作用。同时,他们深入探讨了如何在当今社会中继续传扬和实践家国情怀以及…

C++ CryptoPP使用AES加解密

Crypto (CryptoPP) 是一个用于密码学和加密的 C 库。它是一个开源项目&#xff0c;提供了大量的密码学算法和功能&#xff0c;包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto 的目标是提供高性能和可靠的密码学工具&#xff0c;以满足软件开发中对…

什么是木马

木马 1. 定义2. 木马的特征3. 木马攻击流程4. 常见木马类型5. 如何防御木马 1. 定义 木马一名来源于古希腊特洛伊战争中著名的“木马计”&#xff0c;指可以非法控制计算机&#xff0c;或在他人计算机中从事秘密活动的恶意软件。 木马通过伪装成正常软件被下载到用户主机&…

strstr 的使用和模拟实现

就位了吗&#xff1f;如果坐好了的话&#xff0c;那么我就要开始这一期的表演了哦&#xff01; strstr 的使用和模拟实现: char * strstr ( const char * str1, const char * str2); Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 i…

030 - STM32学习笔记 - ADC(四) 独立模式多通道DMA采集

030 - STM32学习笔记 - ADC&#xff08;四&#xff09; 独立模式多通道DMA采集 中断模式和DMA模式进行单通道模拟量采集&#xff0c;这节继续学习独立模式多通道DMA采集&#xff0c;使用到的引脚有之前使用的PC3&#xff08;电位器&#xff09;&#xff0c;PA4&#xff08;光敏…

Peter算法小课堂—高精度乘法

给大家看个小视频13 高精度算法 乘法_哔哩哔哩_bilibili 乘法竖式 大家觉得Plan A好&#xff0c;还是Plan B好呢&#xff08;对于计算机来说&#xff09;&#xff1f;那显然是B啦 x*y问题 mul思路&#xff1a;mul()函数返回x数组乘y数组的积&#xff0c;保存在z数组。根据上…

基于SpringBoot的旅游网站的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;旅游网站当然也不能排除在外&#xff0c;随着旅游网站的不断成熟&#xff0c;它彻底改变了过去传统的旅游网站方式&#xff0c;不仅使旅游管理…

three.js结合vue

作者&#xff1a;baekpcyyy&#x1f41f; 1.搭建环境 ps&#xff1a;这里要按照node.js在之前有关vue搭建中有介绍 新建文件夹并在vsc终端中打开 1.输入vite创建指令 npm init vitelatest然后我们cd进入刚才创建的目录下 npm install安装所需依赖 npm run dev启动该项目 …

Python正则表达式:match()和search()函数全面解读

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;正则表达式是强大的工具&#xff0c;能够用于文本匹配、搜索和替换。re模块提供了许多函数来处理正则表达式&#xff0c;其中match()和search()是两个常用的函数。本文将深入探讨这两个函…

论文复现代码《基于自适应哈夫曼编码的密文可逆信息隐藏算法》调试版

前言 本文展示论文《基于自适应哈夫曼编码的密文可逆信息隐藏算法》的复现代码。代码块的结构如下&#xff1a; 其中&#xff0c;每个代码块都包含了测试该代码块的功能的主函数代码&#xff0c;使用时可放心运行&#xff0c;前提是你按照这个包结构把文件命名改好&#xff0c…