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
以下是您可以尝试的一些方法:
-
使用antrun插件和
copy
任务在generate-resources
阶段制作资源文件的copy
。 使用antrun插件的一个例子在关于使用maven复制的这个SO问题的答案中给出。 您甚至可以使用ant的属性扩展将每个$ {log.file.postfix}扩展为一个不同的值,即文字值1,2,3等或唯一占位符,$ {log.file.postfix1},$ {当maven进行资源过滤时,最终会替换log.file.postfix2}。 -
使用您的版本控制系统来设置同一文件的多个副本,而不是使用antrun。 然后,您可以运行多个资源实例:copy-resources目标,每个目标都配置了不同的属性值,以及不同的目标文件名。
如果需要复制很多目标配置,可以将maven-antrun-plugin与ant macrodef一起使用。
maven-antrun-plugin 1.3 copy-resources-all-nodes process-resources ... run
如果你真的有很多目标配置,你也可以使用ant-contrib来迭代目标配置列表。
这里有一个如何做到这一点的例子