Java - 自动配置log4j的日志文件路径

目录

  • 1 日志路径带来的痛点
  • 2 log4j.properties文件的配置
  • 3 彻底解决痛点
    • 3.1 单独的Java程序包 (非Java Web项目)
    • 3.2 Web项目
  • 4 附录 - 获取当前项目、类路径的几种方式

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 -jarjava -cp的方式启动;

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

(1) 启动脚本设置:

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

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

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

# 获取当前脚本的上级目录, 也就是/Project/KafkaConsumer
base_dir=$(dirname $(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)”去除

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

参考资料

log4j 产生的日志位置设置 和 catalina.home、catalina.base

版权声明

作者: 瘦风(https://healchow.com)

出处: 博客园 瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[好文要顶??] 或 [推荐??] 吧??

本文版权归博主所有, 欢迎转载, 但 [必须在文章页面明显位置标明原文链接], 否则博主保留追究相关人员法律责任的权利.

原文地址:https://www.cnblogs.com/shoufeng/p/11310086.html

时间: 2024-08-05 10:57:23

Java - 自动配置log4j的日志文件路径的相关文章

在Spring的项目中配置Log4j存放日志文件到指定目录下

在Spring中使用LOG4J为日志输出的插件已有一段日子了,但有时候发现日志文件虽然是已经在根据自己的理想存放了,但还会有些莫名其妙的项目日志文件出现tomcat内(因为项目的日志文件都以项目命名嘛,所以比较容易区分这些log).这些令我纠结的日志文件,让我在改善一下LOG4J的配置.才发现,之前用的配置方式真是弱爆了. 1.先说自己比较理想的存放日志路径. 我比较喜欢把日志文件放在项目的WEB-INF下,然后当然有个文件夹叫logs.logs相信很多人都会存在在这样的目录下,但放在WEB-I

Log4j 2X 日志文件路径问题

关于路径问题网上说啥的都有,但是也不能说人家错,只能说不适合你这个. 一开始,我用的   ${webapp.root} <RollingFile name="rollingFileSys" fileName="${webapp.root}/WEB-INF/logs/sys.log" append="true" filePattern="${webapp.root}/WEB-INF/logs/sys/$${date:yyyy-MM-

log4j的日志文件保存到项目发布目录,log4j文件每天分割按日期命名

自己设置目录,也就是在项目启动时通过System.setProperty来设置,实现ServletContextListener来解决: public class log4jlistener implements ServletContextListener { public static final String log4jdirkey = "log4jdir"; public void contextDestroyed(ServletContextEvent servletcont

log4j.properties 日志文件的详细配置说明

一.在一个web 项目中,使用tomcat 启动通常会在控制台输出出现一个警告信息: 通常为未添加 log4j.properties文件的原因. 二.下面以一个普通的maven项目为例说明一下 1. 在maven项目的配置文件pom.xml中已经有日志文件的配置选项,如果需要使用,记得配置进去. 1 <!-- 日志文件 --> 2 <dependency> 3 <groupId>org.slf4j</groupId> 4 <artifactId>

Log4j写日志文件使用详解

Log4j输出到控制台成功,写入文件失败 - Log4j和commons log的整合 一.今天在使用commongs-logging.jar和log4j.properties来输出系统日志的时候,发现日志能够成功的输出到控制台,但是去不能写到目的文件中,具体的步骤和原因如下: 1. 只在项目中引入commons-logging.jar commons-logging.jar 使用 Log logger = LogFactory.getLogger(XXX.class), 如果有log4j.pr

修改数据文件和日志文件路径

环境及需求操作系统:Microsoft Windows Server 2008 R2 Enterprise数据库:Microsoft SQL Server 2008 R2 (SP3)服务器增加Fusion-io存储,需将数据库文件迁移到Fusion-io迁移文件必定涉及数据库服务的重启,给定维护时间1小时.服务器上只安装一个数据库实例,实例下面有33个用户数据库(一个小游戏对应一个库),部分数据库有多个数据文件.考虑到要迁移的数据文件个数有107个,最佳方式是使用: ALTER DATABASE

Java异常,配置log4j

注意: 1.Java中的所有异常都是由Throwable类的子类生成的对象,所有的异常类都是Throwable类的子类或子类的子类.Throwable类是Object类的直接子类,Error类和Exception类是Throwable类的两个直接子类. Error  错误类 java.lang.Error 错误类一般是指虚拟机相关的 Exception  异常类 2.java.lang.Exception类是Java中所有异常的直接或间接父类 java中异常处理是通过5个关键字实现的try,ca

MYSQL 日志文件路径错误 1067错误

场景再现: --------------------------------------------------------------------------------------------------------------------------- 第一步: 找到出错的原因.运行-->  eventvwr  可以看到是出了什么错 这个说明日志文件的路径不对! 第二步: 改动日志文件的位置: 要在配置文件中修改: windows 系统日志文件在安装目录的data文件夹中,打开my.ini

转-IE浏览器自动配置代理脚本-Proxy.PAC文件及PAC相关语法

用笔记本上网时,往返家里和单位,因为单位是用的代理上网,家里是直接连接.因此每次都要修改IE的代理设置,虽然是个小事,但是每次都要修改总是有点烦 ,于是参考GOOGLE,写了一个自动配置代理的脚本.这样无论在家和在公司,只要连上局域网就可以上网了 . function FindProxyForURL(url,host) {if((isPlainHostName(host))||shExpMatch(url,"http://127.0.0.1/*")||isInNet(host,&quo