Maven:如何使用不同的属性值多次过滤相同的资源?

我们的项目使用Log4J,通过log4j.properties文件配置。 我们有多个生产服务器,可以记录到不同的日志文件,以便区分日志。 所以节点1的log4j.properties如下所示:

... log4j.appender.Application.File=D:/logs/application_1.log ... log4j.appender.tx_info.File=D:/logs/tx_info_1.log ... 

而节点2的log4j.properties看起来像

 ... log4j.appender.Application.File=D:/logs/application_2.log ... log4j.appender.tx_info.File=D:/logs/tx_info_2.log ... 

我们已经使用Maven配置文件生成我们的服务器配置。 到目前为止,它包含几个不同的log4j.properties文件,这些文件仅在日志文件名中有所不同,如上所示。 我想使用像这样的资源模板文件使用Maven生成这些文件:

 ... log4j.appender.Application.File=${log.location}/application${log.file.postfix}.log ... log4j.appender.tx_info.File=${log.location}/tx_info${log.file.postfix}.log ... 

使用不同的${log.file.postfix}值可以轻松地多次运行Maven,以便每次都生成一个不同的日志属性文件。 但是,我想要为一个版本中的每个服务器生成一个不同的属性文件(名称/路径不同) 。 我相信这可以做到,例如通过antrun插件,但我不熟悉。 实现这一目标的最简单方法是什么?

(…)我很确定这可以做到,例如通过antrun插件,但我不熟悉。 实现这一目标的最简单方法是什么?

您确实可以使用resources:copy-resources和POM中的几个 (请注意resources:copy-resources不允许更改目标文件的名称)。

假设您有以下结构:

 $ tree . . ├── pom.xml └── src ├── main │  ├── filters │  │  ├── filter-node1.properties │  │  └── filter-node2.properties │  ├── java │  └── resources │  ├── log4j.properties │  └── another.xml └── test └── java 

log4j.properties使用占位符且filter-nodeN.properties文件包含值的位置。 例如:

 # filter-node1.properties log.location=D:/logs log.file.postfix=_1 

然后,在pom.xml ,配置资源插件并为每个节点定义一个 ,以使用特定的输出目录和要使用的特定filter调用copy-resources

  ...     src/main/resources true   **/log4j.properties      maven-resources-plugin 2.4.3   copy-resources-node1 process-resources  copy-resources   ${basedir}/target/node1   src/main/resources true  **/log4j.properties     src/main/filters/filter-node1.properties     copy-resources-node2 process-resources  copy-resources   ${basedir}/target/node2   src/main/resources true  **/log4j.properties     src/main/filters/filter-node2.properties         

运行mvn process-resources会产生以下结果:

 $ tree . . ├── pom.xml ├── src │  ├── main │  │  ├── filters │  │  │  ├── filter-node1.properties │  │  │  └── filter-node2.properties │  │  ├── java │  │  └── resources │  │  ├── log4j.properties │  │  └── another.xml │  └── test │  └── java └── target ├── classes │  └── another.xml ├── node1 │  └── log4j.properties └── node2 └── log4j.properties 

使用每个log4j.properties的适当值。

 $ cat target/node1/log4j.properties log4j.appender.Application.File=D:/logs/application_1.log log4j.appender.tx_info.File=D:/logs/tx_info_1.log 

这种方法有用,但是很冗长,如果你有相当数量的节点,这可能是一个问题。


我尝试使用Maven AntRun插件编写更简洁和可维护的东西,但是我无法从ant-contrib获得for任务在Maven下工作(原因不明, for task无法识别)我放弃了

这是使用Maven AntRun插件的替代方案。 没有什么复杂的,没有循环,我只是将源文件复制到另一个位置,动态更改其名称并过滤内容:

   maven-antrun-plugin 1.3   copy-resources-all-nodes process-resources                  run     

请注意,Ant默认使用@作为令牌的分隔符(无法使其使用maven样式分隔符),因此log4j.properties变为:

 log4j.appender.Application.File=@log.location@/application@log.file.postfix@.log log4j.appender.tx_info.File=@log.location@/tx_info@log.file.postfix@.log 

但是,由于这些值似乎是特定于节点的, 您是否考虑使用系统属性 (可以放在启动脚本中)? 这是我已经完成的(使用log4j.xml ),它运行良好,它将大大简化事情。

虽然这有点旧,但我最近遇到了这个post,并希望使用iterator-maven-plugin提出更新的解决方案。 可在此处找到概述: http : //khmarbaise.github.io/iterator-maven-plugin/

如何实现目标的一个具体示例是将迭代器插件与复制资源和filter相结合。 您甚至可以添加自定义属性文件以用作filter,以防您使用此方法具有每个节点唯一的其他属性。

  com.soebes.maven.plugins iterator-maven-plugin 0.3   configure-log-properties validate  iterator   log.file.postfix 1,2,3,4,5    maven-resources-plugin 2.7  copy-resources  ${project.build.directory}/nodes/${log.file.postfix}   src/main/resources  log4j.properties  true          

以下是您可以尝试的一些方法:

  1. 使用antrun插件和copy任务在generate-resources阶段制作资源文件的copy 。 使用antrun插件的一个例子在关于使用maven复制的这个SO问题的答案中给出。 您甚至可以使用ant的属性扩展将每个$ {log.file.postfix}扩展为一个不同的值,即文字值1,2,3等或唯一占位符,$ {log.file.postfix1},$ {当maven进行资源过滤时,最终会替换log.file.postfix2}。

  2. 使用您的版本控制系统来设置同一文件的多个副本,而不是使用antrun。 然后,您可以运行多个资源实例:copy-resources目标,每个目标都配置了不同的属性值,以及不同的目标文件名。

如果需要复制很多目标配置,可以将maven-antrun-plugin与ant macrodef一起使用。

   maven-antrun-plugin 1.3   copy-resources-all-nodes process-resources                 ...    run     

如果你真的有很多目标配置,你也可以使用ant-contrib来迭代目标配置列表。

这里有一个如何做到这一点的例子