上篇文章透过 docker-compose 进行 Log 传递,这次则是使用 Spring boot 环境变数进行定义。范例在github 上,这个专案主要是实现简单的 CRUD,後续有加 Log 相关的配置。
首先,主要加入以下的库。
...
<dependency>
<groupId>org.fluentd</groupId>
<artifactId>fluent-logger</artifactId>
<version>0.3.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- send to flunted -->
<dependency>
<groupId>com.sndyuk</groupId>
<artifactId>logback-more-appenders</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version>
</dependency>
在 configuration/Fluentd.java
中定义了一个关於 Fluent bit 的连线配置。
@Configuration
@ConfigurationProperties(prefix = "cch.fluentd")
@Setter
@Getter
public class Fluentd {
@Value("${cch.fluentd.host}")
private String host;
@Value("${cch.fluentd.port}")
private String port;
}
连线配置可以如在 src/main/resources/application.properties
下的配置
...
logging.config=classpath:logback-spring.xml
cch.fluentd.host=192.168.101.129 # this
cch.fluentd.port=3003 # this
在 src/main/resources
下定义一个 logback-spring.xml 它是用来配置 Log,在上一篇并没有这个。定义内容如下
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- springProperty 可当作是环境变数宣告-->
<springProperty scope="context" name="fluentHost" source="cch.fluentd.host"/>
<springProperty scope="context" name="fluentPort" source="cch.fluentd.port" defaultValue="24224" />
<springProperty scope="context" name="springAppName" source="spring.application.name" />
<springProperty scope="context" name="env" source="spring.profiles.active" defaultValue="local"/>
<!-- 建立一个 `ConsoleAppender` 的类,相似於 `System.out.print` 打印数据一样。该配置设置了日志输出的格式,这些表示方式根据已发送到记录器的讯息替换为生成的值。
-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- console 打印 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level - %logger{36} - %msg trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %n</pattern> <!-- 定义 Log 结构,可以参考 https://ithelp.ithome.com.tw/articles/10263898 -->
</encoder>
</appender>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender"> <!-- 定义 传递到 fluent bit 的连线 -->
<tag>debug</tag>
<label>normal</label>
<remoteHost>${fluentHost}</remoteHost>
<port>${fluentPort}</port>
<additionalField>
<key>env</key>
<value>${env}</value>
</additionalField>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <!-- 将日志转 Json 格式-->
<providers class="net.logstash.logback.composite.loggingevent.LoggingEventJsonProviders">
<pattern>
<pattern>
{
"timestamp": "%date{ISO8601}",
"level": "%level",
"application": "${springAppName:-}",
"trace": "%X{trace_id:-}",
"span": "%X{span_id:-}",
"trace_flags": "%X{trace_flags:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"message": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FLUENT" />
</root>
</springProfile>
<!-- 配置将日志写入档案 -->
<springProfile name="file">
<property name="logPath" value="/var/log"/>
<appender name="fileInfoLog" filePermissions="rw-r--r--" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers class="net.logstash.logback.composite.loggingevent.LoggingEventJsonProviders">
<pattern>
<pattern>
{
"timestamp": "%date{ISO8601}",
"level": "%level",
"application": "${springAppName:-}",
"trace": "%X{trace_id:-}",
"span": "%X{span_id:-}",
"trace_flags": "%X{trace_flags:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"message": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${logPath}/info.%d{dd-MM-yyyy}_%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>10MB</maxFileSize>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="fileInfoLog" />
</root>
</springProfile>
<springProfile name="prod">
<root level="ERROR">
<appender-ref ref="STDOUT" />
<appender-ref ref="FLUENT" />
</root>
</springProfile>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FLUENT" />
</root>
</configuration>
在配置上使用了 springProfile
来切分不同环境上的输出要什麽,当中 <springProfile name="file">
的范畴定义了以档案方式储存 Log,并定义其生命周期,如下
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${logPath}/info.%d{dd-MM-yyyy}_%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>10MB</maxFileSize>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
下面的配置可以说是,prod 环境,打印的 Log 是 ERROR 等级,其输出内容参照 STDOUT
(<appender name="STDOUT"...
) 和 FLUENT
(<appender name="FLUENT"...
)
<springProfile name="prod">
<root level="ERROR">
<appender-ref ref="STDOUT" />
<appender-ref ref="FLUENT" />
</root>
</springProfile>
下面是预设环境的输出
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FLUENT" />
</root>
在此范例中我们可以透过 otel-docker-compose.yml
环境变数指定我们的环境变数
SPRING_PROFILES_ACTIVE: prod # 指定我们要 DEV 还是 PROD,它会对应不同 Log 的打印和配置
CCH_FLUENTD_PORT: 3003 # 指定 Fluent bit port
CCH_FLUENTD_HOST: 192.168.101.129 # Fluent bit IP 位置
要运行的话须将 OTEL 开头相关的环境变数进行注解
至於在 Spring boot 中为不同开发环境设置不同的配置可以如下设置,它们都定义在 resources
目录下,命名规则通常是 application-${开发环境}.properties
。如果要执行的话我们可以将 SPRING_PROFILES_ACTIVE
设置为 file 或是 dev 值,就会读取相对应的 properties
档案
.
├── application-dev.properties # 针对 dev
├── application-file.properties # 针对 file
├── application-prod.properties # 针对 prod
├── application.properties # 预设
<<: [Day 04] 眼前的黑不是黑,你说的白是什麽白?(直方图均衡化)
>>: 从零开始的8-bit迷宫探险【Level 11】在 iPhone 里盖座迷宫,就。很。墙
接下来说说我觉得非常好用的两个函数 getRange 与 getDataRange 这两个函数在取得...
NAT 网路位址转换(英语:Network Address Translation,缩写:NAT)是...
今天的内容算是当初一时没考虑到的东西。 主要是Ptt一页的文章最多列出20篇,若要搜寻到20篇以前的...
Onboarding process 第一周有哪些重点 每个月定期追踪 第三个月是最危险的 ...
什麽时候知道自己已经是大叔了...从看到国民妹妹会露出姨母笑时... 或许这部分比较简单,网路上查不...