Fluent Bit: 转换 GBK 日志

文摘   2024-07-24 09:48   中国香港  

作者:袁庆彬,磐基 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 的过滤器实现包括以下几个步骤:

  1. (可选)编译为 AOT(Ahead Of Time)对象,优化 Wasm 执行流水线

  2. 在 Fluent Bit 的主配置文件中,配置 WASM 过滤器以加载并使用编译好的 WASM 程序,从而使其能够处理数据流。

  3. 编写一个自定义的 WASM 处理程序,该程序将由配置的 WASM 过滤器调用,以实现特定的数据处理逻辑。

Wasm 配置参数

参数名描述
Wasm_Path指定用于过滤的 WASM 程序的路径,可以是主配置文件的相对路径。
Event_Format定义与 WASM 程序交互的事件格式,可以是msgpackjson,默认值为json
Function_Name指定 WASM 程序中用于过滤的函数名称。
Accessible_Paths指定允许 WASM 程序访问的路径白名单。

实现 GBK 到 UTF-8 的转换

  1. 首先,需要编写一个用于将 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() {}
  1. 在 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
  1. 配置 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 *
  1. 手动生成 GBK 数据以检验 ConvertGBKToUTF8.wasm 的转换效果。
echo 京口瓜洲一水间,钟山只隔数重山。春风又绿江南岸,明月何时照我还。| iconv -f utf8 -t gbk >> /tmp/gbk.log
  1. 从下面的截图中,可以看到 GBK 乱码日志已成功转换为 UTF-8 并采集。

结论

在配置 WASM 时,务必要将 Event_Format 设置为 msgpack。为了实现字符转码,我们经过大量实验和验证,发现使用 json 格式时,接收到的字节在转换为 Unicode 再转换为 UTF-8 时,部分字符依然会出现乱码。通过阅读 Fluent Bit 的源代码,我们了解到 JSON 格式进行了额外的编码转换,导致无法正确查询到 Unicode 编码表,从而无法实现预期效果。

最后值得指出的是,Fluent Bit 凭借其卓越的性能和灵活性,结合WASM技术,能够高效地应对复杂的数据处理需求。企业可以显著提升日志数据处理的灵活性,从而构建更加健壮且具有高度适应性的日志处理管道。这种组合不仅提高了系统的处理能力,还为满足多样化的数据处理需求提供了强大的支持。

参考资料
[1]

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)微信公众号。

LFAPAC
Linux基金会通过提供财务和智力资源、基础设施、服务、活动以及培训来支持创建永续开源生态系统。在共享技术的创建中,Linux基金会及其项目通过共同努力形成了非凡成功的投资。
 最新文章