Externalise CONFIGs and LOGBACK outside of the Code

Viewed 38

I have Spring Boot App in Gradle with Liquibase changesets.

This code is multi module app with about four modules in hexagonal architecture.

enter image description here

and the resources folder structure looks like this for doctors-data-deploy module:

enter image description here

My Issue is I want to put configs and logback files outside of the code, how can I externalise these files from code.

I want to run the code in 2 ways, as follows:

  1. And I want to run my code as Jar file and want to pass these configs and logback files while running the jar e.g. java -Dspring.profiles.active=local -jar doctors-0.1.0-SNAPSHOT.jar -Dlogback-config-file=logback-spring.xml -Dother-config-file=application.yml

    Not Sure what will be the exact syntax for this?

  2. If I externalise both the config and logback files, how could I pass these property in my coode If I run the spring boot app as it is by clicking on the run button in intelliJ.

Below is my application yml file

server:
  tomcat:
    connectionTimeout: 300000
management:
  endpoint:
    mappings:
      enabled: true
spring:
  liquibase:
    change-log: classpath:/db/changelog/db.changelog-master.xml
  datasource:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    hikari:
      minimum-idle: 5
      maximumPoolSize: 20
      idleTimeout: 30000
      maxLifetime: 2000000
      connectionTimeout: 30000
      poolName: data-pool
  jpa:
    hibernate:
      use-new-id-generator-mappings: false
      ddl-auto: none
    database-platform: org.hibernate.dialect.Oracle12cDialect
  quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: never
    properties:
      org:
        quartz:
          scheduler:
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
            useProperties: false
            misfireThreshold: 60000
            clusterCheckinInterval: 5000
            isClustered: true
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

