springbootlogback如何从apollo配置中⼼读取变量
⽬录
springbootlogback从apollo配置中⼼读取变量
1、在apollo配置中⼼添加
2、项⽬的l配置⽂件配置如下
3、在l配置springProperty标签
SpringBootLogback⽆法获取配置中⼼属性
如何解决
解决⽅案
springboot logback 从apollo配置中⼼读取变量
1、在apollo配置中⼼添加
logback-config.properties配置⽂件
2、项⽬的l配置⽂件配置如下
主要是abled: true这个配置
app:
id: SX-sale-app-soa
apollo:
bootstrap:
enabled: true
#将Apollo配置加载提到初始化⽇志系统之前
eagerLoad:
enabled: true
namespaces: l,logback-config
3、在l配置springProperty标签
设置好标签名称和配置中⼼变量名称的,使⽤的时候${name}引⼊该变量
<?xml version="1.0" encoding="UTF-8"?>
<!-- ⽇志级别从低到⾼分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置⽂件如果发⽣改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置⽂件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性⽣效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部⽇志信息,实时查看logback运⾏状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">
<!-- 读取apollo配置中⼼设置的变量 -->
<springProperty scope="context" name="logstash.host" source="logstash.host"></springProperty>
<springProperty scope="context" name="logstash.port" source="logstash.port"></springProperty>
<springProperty scope="context" name="log.path" source="log.path"></springProperty>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<remoteHost>${logstash.host}</remoteHost>
<port>${logstash.port}</port>
<!-- encoder必须配置,有多种可选 -->
<encoder charset="UTF-8" class="net.der.LogstashEncoder" >
<!-- "appname":"yang_test" 的作⽤是指定创建索引的名字时⽤,并且在⽣成的⽂档中会多了这个字段  -->
<customFields>{"appname":"server-user"}</customFields>
</encoder>
</appender>
这个是后启动⽇志中会报如下错误:
20:26:50,683 |-ERROR in ch.joran.spi.Interpreter@120:31 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
20:26:50,683 |-ERROR in ch.joran.spi.Interpreter@121:58 - no applicable action for [
logger], current ElementPath is [[configuration][springProfile][logger]]
20:26:50,683 |-ERROR in ch.joran.spi.Interpreter@132:42 - no applicable action for [appender-ref], current ElementPath is [[configuration][springProfile][logger][appender-ref]]
这是因为⽇志⽂件的名称是l的话,logback会在SpringCloud和apollo配置加载之前加载⽇志配置,这时⽇志⽂件中的springProfile的配置是⽆效的。所以根据官⽅⽂档说明,需要将l改为l,然后报错就没有了。
注:虽然l⽂件名启动时会报错,但是不影响实际效果,猜测是因为上边第⼆步中的配置会在后边再次加载logback⽇志,所以logback依然会产⽣效果,但是对于有代码洁癖的⼈来说,没有任何报错和异常才是最舒服的。
SpringBoot Logback⽆法获取配置中⼼属性
最近在做项⽬中,需要把项⽬中的⽇志信息通过RabbitMQ将规定格式的消息发送到消息队列中,然后ELK系统通过消息队列拿⽇志并且保存起来,在⽇志的配置⽂件(l)中我们需要加⼊RabbitMQ的配置信息,我们的RabbitMQ信息存在Nacos的配置中⼼,就出现项⽬启动⽆法获取到RabbitMQ的配置,导致出错
如何解决
问题原因
中对LogBack的描述中我们可以知道,项⽬启动时,l或者l加载早于l,所以我们在l中配置的RabbitMQ属性⽆法获取到
<property name="rabbitmq_host" source="spring.rabbitmq.host"/>
<property name="rabbitmq_vhost" source="spring.rabbitmq.virtual-host"/>
<property name="rabbitmq_username" source="spring.rabbitmq.username"/>
<property name="rabbitmq_password" source="spring.rabbitmq.password"/>
source 指定的是l 配置⽂件的key
解决⽅案
将l 或者l ⽂件⾃定义名称,并在配置中⼼中指定该⽂件,这样SpringBoot 就不会在获取配置中⼼配置之前加载⽇志配置了配置中⼼的配置
#RabbitMQ 配置
spring:
rabbitmq:
host: 127.0.0.1
virtual-host: test
username: admin
password: 123
logging:
config: l
⽇志配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- ⽇志存放路径 -->
<property name="log.path" value="./target/logs/system-service" />
<!-- 参数 -->
<property name="app_name" source="spring.application.name"/>
<property name="app_instance_id" source="rabbitmq.instance"/>
<property name="rabbitmq_host" source="spring.rabbitmq.host"/>
<property name="rabbitmq_vhost" source="spring.rabbitmq.virtual-host"/>
<property name="rabbitmq_username" source="spring.rabbitmq.username"/>
<property name="rabbitmq_password" source="spring.rabbitmq.password"/>
<!-- ⽇志输出格式 -->
<property name="log.pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%method,%line] - %msg%n" />:ss} %-5level ${springAppName:-} %thread %logger %msg%n"/>    <!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 系统⽇志输出 -->
<appender name="FIFE" class="ch.olling.RollingFileAppender">
<file>${log.path}/${app_name}.log</file>
<!-- 循环政策:基于时间创建⽇志⽂件 -->
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<!-- ⽇志⽂件名格式 -->
<fileNamePattern>${log.path}/${app_name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- ⽇志最⼤的历史 60天 -->
<maxHistory>10</maxHistory>
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<append>true</append>
<encoder>
<pattern>${log.pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- ⽇志发送到消息队列RabbitMQ,接⼊ELK -->
<appender name="RabbitMQ" class="org.springframework.amqp.rabbit.logback.AmqpAppender">
<!-- 纯⽂本,不是格式化的JSON -->
<layout>
<pattern>
{
"appName":"${app_name}",
"appInstance":"${app_instance_id}",
"date":"%d{yyyy-MM-dd HH:mm:ss.SSS}",
"thread":"[%thread]",
"level":"%-5level",
"logger":"%logger{36}",
"msg":"%msg"
}
</pattern>
</layout>
<host>${rabbitmq_host}</host>
<port>5672</port>
<username>${rabbitmq_username}</username>
<password>${rabbitmq_password}</password>
<virtualHost>${rabbitmq_vhost}</virtualHost>
<declareExchange>false</declareExchange>
<exchangeType>direct</exchangeType>
<exchangeName>logs.direct</exchangeName>
<routingKeyPattern>logback</routingKeyPattern>
<generateId>true</generateId>
<durable>false</durable>
<charset>UTF-8</charset>springcloud和springboot
<deliveryModel>NON_PERSISTENT</deliveryModel>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--系统操作⽇志-->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
<appender-ref ref="RabbitMQ" />
</root>
</configuration>
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。