Знаток: как отфильтровать тот же ресурс многократно с различными значениями свойств?

Наш проект использует Log4J, настроенный через log4j.properties файл. У нас есть несколько рабочих серверов, которые регистрируются к различным файлам журнала, так, чтобы журналы могли дифференцироваться. Так log4j.properties для узла 1 похож на это:

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

в то время как log4j.properties для узла 2 похож

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

Мы уже используем профили Знатока для генерации нашей конфигурации сервера. До сих пор это содержало несколько отличных 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
...

Легко выполнить Знатока многократно с различным ${log.file.postfix} значения для генерации единственного другого файла свойств журнала каждый раз. Однако то, что я хотел бы, должно генерировать отличный файл свойств (с отличающимся именем/путем) для каждого сервера в одной сборке. Я абсолютно уверен, что это может быть сделано, например, через antrun плагин, но я не знаком с этим. Что самый простой путь состоит в том, чтобы достигнуть этого?

17
задан Tunaki 31 January 2016 в 22:56
поделиться

2 ответа

(...) Я почти уверен, что это можно сделать, например через плагин antrun, но я не знаком с этим. Каков самый простой способ добиться этого?

Вы действительно можете использовать ресурсов: 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 настройте плагин ресурсов и определите один для каждого узла для вызова 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>

Запуск 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 Plugin, но мне не удалось заставить задачу for из ant-contrib работать под Maven (для неизвестного Причина в том, что задача для не распознается), и я отказался от .

Вот альтернатива с использованием подключаемого модуля 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

Но, поскольку эти значения кажутся специфичными для узла, рассматривали ли вы вместо этого использование системных свойств (что вы могли бы разместить в сценариях запуска)? Это то, что я уже делал (с log4j.xml ), он работает хорошо и сильно упростит работу.

15
ответ дан 30 November 2019 в 13:53
поделиться

Вот несколько подходов, которые вы можете попробовать:

  1. используйте плагин antrun и задачу copy для создания дубликатов вашего файла ресурсов на этапе generate-resources . Пример использования подключаемого модуля antrun приведен в ответе на этот вопрос SO о копировании с помощью maven . Вы даже можете использовать расширение свойств ant для расширения каждого $ {log.file.postfix} до отдельного значения, будь то буквальные значения, 1, 2, 3 и т. Д., Или уникальные заполнители, $ {log.file.postfix1}, $ { log.file.postfix2}, которые, наконец, заменяются, когда maven выполняет фильтрацию ресурсов.

  2. Вместо использования antrun используйте свою систему управления версиями для создания нескольких копий одного и того же файла. Затем вы можете запустить несколько экземпляров цели resources: copy-resources , для каждого из которых настроены разные значения свойств и другое имя целевого файла.

1
ответ дан 30 November 2019 в 13:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: