首页 > 解决方案 > 如何在 Spring Boot 中将父项目的 gradle 属性传递给 logback.xml?

问题描述

我有这个项目结构:

- parent-project
  - build.gradle
  - gradle.properties
  - child-project
    - build.gradle
    - src
      - main
        - java
        - resources
          - application.properties
          - logback.xml

这是父 build.gradle:

allprojects {
    apply plugin: 'java'
    apply plugin: 'groovy'
    apply plugin: 'maven'

    group = 'com.test'

    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11

    repositories {
        mavenLocal()
        maven {
            url nexusRepo
            credentials {
                username = nexusUsername
                password = nexusPassword
            }
        }
        mavenCentral()
        jcenter()
    }
    
    uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: nexusRepo) {
                    authentication(userName: nexusUsername, password: nexusPassword)
                }
            }
        }
    }
}

uploadArchives.enabled = false

我的父项目的 gradle.properties 包含以下内容:

version=0.1.0-SNAPSHOT

这是子项目 build.gradle:

plugins {
    id 'org.springframework.boot' version '2.3.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
    id 'groovy'
    id 'war'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

dependencies {
    //spring boot related dependencies
    ...
    implementation "com.xm.logback:jLogbackGelfAppender:1.1.0"
    implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
    implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
    implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3'
    implementation group: 'net.logstash.logback', name: 'logstash-logback-encoder', version: '6.3'
    ...
    //testing related dependencies
}

这是子项目 application.properties:

prop.testserver.computer-name=${COMPUTERNAME}
...

# graylog properties
graylogHost=host.com
graylogPort=555
graylogSourceId=app_id_dev

我发布 prop.testserver.computer-name 属性的原因是因为我尝试使用 gradle resourceProcess 并收到有关此属性的错误。

这是我的 logback.xml:

<!DOCTYPE configuration>

<configuration>
  <contextName>${graylogSourceId}</contextName>
  <jmxConfigurator/>

  <springProperty scope="context" name="graylogHost" source="graylogHost"/>
  <springProperty scope="context" name="graylogPort" source="graylogPort"/>
  <springProperty scope="context" name="graylogSourceId" source="graylogSourceId"/>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
  </appender>

  <appender name="GELF" class="com.xm.logback.GelfAppender">
    <server>${graylogHost}</server>
    <port>${graylogPort}</port>
    <protocol>TCP</protocol>
    <includeSource>true</includeSource>
    <includeMDC>true</includeMDC>
    <additionalFields>
      application=${graylogSourceId}
    </additionalFields>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%m</pattern>
    </layout>
  </appender>

  <logger name="com.test" level="INFO">
    <appender-ref ref="GELF"/>
  </logger>

  <root level="INFO">
    <appender-ref ref="CONSOLE"/>
  </root>

</configuration>

我需要在 in logback 中添加一个 application_version,但我无法通过该过程尝试不同的版本。

首先我尝试使用这个选项

然后我补充说:

processResources {
    filesMatching('application.properties') {
        expand(project.properties)
    }
}

到子项目 build.gradle 我得到了这个错误:

Groovy 模板扩展缺少属性 (COMPUTERNAME)。定义的键 [parent,classLoaderScope,configurations,plugins,objects,logger,rootDir,projectRegistry,path,testResultsDirName,targetCompatibility,java,normalization,bootJar,childProjects,jar,state,processResources,serviceRegistryFactory,tasks,ext,projectDir,dependencyLocking,projectEvaluationBroadcaster ,dependencyManagement,projectPath,模块,inheritedScope,nexusBuilderUsername,版本,脚本,依赖项,processTestResources,webAppDir,扩展,modelRegistry,安装,projectEvaluator,nexusBuilderUserPassword,projectConfigurator,archivesBaseName,日志,configurationActions,sourceCompatibility,状态,子项目,组件,displayName,bootWar , nexusDeployerUsername, parentIdentifier, testClasses, antBuilderFactory, out,

我需要帮助将应用程序版本从父 gradle.properties 参数化地传递给子项目 logback.xml。请帮忙,提前谢谢。

标签: javaspringspring-bootgradle

解决方案


您当然可以在构建期间对您的属性文件执行搜索/替换。在您的情况下,它失败了,因为 Gradle 正在尝试扩展${COMPUTERNAME}您的 application.properties 文件中的引用。您可以通过使用filter而不是来解决它expand,或者通过定义COMPUTERNAME为具有值“${COMPUTERNAME}”的 Gradle 属性(本质上将值替换为自身)。但是,为了在您的 logback 配置中包含应用程序版本,有一个(恕我直言)更优雅的解决方案。

Spring Boot 具有将构建信息作为属性文件包含在应用程序中的功能。在 Gradle 中,您可以通过以下方式启用它:

springBoot {
    buildInfo()
}

该文件将在运行时类路径下的META-INF/build-info.properties. 然后,您可以将其作为属性源包含在 Logback 中:

<configuration>
  <property resource="META-INF/build-info.properties" />
</configuration>

现在可以像您对 Spring 属性所做的那样引用文件中的属性。尝试${build.version}获取版本。

您还可以让 Spring Boot 在启动信息消息中打印出版本。但是在这里你必须将它添加到 MANIFEST.MF 文件中,例如通过:

bootJar {
  manifest {
    attributes(
      "Implementation-Title": project.name,
      "Implementation-Version": archiveVersion
    )
  }
}

(请注意,只有在您运行实际的 bootJar 文件时才会打印它 -bootRun在 Gradle 中运行任务不会这样做。)


推荐阅读