作者:袁庆彬,磐基 Paas 团队
简介
Fluent Bit[1] 是一个针对 Linux、OSX、Windows 和 BSD 系列操作系统设计的高性能、轻量级日志处理器、流处理器和转发器。它专注于卓越的性能,能够高效地从多个来源收集事件,并提供简洁易用的配置接口,以满足复杂的数据处理需求。
在数据来源日益多样化的背景下,处理不同字符编码的能力变得至关重要。尤其是在 Linux 环境下,GBK
编码的中文日志可能会出现乱码,因此将这些GBK
乱码日志准确转换为UTF-8
编码,对于确保日志内容的准确检索和分析至关重要。特别是在磐基集群中,我们多次接到客户对日志转码的需求,这进一步突显了进行准确转换的必要性。
本文将介绍如何通过 Fluent Bit,利用 WebAssembly(WASM)技术实现 GBK
到 UTF-8
的复杂数据转换。
使用 Wasm 程序作为 FILTER
Fluent Bit 为了满足的灵活过滤机制的需求, 现在支持通过内置的 Wasm[2] 程序及其运行时环境编写自定义过滤器,从而扩展其功能。基于 WASM
的过滤器实现包括以下几个步骤:
(可选)编译为 AOT(Ahead Of Time)对象,优化 Wasm 执行流水线
在 Fluent Bit 的主配置文件中,配置 WASM 过滤器以加载并使用编译好的 WASM 程序,从而使其能够处理数据流。
编写一个自定义的 WASM 处理程序,该程序将由配置的 WASM 过滤器调用,以实现特定的数据处理逻辑。
Wasm 配置参数
参数名 | 描述 |
---|---|
Wasm_Path | 指定用于过滤的 WASM 程序的路径,可以是主配置文件的相对路径。 |
Event_Format | 定义与 WASM 程序交互的事件格式,可以是msgpack 或json ,默认值为json 。 |
Function_Name | 指定 WASM 程序中用于过滤的函数名称。 |
Accessible_Paths | 指定允许 WASM 程序访问的路径白名单。 |
实现 GBK 到 UTF-8 的转换
首先,需要编写一个用于将 GBK 转换为 UTF-8 的 WASM 模块,以下是一个使用 Go 语言编写的示例代码:
package main
import (
"github.com/axgle/mahonia"
"github.com/vmihailenco/msgpack/v5"
"unsafe"
)
//export ConvertGBKToUTF8
func ConvertGBKToUTF8(tag *uint8, tag_len uint, time_sec uint, time_nsec uint, record *uint8, recordLen uint) *uint8 {
brecord := unsafe.Slice(record, recordLen)
var logData map[string]interface{}
// 反序列化 MessagePack 数据
if err := msgpack.Unmarshal(brecord, &logData); err != nil {
return record
}
// 处理 "log" 字段内容
if logStr, ok := logData["log"].(string); ok {
enc := mahonia.NewDecoder("gbk")
logData["log"] = enc.ConvertString(logStr)
}
// 序列化修改后的数据为 MessagePack 格式
newBRecord, err := msgpack.Marshal(logData)
if err != nil {
return record
}
// 将 newBRecord 转换为 *uint8 返回
return (*uint8)(unsafe.Pointer(&newBRecord[0]))
}
func main() {}
在 Ubuntu 系统上安装 TinyGo[3] 并使用 TinyGo 将上述代码构建为 WASM 程序。
wget https://github.com/tinygo-org/tinygo/releases/download/v0.32.0/tinygo_0.32.0_amd64.deb
sudo dpkg -i tinygo_0.32.0_amd64.deb
tinygo build -target=wasi -o bin/ConvertGBKToUTF8.wasm main.go
配置 Fluent Bit 以加载和执行 WASM 模块,通过设置 FILTER 插件实现数据转换。
[SERVICE]
Flush 1
Daemon Off
Log_Level info
HTTP_Server Off
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name tail
Tag gbk.local
Path /tmp/test.log
[FILTER]
Name wasm
match gbk.*
Event_Format msgpack
WASM_Path /path/to/ConvertGBKToUTF8.wasm
Function_Name ConvertGBKToUTF8
accessible_paths .,/path/to/fluent-bit
[OUTPUT]
Name stdout
Match *
手动生成 GBK 数据以检验 ConvertGBKToUTF8.wasm 的转换效果。
echo 京口瓜洲一水间,钟山只隔数重山。春风又绿江南岸,明月何时照我还。| iconv -f utf8 -t gbk >> /tmp/gbk.log
从下面的截图中,可以看到 GBK 乱码日志已成功转换为 UTF-8 并采集。
结论
在配置 WASM 时,务必要将 Event_Format
设置为 msgpack
。为了实现字符转码,我们经过大量实验和验证,发现使用 json
格式时,接收到的字节在转换为 Unicode 再转换为 UTF-8 时,部分字符依然会出现乱码。通过阅读 Fluent Bit 的源代码,我们了解到 JSON 格式进行了额外的编码转换,导致无法正确查询到 Unicode 编码表,从而无法实现预期效果。
最后值得指出的是,Fluent Bit 凭借其卓越的性能和灵活性,结合WASM
技术,能够高效地应对复杂的数据处理需求。企业可以显著提升日志数据处理的灵活性,从而构建更加健壮且具有高度适应性的日志处理管道。这种组合不仅提高了系统的处理能力,还为满足多样化的数据处理需求提供了强大的支持。
Fluent Bit: http://fluentbit.io
[2]Wasm: https://webassembly.org/
[3]TinyGo: https://tinygo.org/
点击【阅读原文】到达项目网站了解更多。
文章转载自CNCF。点击这里阅读原文了解更多。
联系Linux Foundation APAC
Linux基金会是非营利性组织,是技术生态系统的重要组成部分。
Linux基金会通过提供财务和智力资源、基础设施、服务、活动以及培训来支持创建永续开源生态系统。在共享技术的创建中,Linux基金会及其项目通过共同努力形成了非凡成功的投资。请关注LFAPAC(Linux Foundation APAC)微信公众号。