2010-07-22 15 views
17

Dự án của chúng tôi sử dụng Log4J, được định cấu hình thông qua tệp log4j.properties. Chúng tôi có nhiều máy chủ sản xuất, đăng nhập vào các tệp nhật ký khác nhau để các nhật ký có thể được phân biệt. Vì vậy, log4j.properties cho nút 1 trông như thế này:Maven: làm cách nào để lọc cùng một tài nguyên nhiều lần với các giá trị thuộc tính khác nhau?

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

trong khi log4j.properties cho nút 2 trông giống như

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

Chúng tôi đã sử dụng các cấu Maven để tạo ra cấu hình máy chủ của chúng tôi. Cho đến nay, nó chứa một số tệp log4j.properties khác biệt chỉ khác với tên tệp nhật ký như được hiển thị ở trên. Tôi muốn tạo ra những tập tin này với Maven sử dụng một nguồn tập tin mẫu như thế này:

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

Nó rất dễ dàng để chạy Maven nhiều lần với giá trị khác nhau ${log.file.postfix} để tạo ra một tập tin khác nhau sở hữu bản ghi đơn mỗi lần. Tuy nhiên, những gì tôi muốn là để tạo một tệp thuộc tính riêng biệt (với tên/đường dẫn khác nhau) cho mỗi máy chủ trong một bản dựng. Tôi khá chắc chắn điều này có thể được thực hiện, ví dụ: thông qua plugin antrun, nhưng tôi không quen với điều đó. Cách đơn giản nhất để đạt được điều này là gì?

Trả lời

1

Dưới đây là một số phương pháp mà bạn có thể thử:

  1. sử dụng plugin antrun, và nhiệm vụ copy để làm bản sao của tập tin tài nguyên của bạn trong giai đoạn generate-resources. Một ví dụ về việc sử dụng plugin antrun được đưa ra trong câu trả lời cho câu hỏi SO này trên copying with maven. Bạn thậm chí có thể sử dụng mở rộng thuộc tính của kiến ​​để mở rộng mỗi $ {log.file.postfix} thành một giá trị riêng biệt, hoặc giá trị bằng chữ, 1,2,3 v.v. hoặc trình giữ chỗ duy nhất, $ {log.file.postfix1}, $ { log.file.postfix2} mà cuối cùng được thay thế khi maven thực hiện lọc tài nguyên.

  2. Thay vì sử dụng tính năng chống vi phạm, hãy sử dụng hệ thống kiểm soát phiên bản của bạn để thiết lập nhiều bản sao của cùng một tệp. Sau đó, bạn có thể chạy nhiều phiên bản của mục tiêu resources:copy-resources, mỗi trường hợp có các giá trị thuộc tính khác nhau được định cấu hình và một tên tệp đích khác.

+0

Cảm ơn ý tưởng.Sử dụng tài nguyên: sao chép tài nguyên, nó sẽ không thể sao chép _ cùng một file_ nhiều lần với các mục tiêu khác nhau, với các thuộc tính khác nhau? Tuy nhiên, tôi không thể tìm ra cách cấu hình các thuộc tính cho các thực thi khác nhau - bạn có thể chỉ cho tôi một ví dụ cụ thể không? –

+0

Bạn có thể gọi mục tiêu sao chép tài nguyên nhiều lần trong pom của bạn, mỗi lần chỉ định cùng một mục tiêu nguồn khác nhau. Tôi không biết liệu tài nguyên sao chép có cho phép đổi tên tệp hay không nhưng nó cho phép đặt thư mục đích. Mặt trời chiếu sáng - Tôi phải đi làm trong vườn, nhưng tôi sẽ cố gắng sắp xếp thứ gì đó cụ thể với nhau sau này. – mdma

15

(...) Tôi khá chắc chắn điều này có thể được thực hiện, ví dụ: thông qua plugin antrun, nhưng tôi không quen với điều đó. Cách đơn giản nhất để đạt được điều này là gì?

Bạn thực sự có thể sử dụng resources:copy-resources và một số <execution> trong POM của bạn (lưu ý rằng resources:copy-resources không cho phép thay đổi tên của tập tin mục tiêu mặc dù).

Giả sử bạn có cấu trúc sau:

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

đâu log4j.properties đang sử dụng giữ chỗ và filter-nodeN.properties file chứa các giá trị.Ví dụ:

# filter-node1.properties 

log.location=D:/logs 
log.file.postfix=_1 

Sau đó, trong pom.xml của bạn, cấu hình các plugin nguồn lực và xác định một <execution> mỗi nút để gọi copy-resources với một thư mục đầu ra cụ thể và một bộ lọc đặc biệt để sử dụng:

<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> 

Chạy mvn process-resources sẽ tạo ra kết quả sau:

