背景
项目(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>