Maven: how to filter the same resource multiple times with different property values?

后端 未结 4 716
暖寄归人
暖寄归人 2021-02-02 14:12

Our project uses Log4J, configured via log4j.properties file. We have multiple production servers, which log to different log files, so that the logs can be differentiated. So l

4条回答
  •  囚心锁ツ
    2021-02-02 15:09

    (...) I am fairly sure this can be done, e.g. via the antrun plugin, but I am not familiar with that. What is the simplest way to achieve this?

    You could indeed use resources:copy-resources and several in your POM (note that resources:copy-resources doesn't allow to change the name of the target file though).

    Let's assume you have the following structure:

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

    Where log4j.properties is using place holders and the filter-nodeN.properties files contain the values. For example:

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

    Then, in your pom.xml, configure the resources plugin and define one per node to call copy-resources with a specific output directory and a specific filter to use:

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

    Running mvn process-resources would produce the following result:

    $ 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
    

    With the appropriate values in each 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
    

    This kinda works, but is verbose and this might be a problem if you have a decent amount of nodes.


    I tried to write something more concise and maintainable using the Maven AntRun Plugin but I couldn't get the for task from ant-contrib to work under Maven (for an unknown reason, the for task isn't recognized) and I gave up.

    Here is an alternative using the Maven AntRun Plugin. Nothing complicated, no loop, I'm just copying the source file to another location, changing its name on the fly and filtering the content:

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

    Note that Ant uses @ by default as delimiters for token (couldn't get it to use maven style delimiters) so the log4j.properties became:

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

    But, since these values seem to be node specific, did you consider using system properties instead (that you could place in the startup scripts)? This is something I've already done (with a log4j.xml), it works well and it would highly simplify things.

提交回复
热议问题