Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)

1 日志路径带来的痛点

Java 项目中少不了要和log4j等日志框架打交道, 开发环境和生产环境下日志文件的输出路径总是不一致, 设置为绝对路径的方式缺少了灵活性, 每次变更项目路径都要修改文件, 目前想到的最佳实现方式是: 根据项目位置自动加载并配置文件路径.

本文借鉴 Tomcat 的配置方式 “${catalina.home}/logs/catalina.out”, 通过相对路径的方式设置日志的输出路径, 有其他解决方案的小伙伴, 请直接评论区交流哦😯

2 log4j.properties文件的配置

# 设置要输出的日志的级别 - 注意: properties文件中的注释信息只能处于行首, 不要跟在行尾
log4j.rootLogger=INFO,stdout,logfile

### 输出到控制台, Java程序运行时的标准输出信息
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 2019-05-25 19:09:46
log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n

### 输出到日志文件
# 按天滚动生成, 不支持MaxFileSize, 而RollingFileAppender支持
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
# 项目的logs目录下
# log4j.appender.logfile.File=${base.dir}/logs/elastic-server.log
log4j.appender.logfile.Append=true
# 输出INFO及以上的日志, 按日期滚动就无须配置单个日志文件的最大体积了
log4j.appender.logfile.Threshold=INFO
# log4j.appender.logfile.MaxFileSize=100MB
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n

3 彻底解决痛点

3.1 单独的Java程序包 (非Java Web项目)

单独的Java程序包, 需要通过命令java -jar或java -cp的方式启动;

我们可以在启动命令中加入系统运行时变量, 在log4j加载配置文件之前通过System.getProperties("path")读取此变量, 即可实现灵活加载当前路径.

(1) 启动脚本设置:

假设当前项目的目录结构为:

/Projects/KafkaConsumer
丨 bin 项目的启动脚本
丨 conf 项目的配置文件
丨 lib 项目的其他依赖包
丨 bogs 项目的日志输出路径

启动脚本位于bin目录下, 内容示例如下:

# 获取当前脚本所处的目录, 然后进入其上级目录, 最后pwd输出该目录, 最终的结果是/Project/KafkaConsumer
base_dir=$(cd `dirname $0`; cd ..; pwd)
# 获取Java运行程序的位置, 并指定主类
java_bin=$(which java)
main_class="org.shoufeng.elastic.ConsumerMain"

# 通过-cp、扩展CLASSPATH、指定主类的方式启动项目,
# 并通过“-D”的方式向此程序的运行时环境中设置当前项目的路径,
# 即可在程序中通过System.getProperty("base.dir")获取此路径 