$ 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 

Với các giá trị thích hợp trong mỗi 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 

Loại này hoạt động, nhưng tiết ra và đây có thể là vấn đề nếu bạn có số lượng nút lớn.


Tôi cố gắng để viết một cái gì đó ngắn gọn hơn và duy trì sử dụng Maven AntRun Plugin nhưng tôi không thể nhận được nhiệm vụ for từ ant-contrib làm việc dưới Maven (đối với một lý do không rõ, nhiệm vụ for không được công nhận) và tôi đã từ bỏ .

Đây là giải pháp thay thế bằng Trình cắm AntRun Maven. Không có gì phức tạp, không có vòng lặp, tôi chỉ cần sao chép các tập tin nguồn đến vị trí khác, việc thay đổi tên của nó một cách nhanh chóng và lọc nội dung:

<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> 

Lưu ý rằng Ant sử dụng @ theo mặc định như delimiters mã thông báo (couldn' t nhận được nó để sử dụng delimiters phong cách maven) để trở thành log4j.properties:

[email protected]@/[email protected]@.log 
[email protected]@/[email protected]@.log 

Nhưng, vì những giá trị này dường như là nút cụ thể, cậu xem xét sử dụng thuộc tính hệ thống thay vì (tha t bạn có thể đặt trong các kịch bản khởi động)? Đây là một cái gì đó tôi đã làm (với một log4j.xml), nó hoạt động tốt và nó sẽ rất đơn giản hóa mọi thứ.

+0

Cảm ơn ví dụ đầy đủ. Nó thực sự là rất tiết - may mắn là chúng tôi chỉ có 3 nút để nó không nhận được _too_ ra khỏi tay ... btw bạn có biết cách nào để xác định chỉ là một thuộc tính cho mỗi hồ sơ thực thi thay vì một tập tin thuộc tính đầy đủ? Chúng tôi chỉ có một thuộc tính duy nhất thay đổi trên các nút, do đó, một tệp thuộc tính đầy đủ có vẻ hơi quá mức. –

+0

Sử dụng các thuộc tính hệ thống thay vì nhiều cấu hình thực thi âm thanh chắc chắn thanh lịch hơn. Tôi đoán bạn dựa vào JBoss để giải quyết các thuộc tính trong log4j.xml, phải không? Điều đó có thể không làm việc cho chúng ta ngay bây giờ, vì log4j.properties của chúng ta nằm trong một thư mục bên ngoài, không được nạp thông qua JBoss. Tuy nhiên chúng tôi có kế hoạch di chuyển cấu hình của chúng tôi theo JBoss, vì vậy điều này có thể trở thành giải pháp hoàn hảo khi chúng tôi đã di chuyển cấu hình Log4j của mình sang jboss-log4j.xml ... –

+0

@ Péter: Đáng buồn thay, không, tôi không biết cách sử dụng ' sao chép tài nguyên mà không sử dụng tệp để lọc. Dựa trên các chi tiết được đề cập, mặc dù tôi đã thêm một triển khai thực hiện antrun. Vẫn còn một số sự trùng lặp (đó là lý do tại sao tôi muốn sử dụng vòng lặp 'for' ban đầu) nhưng nó vẫn ngắn gọn hơn. Cá nhân, tôi thích cách tiếp cận antrun cho trường hợp sử dụng này. Về các thuộc tính hệ thống, có điều này là một cái gì đó lấy cảm hứng từ JBoss (mà tôi đã sử dụng thành công trên một cụm weblog lớn). Tôi nghĩ rằng nó là đáng nói đến tùy chọn này. –

0

Nếu có nhiều cấu hình đích cần được sao chép, bạn có thể sử dụng trình cắm maven-antrun cùng với macrodef kiến.

<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/[email protected]{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> 

Nếu bạn thực sự có nhiều cấu hình đích, bạn cũng có thể sử dụng ant-contrib để lặp qua danh sách cấu hình đích.

Có một ví dụ làm thế nào để làm điều này here

3

Mặc dù đây là một chút cũ, tôi tình cờ gặp thread thời gian gần đây và muốn đề xuất một giải pháp được cập nhật bằng cách sử dụng iterator-maven-plugin. Tổng quan được tìm thấy tại đây: http://khmarbaise.github.io/iterator-maven-plugin/

Ví dụ cụ thể về cách bạn có thể hoàn thành mục tiêu của mình là kết hợp plugin lặp với tài nguyên bản sao và bộ lọc được bật. Bạn thậm chí có thể thêm tệp thuộc tính tùy chỉnh để sử dụng làm bộ lọc trong trường hợp bạn có các thuộc tính khác là duy nhất cho mỗi nút với phương pháp này.

<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>