springboot 动态指定日志路径(logback) 自动跟随项目路径

本文介绍了解决Jar包在不同环境下启动时日志路径不一致的问题,通过自定义日志上下文监听器获取项目路径,并在logback.xml中使用该路径作为日志输出目录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

项目(jar项目)开发时,日志文件输出路径配置的为相对路径(与项目src是同一个目录):在这里插入图片描述

问题 (希望日志跟随jar文件目录生成)

在项目部署(cmd 直接运行jar文件)时,如果在jar文件下启动,日志输出路径没有问题(与jar同一文件夹),但使用全路径启动时,log文件夹则生成在运行命令的所在盘符中(如:路径在C盘下,启动在E盘下的jar,log日志则在C盘中):
在这里插入图片描述

解决

办法一

使用配置文件,配置输出路径,参考:
SpringBoot项目在logback.xml中读取配置中的日志路径问题
这种办法需要每次发布时,要先配置输出路径,不是我想要的。

办法二

项目启动时,获得项目存放的路径,将路径加载到日志配置文件中作为日志输出路径:

第一步获取项目所在路径:

可以参考我另一篇获取项目路径的文章:
使用全路径启动jar包,获取全路径(win、linux通用)

第二步监听日志上下文,将路径写入配置文件中

1、代码:

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.LifeCycle;

public class CustomLogContextListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {

    /** 存储日志路径标识 */
    public static final String LOG_PAHT_KEY = "LOG_PATH";

    @Override
    public void start() {
    URL urls = LoggerManage.class.getProtectionDomain().getCodeSource().getLocation();
		String filePath=null;
		try{
			filePath=URLDecoder.decode(urls.getPath(),"utf-8");//转化为utf-8编码
			System.out.println("CustomLogContextListener_start_filePath:"+filePath);
		}catch(Exception e){
			e.printStackTrace();
		}
        System.setProperty(LOG_PAHT_KEY, filePath);
        Context context = getContext();
        context.putProperty(LOG_PAHT_KEY,  filePath);
    }

 	@Override
    public boolean isResetResistant() {
        return false;
    }

    @Override
    public void onStart(LoggerContext context) {

    }

    @Override
    public void onReset(LoggerContext context) {

    }

    @Override
    public void onStop(LoggerContext context) {

    }

    @Override
    public void onLevelChange(Logger logger, Level level) {

    }

    @Override
    public void stop() {

    }

    @Override
    public boolean isStarted() {
        return false;
    }
}

2、日志配置文件(2处)

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
	<contextName>logback</contextName>


	<!-- 1、将监听类加入到xml -->
	 <contextListener class="com.x.x.x.listener.CustomLogContextListener" />


	<!--输出到控制台 -->
	<appender name="console"
		class="ch.qos.logback.core.ConsoleAppender">
		<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息 -->
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>debug</level>
		</filter>
		<encoder>
			<pattern>
				%d %p (%file:%line\)- %m%n
			</pattern>
			<charset>utf-8</charset>
		</encoder>
	</appender>

	<!--输出到info -->
	<appender name="info"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			
			
			<!-- 2、直接使用监听类的变量${LOG_PATH} -->
			<fileNamePattern>${LOG_PATH}/log/info-%d{yyyy-MM-dd}.log</fileNamePattern>


		</rollingPolicy>
		<append>true</append>
		<encoder>
			<pattern>
				%d %p (%file:%line\)- %m%n
			</pattern>
			<charset>utf-8</charset>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印INFO日志 -->
			<level>INFO</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<!--输出到error -->
	<appender name="error"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_PATH}/log/error-%d{yyyy-MM-dd}.log</fileNamePattern>
		</rollingPolicy>
		<append>true</append>
		<encoder>
			<pattern>
				%d %p (%file:%line\)- %m%n
			</pattern>
			<charset>utf-8</charset>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印ERROR日志 -->
			<level>ERROR</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<!--输出到warn -->
	<appender name="warn"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_PATH}/log/warn-%d{yyyy-MM-dd}.log</fileNamePattern>
		</rollingPolicy>
		<append>true</append>
		<encoder>
			<pattern>
				%d %p (%file:%line\)- %m%n
			</pattern>
			<charset>utf-8</charset>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印WARN日志 -->
			<level>WARN</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<!--分别设置对应的日志输出节点 -->
	<root level="info">
		<appender-ref ref="console" />
		<appender-ref ref="info" />
		<appender-ref ref="error" />
		<appender-ref ref="warn" />
	</root>

</configuration>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值