Below is my logback-spring.xml file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>

    <springProperty scope="context" name="app_name" source="spring.application.name"/>
    <springProperty scope="context" name="environment" source="param_env" defaultValue="default_env"/>
    <springProperty scope="context" name="tenant" source="param_tenant" defaultValue="default_tenant"/>

    <property name="GENERIC_PATTERN"
              value="[%date{ISO8601}] [%p] [%t] [%X{traceId:-}] [%X{orderId:-}] [%X{batchJobId:-}] [%X{username:-}] [%X{functional-context}] [%c{2}] %4L | %m%n"/>
    <property name="CONSOLE_LOG_PATTERN" value="$GENERIC_PATTERN"/>
    <property name="CHARSET" value="UTF-8"/>

    <property name="LOG_DIR"
              value="logs/${envname:-${environment}}/${param_dtlogname:-${app_name}}"/>

    <logger name="org.springframework" level="INFO"/>
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.dt" level="INFO"/>
    <logger name="com.dt" level="INFO"/>

    <logger name="org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"
            level="INFO"/>

    <logger name="org.springframework.security" level="INFO"/>
    <logger name="org.hibernate" level="INFO"/>

    <!-- Auto configuration report-->
    <logger name="org.springframework.boot.autoconfigure" level="DEBUG"/>
    <logger name="org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener"
            level="TRACE"/>

    <springProfile name="local,component-test,component-test-security,scheduler-test">

        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <charset>${CHARSET}</charset>
                <pattern>${GENERIC_PATTERN}</pattern>
            </encoder>
        </appender>

        <logger name="zuul.web.request.logger" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE"/>
        </logger>

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

    </springProfile>


        <appender name="FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

            <file>${LOG_DIR}/${param_dtlogname}-${HOSTNAME}.log</file>

            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!-- daily rollover -->
                <fileNamePattern>
                    ${LOG_DIR}/${param_dtlogname}-${HOSTNAME}.%d{yyyy-MM-dd}.%i.log
                </fileNamePattern>
                <maxFileSize>1GB</maxFileSize>
                <totalSizeCap>10GB</totalSizeCap>
                <!-- keep 30 days worth of history -->
                <maxHistory>30</maxHistory>
            </rollingPolicy>

            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <mdc/>
                    <pattern>
                        <omitEmptyFields>true</omitEmptyFields>
                        <pattern>
                            {
                            "app_name": "${app_name}",
                            "HOSTNAME":"${HOSTNAME}",
                            "environment":"${environment}"
                            }
                        </pattern>
                    </pattern>
                    <logLevel/>
                    <timestamp/>
                    <threadName/>
                    <logstashMarkers/>
                    <tags/>
                    <arguments/>
                    <version/>
                    <stackTrace/>
                    <loggerName/>
                    <threadName/>
                    <message/>
                </providers>
            </encoder>
        </appender>

        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <charset>${CHARSET}</charset>
                <pattern>${GENERIC_PATTERN}</pattern>
            </encoder>
        </appender>

        <appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LogstashEncoder">
                <fieldNames>
                    <timestamp>timestamp</timestamp>
                    <message>logdata</message>
                    <version>[ignore]</version>
                    <levelValue>[ignore]</levelValue>
                </fieldNames>
                <timeZone>UTC</timeZone>
            </encoder>
        </appender>

        <appender name="API_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

            <file>${LOG_DIR}/api-${param_dtlogname}-${HOSTNAME}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!-- daily rollover -->
                <fileNamePattern>
                    ${LOG_DIR}/api-${param_dtlogname}-${HOSTNAME}.%d{yyyy-MM-dd}.%i.log
                </fileNamePattern>
                <maxFileSize>1GB</maxFileSize>
                <totalSizeCap>10GB</totalSizeCap>
                <!-- keep 30 days worth of history -->
                <maxHistory>30</maxHistory>
            </rollingPolicy>

            <encoder class="net.logstash.logback.encoder.LogstashEncoder">
                <fieldNames>
                    <timestamp>[ignore]</timestamp>
                    <message>logdata</message>
                    <version>[ignore]</version>
                    <levelValue>[ignore]</levelValue>
                </fieldNames>
                <timeZone>UTC</timeZone>
            </encoder>
        </appender>

        <appender name="APPLICATION_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">

            <file>${LOG_DIR}/startup-${param_dtlogname}-${HOSTNAME}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <!-- daily rollover -->
                <fileNamePattern>
                    ${LOG_DIR}/startup-${param_dtlogname}-${HOSTNAME}.%d{yyyy-MM-dd}.%i.log
                </fileNamePattern>
                <maxFileSize>1GB</maxFileSize>
                <totalSizeCap>10GB</totalSizeCap>
                <!-- keep 30 days worth of history -->
                <maxHistory>30</maxHistory>
            </rollingPolicy>

            <encoder class="net.logstash.logback.encoder.LogstashEncoder">
                <fieldNames>
                    <timestamp>timestamp</timestamp>
                    <message>logdata</message>
                    <version>[ignore]</version>
                    <levelValue>[ignore]</levelValue>
                </fieldNames>
                <timeZone>UTC</timeZone>
            </encoder>
        </appender>

        <logger name="api.logger" level="INFO" additivity="false">
            <appender-ref ref="API_FILE_APPENDER"/>
        </logger>

        <logger name="application.startup.logger" level="INFO" additivity="false">
            <appender-ref ref="APPLICATION_FILE_APPENDER"/>
        </logger>

        <appender name="SENTRY" class="io.sentry.logback.SentryAppender">
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>ERROR</level>
            </filter>
            <encoder>
                <pattern>${GENERIC_PATTERN}</pattern>
            </encoder>
        </appender>

        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE_APPENDER"/>
            <appender-ref ref="SENTRY"/>
        </root>
    </springProfile>
</configuration>

Can someone please help on this ?

1 Answers

In order to externalize SpringBoot configuration, the correct environment property to set is

--spring.config.location.

Please refer to the relevant documentation page for further info: https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/boot-features-external-config.html.

As for logback, you may want to try the solutions proposed here -Dlogback.configurationFile=logback.xml ignored when running Spring-Boot.

In order to pass program arguments in IntelliJ, simply go to run/debug configurations, select the desired run configuration, and place all the arguments in the 'Program Arguments' text field.

Related