nohup ${java_bin} -Dbase.dir=${base_dir} -cp ${CLASSPATH}:${base_dir}/conf:${base_dir}/lib/* ${main_class} >> /dev/null &

(2) Java程序读取变量:

实log4j的FileAppender本身支持动态设置文件路径, 如:

log4j.appender.logfile.File=${base.log}/logs/app.log

其中“${base.log}”是一个变量, 会被System Property中的base.log的值代替, 代码中的使用方式为:

public static void main(String[] args) {
 // 获取系统运行时变量中的日志文件的输出路径
 // 此变量需要在启动命令中通过-D的方式设置
 String baseDir = System.getProperty("base.dir");
 if (baseDir == null) {
  // 开发环境中使用
  baseDir = System.getProperty("user.dir");
  System.setProperty("base.dir", baseDir);
 }
 log.info("==== 系统运行路径: " + System.getProperty("base.dir") + " ====");
 // 其他处理逻辑......
}

需要注意的是, 这种方式设置的环境变量只在当前Java进程(也就是当前项目)中有效, 并不会影响到其他项目.

3.2 Web项目

如果是Web项目, 可通过修改Web容器的环境变量方式实现. 以 Tomcat 为例:

# log4j的配置文件支持服务器的vm环境变量, 格式类似${catalina.home}
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/logs_tomcat.log
log4j.appender.R.MaxFileSize=100MB 

${catalina.home}是在${tomcat_home}/bin/catalina.sh中通过-D参数设置的:

-Dcatalina.home="$CATALINA_HOME"

基于这个思路, 我们也可以向Web容器的VM参数中设置一个参数, 比如-Dmylog.home="/Project/logs", 创建日志对象时即可使用.

4 附录 - 获取当前项目、类路径的几种方式

public static void main(String[] args) {
 // 获取 class 文件的绝对路径, 定位到具体的包名, 结果如:
 // /Projects/KafkaConsumer/target/classes/org/shoufeng/consumer/
 System.out.println(KafkaConsumer.class.getResource(""));

 // 获取 class 文件的绝对路径, 如: /Projects/KafkaConsumer/target/classes/,
 // 如果在bin目录下通过java -jar等命令启动时, 结果就是 /Projects/KafkaConsumer/bin/
 System.out.println(ClassLoader.getSystemResource(""));
 System.out.println(KafkaConsumer.class.getResource("/"));
 System.out.println(KafkaConsumer.class.getClassLoader().getResource(""));
 System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
 // 说明: 上述4种用法的返回结果类型都是URL, 其toString()返回的内容以"file:"开头, 可通过“.toString().substring(5)”去除
 // 推荐: 使用“.getPath()”就可以直接获取到路径

 // 获取工程的绝对路径, 如: /Projects/KafkaConsumer,
 // 若在bin中通过java -jar等命令启动, 路径就变成了: /Projects/KafkaConsumer/bin
 System.out.println(System.getProperty("user.dir"));
}

补充知识:在web中使用log4j时,配置日志文件的存放位置

废话不多说,直接上代码。

log4j.properties配置如下

log4j.rootLogger = info,out1,out2
log4j.appender.out1=org.apache.log4j.FileAppender
log4j.appender.out1.File=test.log

log4j.appender.out1.layout=org.apache.log4j.PatternLayout
log4j.appender.out1.layout.ConversionPattern=%d %-5p - %m at %l%n

log4j.appender.out2=org.apache.log4j.ConsoleAppender
log4j.appender.out2.layout=org.apache.log4j.PatternLayout
log4j.appender.out2.layout.ConversionPattern=%d %-5p - %m at %l%n

问题一:这个test.log文件会存放在哪呢?

经测试发现,test.log这个相对路径相对的是user.dir系统参数的值。

假如我的tomcat的安装路径为D:\apache-tomcat-6.0.16,则user.dir=D:\apache-tomcat-6.0.16\bin,当不确定时,我们可以用System.getProperties()将所有的系统参数在jsp中打印出来。

问题二:

如果我们将test.log改为绝对路径/test.log,这个test.log文件又会存放在哪呢?

经测试发现,/test.log这个绝对路径的根路径是user.dir系统参数的根路径,即test.log会存放在D:\test.log。

补充:

我们在log4j.properties文件中还可以通过${系统参数}的方式来指明日志文件存放路径。

log4j.appender.out1.File=${user.dir}/logs/test.log

以上这篇Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springboot使用Logback把日志输出到控制台或输出到文件

    一:日志: 1.配置日志级别 日志记录器(Logger)的行为是分等级的.如下表所示: 分为:OFF.FATAL.ERROR.WARN.INFO.DEBUG.ALL 默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别 设置日志级别 logging.level.root=WARN 这种方式只能将日志打印在控制台上 二.Logback日志 spring boot内部使用Logback作为日志实现的框架. Logback和log4j非常相似,如果你对l

  • 详解slf4j+logback在java工程中的配置

    本文主要介绍一下slf4j+logback在java工程中的配置,面向的读者主要是已经对slf4j+logback有一定了解的同学,但是在文章开头也做了一些知识铺垫,下面咱们进入正题. 在介绍slf4j+logback配置之前,首先对日志组件logback进行介绍. (一)日志组件logback的介绍及配置使用方法 一.logback的介绍     Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classi

  • Spring Boot 日志配置方法(超详细)

    默认日志 Logback : 默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台.在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了. 从上图可以看到,日志输出内容元素具体如下: 时间日期:精确到毫秒 日志级别:ERROR, WARN, INFO, DEBUG or TRACE 进程ID 分隔符:- 标识实际日志的开始 线程名:方括号括起来(可能会截断控制台输出) Logger名:通常使用源代码的类名 日志内容 添加日志依赖 假如mave

  • Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)

    1 日志路径带来的痛点 Java 项目中少不了要和log4j等日志框架打交道, 开发环境和生产环境下日志文件的输出路径总是不一致, 设置为绝对路径的方式缺少了灵活性, 每次变更项目路径都要修改文件, 目前想到的最佳实现方式是: 根据项目位置自动加载并配置文件路径. 本文借鉴 Tomcat 的配置方式 "${catalina.home}/logs/catalina.out", 通过相对路径的方式设置日志的输出路径, 有其他解决方案的小伙伴, 请直接评论区交流哦

  • 自定义log4j日志文件命名规则说明

    目录 自定义log4j日志文件命名规则 根据log4j的API定义自己的FileAppender 对应的log4j.properties的配置文件如下 输出的日志文件命名如下 log4j自定义生成文件的名称 log4j.properties MyRollingFileAppender.java 自定义log4j日志文件命名规则 项目中的日志需要采用一致的命名规范和文件规范,命名规则为:项目模块标识_index_日期时间_日志级别.log,且每个级别日志文件放在单独的文件夹,且每个文件夹下日志的数

  • Log4j 日志文件Linux/Mac/Windows通用存放位置设置方法

    log4j1/log4j2中category的配置以及log的输出位置(windows和linux通用的log输出位置) 一.场景和需求 假设我现在有3个独立的用project(暂时用maven关联起来,当然也可以不用maven),一个是提供公共服务的infrastructure,一个是提供存储的persister,一个是提供搜索的searcher,其中提供基础服务的所有的类,例如DateUtils,HttpUtils等工具类都位于目录com.chuanliu.platform.activity

  • SSM项目中配置LOG4J日志的方法

    本文介绍了SSM项目中配置LOG4J日志的方法,分享给大家,具体如下: 在pom文件中添加依赖 . <!--Log4j2配置--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.1</version> </dependency> <

  • java配置context.xml文件的方法图解

    修改context.xml文件 自从学习了servlet后,每次修改里面的内容后,想要访问都要重启服务器,这样感觉很麻烦的,所以今天就教大家一个方法,只需要一行代码就解决"无需重新启动服务器". 请看下面的图示: 在第19行代码处<Context>里面写上reloadable="true",然后进行保存.    reloadable="true"意思是重新加载(自动刷新) 这样就可以实现无论修改什么都不需要重新启动服务器,就可以直接访

  • java使用FFmpeg合成视频和音频并获取视频中的音频等操作(实例代码详解)

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序. ffmpeg命令参数如下: 通用选项 -L license -h 帮助 -fromats 显示可用的格式,编解码的,协议的... -f fmt 强迫采用格式fmt -I filename 输入文件 -y 覆盖输出文件 -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持 -title

  • java自定义日志输出文件(log4j日志文件输出多个自定义日志文件)

    log4j输出多个自定义日志文件 如果在实际应用中需要输出独立的日志文件,怎样才能把所需的内容从原有日志中分离,形成单独的日志文件呢? 先看一个常见的log4j.properties文件,它是在控制台和test.log文件中记录日志: 复制代码 代码如下: log4j.rootLogger=DEBUG, stdout, logfile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layo

  • Java中 log4j日志级别配置详解

    1.1 前言 说出来真是丢脸,最近被公司派到客户公司面试外包开发岗位,本来准备了什么redis.rabbitMQ.SSM框架的相关面试题以及自己做过的一些项目回顾,信心满满地去面试,结果别人一上来就问到了最近项目使用的日志系统是什么?日志级别是怎么配置的?当时我都蒙X了,平时都是项目经理搭的,我自己也是随便上网一搜往配置文件一黏贴就OK了.我就这么说完后面试官深深定了我一眼,当时我的内心羞愧到...... 1.2 闲话少说,讲讲日志的发展故事(如果已经了解的可以跳过,直接看1.3日志配置) 要想

  • 详解Log4j 日志文件存放位置设置

    以DailyRollingFileAppender 为例:假设每天一个日志文件 有以下设置: log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender log4j.appender.A1.File=app.log log4j.appender.A1.DatePattern='.'yyyy-MM-dd log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.append

  • Java实时监控日志文件并输出的方法详解

    前言 最近有一个银行数据漂白系统,要求操作人员在页面调用远端Linux服务器的shell,并将shell输出的信息保存到一个日志文件,前台页面要实时显示日志文件的内容.这个问题难点在于如何判断哪些数据是新增加的,通过查看JDK 的帮助文档, java.io.RandomAccessFile可以解决这个问题.为了模拟这个问题,编写LogSvr和 LogView类,LogSvr不断向mock.log日志文件写数据,而 LogView则实时输出日志变化部分的数据. 代码1:日志产生类 package

随机推荐