OpenShift 預設的 Container Logs Aggregator 是 EFK:
- Elasticsearch - Store, Search, and Analyze
- Fluentd - Log Collector, Processor, and Aggregator
- Kibana - Explore, Visualize, and Share
Fluent Bit 跟 Fluentd 都是 Treasure Data 的產品, 而 Fluent Bit 像是一個輕量級的 Fluentd, 專門處理 Log Collector 及 Processor, 而有較少的 Log Aggregator 功能
跟 Fluentd 相比效能更好, 不論 CPU 跟記憶體的使用率 Fluent Bit 都有更好的表現, 因此在公司轉換 OpenShfit 之前, 我們將使用 Fluent Bit 來取代 Logstach 來收集公司微服務中的 Log
延伸閱讀: Fluent-bit rocks
以 Spring Boot App 為範例, 來介紹要怎麼配置成 JSON logging
我們建議使用 logstash/logstash-logback-encoder 來做輸出 JSON 的 encoder, 因此在 pom.xml
中請加上:
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder.version}</version>
</dependency>
準備一個 Profile 名稱, 如 jsonout
, 只有在開啟該 profile 才會啟動
# application-jsonout.yaml
logging:
config: classpath:logback-spring-jsonout.xml
在 logback-spring-jsonout.xml
中, 我們先加上以下 JSON appender, 並且設定 app_name
來自於 properties 中的 spring.application.name
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender class="ch.qos.logback.core.ConsoleAppender" name="jsonout">
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<mdc/>
<timestamp>
<timeZone>Asia/Taipei</timeZone>
</timestamp>
<logLevel/>
<threadName/>
<loggerName>
<fieldName>class_name</fieldName>
</loggerName>
<message/>
<pattern>
<pattern>
{
<!-- 以下加入客製的額外資訊, 如 app_name, app_version...等
而 app_name 在非 kubernetes 環境是很有用的, 但在 kubernetes 環境中可以用 container_name 取代 -->
"app_name": "${appName:-}",
"pid": "${PID:-}"
}
</pattern>
</pattern>
<stackTrace>
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<maxDepthPerThrowable>30</maxDepthPerThrowable>
<!-- 最多帶 10k 的 stack trace, 超過應該也沒用了 -->
<maxLength>10240</maxLength>
<shortenedClassNameLength>20</shortenedClassNameLength>
<!-- 將 root cause 擺最前面, 避免超過 10k 被 trim 掉 -->
<rootCauseFirst>true</rootCauseFirst>
</throwableConverter>
</stackTrace>
</providers>
</encoder>
</appender>
<root level="...">
<appender-ref ref="jsonout" />
</root>
<logger name="..." level="debug"/>
延伸閱讀: Providers 的配置說明