17

我们的项目使用通过 log4j.properties 文件配置的 Log4J。我们有多个生产服务器,分别记录到不同的日志文件,以便区分日志。所以节点 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
...

使用不同的值多次运行 Maven${log.file.postfix}以每次生成一个不同的日志属性文件很容易。但是,我想要的是在一个 build 中为每个服务器生成一个不同的属性文件(名称/路径不同)。我相当肯定这可以做到,例如通过 antrun 插件,但我对此并不熟悉。实现这一目标的最简单方法是什么?

4

4 回答 4

16

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

您确实可以在您的 POM 中使用resources:copy-resourcesand 几个<execution>(请注意,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,配置资源插件并为<execution>每个节点定义一个以copy-resources使用特定输出目录和要使用的特定过滤器调用:

<project>
  ...
  <build>
    <resources>
      <!-- this is for "normal" resources processing -->
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering><!-- you might still want to filter them -->
        <excludes>
          <!-- we exclude the file from "normal" resource processing -->
          <exclude>**/log4j.properties</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.4.3</version>
        <executions>
          <execution>
            <id>copy-resources-node1</id>
            <phase>process-resources</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/node1</outputDirectory>
              <resources>
                <resource>
                  <directory>src/main/resources</directory>
                  <filtering>true</filtering>
                  <includes>
                    <include>**/log4j.properties</include>
                  </includes>
                </resource>
              </resources>
              <filters>
                <filter>src/main/filters/filter-node1.properties</filter>
              </filters>
            </configuration>
          </execution>
          <execution>
            <id>copy-resources-node2</id>
            <phase>process-resources</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/node2</outputDirectory>
              <resources>
                <resource>
                  <directory>src/main/resources</directory>
                  <filtering>true</filtering>
                  <includes>
                    <include>**/log4j.properties</include>
                  </includes>
                </resource>
              </resources>
              <filters>
                <filter>src/main/filters/filter-node2.properties</filter>
              </filters>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

运行 mvnprocess-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 插件编写更简洁和可维护的东西,但我无法在 Maven 下for完成任务ant-contrib(由于未知原因,for任务无法识别),我放弃了

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

  <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <id>copy-resources-all-nodes</id>
        <phase>process-resources</phase>
        <configuration>
          <tasks>
            <copy file="src/main/resources/log4j.properties" toFile="target/antrun/log4j-node1.properties">
              <filterset>
                <filter token="log.location" value="D:/logs"/>
                <filter token="log.file.postfix" value="_1"/>
              </filterset>
            </copy>
            <copy file="src/main/resources/log4j.properties" toFile="target/antrun/log4j-node2.properties">
              <filterset>
                <filter token="log.location" value="D:/logs"/>
                <filter token="log.file.postfix" value="_2"/>
              </filterset>
            </copy>
          </tasks>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

请注意,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

但是,由于这些值似乎是特定于节点的,您是否考虑改用系统属性(可以放置在启动脚本中)?这是我已经做过的事情(使用 a log4j.xml),效果很好,并且可以高度简化事情。

于 2010-07-23T05:46:11.063 回答
3

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

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

<plugin>

    <groupId>com.soebes.maven.plugins</groupId>
    <artifactId>iterator-maven-plugin</artifactId>
    <version>0.3</version>

    <executions>
        <execution>
            <id>configure-log-properties</id>
            <phase>validate</phase>
            <goals>
                <goal>iterator</goal>
            </goals>
            <configuration>
                <iteratorName>log.file.postfix</iteratorName>
                <content>1,2,3,4,5</content>
                <pluginExecutors>

                    <pluginExecutor>
                        <plugin>
                            <artifactId>maven-resources-plugin</artifactId>
                            <version>2.7</version>
                        </plugin>

                        <goal>copy-resources</goal>

                        <configuration>
                            <outputDirectory>${project.build.directory}/nodes/${log.file.postfix}</outputDirectory>

                            <resources>
                                <resource>
                                    <directory>src/main/resources</directory>
                                    <includes>
                                        <include>log4j.properties</include>
                                    </includes>
                                    <filtering>true</filtering>
                                </resource>
                            </resources>
                        </configuration>

                    </pluginExecutor>
                </pluginExecutors>
            </configuration>
        </execution>
    </executions>
</plugin>
于 2015-05-06T19:46:47.250 回答
1

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

  1. 使用 antrun 插件,以及copy在阶段复制资源文件的任务generate-resources在这个 SO question on copying with maven的答案中给出了使用 antrun 插件的示例。您甚至可以使用 ant 的属性扩展将每个 ${log.file.postfix} 扩展为不同的值,可以是文字值 1,2,3 等,也可以是唯一的占位符 ${log.file.postfix1}, ${ log.file.postfix2} 最终在 maven 进行资源过滤时被替换。

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

于 2010-07-22T12:17:42.957 回答
0

如果需要复制的目标配置很多,可以使用 maven-antrun-plugin 和 ant 宏定义。

  <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <id>copy-resources-all-nodes</id>
        <phase>process-resources</phase>
        <configuration>
          <tasks>
             <macrodef name="copyConfigFile">
                <attribute name="node"/>

                <sequential>
                   <copy file="src/main/resources/log4j.properties"
                         toFile="target/antrun/log4j-@{node}.properties">
                      <filterset>
                         <!-- put the node-specific config in property files node1.properties etc -->
                         <filtersfile file="config/@{node}.properties"/>
                      </filterset>
                   </copy>
                </sequential>
             </macrodef>

             <copyConfigFile node="node1"/>
             <copyConfigFile node="node2"/>
             <copyConfigFile node="node3"/>
             ...

          </tasks>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

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

有一个例子如何做到这一点here

于 2014-01-06T16:34:30.603 回答