ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Telegraf json_v2 解析器完全指南:用 GJSON 路径语法把任意 JSON 转换为行协议

Telegraf json_v2 解析器完全指南:用 GJSON 路径语法把任意 JSON 转换为行协议 Telegraf json_v2 解析器完全指南用 GJSON 路径语法把任意 JSON 转换为行协议【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegrafjson_v2 是 Telegraf 内置的 JSON 解析器parser它通过 GJSON 路径语法 展开结合 parser.go 源码与 testdata 中几十个可运行示例系统讲解 json_v2 的全部配置项、数组与对象的展开规则、类型转换机制以及如何在inputs.file、inputs.mqtt_consumer等插件中落地使用。读完本文你将能够为任意复杂嵌套的 JSON 数据写出精确、可复用的 json_v2 解析配置。json_v2 是什么json_v2 解析器接收合法的 JSON 输入并将其转换成行协议。它的查询语法完全基于 GJSON Path Syntax你可以先在 GJSON playground 上调试自己的路径表达式再写进配置文件。在 Telegraf 中解析器parser作用于输入插件读取到的原始字节流data_format json_v2即声明使用该解析器。其注册入口位于 parser.go 的init()函数通过parsers.Add(json_v2, ...)注册任何输入插件都可通过data_format引用。[!WARNING] 当前实现状态下官方建议在处理数组场景时优先使用 XPath 解析器 而非 json_v2。json_v2 的适用场景主要是简单的对象取值涉及大量数组展开时请评估 XPath 方案。配置总览json_v2 的配置思路是由你来描述想要的线协议形态——定义从输入 JSON 中提取哪些字段、哪些标签。配置被划分为三个子表field—— 采集单个值或同类型同名的值数组作为 line protocol 的 fieldtag—— 采集单个值或值数组作为 line protocol 的 tag值始终被当作字符串object—— 采集 JSON 对象整体支持数组与对象的任意嵌套。一个完整的最小配置骨架如下完整可运行版见各 testdata 目录中的 telegraf.conf[[inputs.file]] urls [] data_format json_v2 [[inputs.file.json_v2]] measurement_name # A string that will become the new measurement name measurement_name_path # A string with valid GJSON path syntax, will override measurement_name timestamp_path # A string with valid GJSON path syntax to a valid timestamp (single value) timestamp_format # A string with a valid timestamp format (see below for possible values) timestamp_timezone # A string with a valid timezone (see below for possible values) [[inputs.file.json_v2.tag]] path # A string with valid GJSON path syntax to a non-array/non-object value rename new name # A string with a new name for the tag key ## Setting optional to true will suppress errors if the configured Path doesnt match the JSON optional false [[inputs.file.json_v2.field]] path # A string with valid GJSON path syntax to a non-array/non-object value rename new name # A string with a new name for the tag key type int # A string specifying the type (int,uint,float,string,bool) ## Setting optional to true will suppress errors if the configured Path doesnt match the JSON optional false [[inputs.file.json_v2.object]] path # A string with valid GJSON path syntax, can include arrays and objects ## Setting optional to true will suppress errors if the configured Path doesnt match the JSON optional false ## Configuration to define what JSON keys should be used as timestamps ## timestamp_key # A JSON key (for a nested key, prepend the parent keys with underscores) to a valid timestamp timestamp_format # A string with a valid timestamp format (see below for possible values) timestamp_timezone # A string with a valid timezone (see below for possible values) ### Configuration to define what JSON keys should be included and how (field/tag) ### tags [] # List of JSON keys (for a nested key, prepend the parent keys with underscores) to be a tag instead of a field, when adding a JSON key in this list you dont have to define it in the included_keys list included_keys [] # List of JSON keys (for a nested key, prepend the parent keys with underscores) that should be only included in result excluded_keys [] # List of JSON keys (for a nested key, prepend the parent keys with underscores) that shouldnt be included in result # When a tag/field sub-table is defined, they will be the only field/tags along with any keys defined in the included_keys list. # If the resulting values arent included in the object/array returned by the root object path, it wont be included. # You can define as many tag/field sub-tables as you want. [[inputs.file.json_v2.object.tag]] path # # A string with valid GJSON path syntax, can include arrays and objects rename new name # A string with a new name for the tag key [[inputs.file.json_v2.object.field]] path # # A string with valid GJSON path syntax, can include arrays and objects rename new name # A string with a new name for the tag key type int # A string specifying the type (int,uint,float,string,bool) ### Configuration to modify the resulting line protocol ### disable_prepend_keys false (or true, just not both) [inputs.file.json_v2.object.renames] # A map of JSON keys (for a nested key, prepend the parent keys with underscores) with a new name for the tag key key new name [inputs.file.json_v2.object.fields] # A map of JSON keys (for a nested key, prepend the parent keys with underscores) with a type (int,uint,float,string,bool) key int配置结构在源码中对应 parser.go 中的三个结构体Config顶层对应[[inputs.file.json_v2]]measurement_name、measurement_name_path、timestamp_path、timestamp_format、timestamp_timezone以及Fields、Tags、JSONObjects三组子配置DataSet对应field/tag子表path、type、rename、optionalObject对应object子表path、optional、timestamp_key、renames、fields、tags、included_keys、excluded_keys、disable_prepend_keys、FieldPaths、TagPaths。值得注意顶层配置可以重复定义多个[[inputs.file.json_v2]]块即多个ConfigParse()会逐个处理每个 config最后把所有 config 产出的 metric 合并返回见 parser.go。通用选项General Optionsmeasurement_name 与 measurement_name_pathmeasurement_name可选把产出的所有 metric 的 measurement 名称固定为给定字符串。measurement_name_path可选定义一个 GJSON 查询从 JSON 输入中提取 measurement 名称。查询必须返回单个数据值否则解析器回退到默认 measurement 名称该选项优先级高于measurement_name。源码中的处理位于 parser.go先以measurement_name为默认值若配置了measurement_name_path且 GJSON 结果既不是数组也不是对象则用结果字符串覆盖。当顶层measurement_name为空时Init()会用输入插件传入的默认 metric 名通常为输入插件名如file填充见 parser.go。testdata 中的 measurement_name_int 用例专门验证了从 JSON 提取非字符串 measurement 名的行为。timestamp_path、timestamp_format、timestamp_timezonetimestamp_path可选GJSON 查询从 JSON 中提取时间戳。查询必须返回单个数据值否则默认使用当前时间。timestamp_format当定义了timestamp_path时必填。可选值unix、unix_ms、unix_us、unix_ns分别对应秒、毫秒、微秒、纳秒级 Unix 时间戳或 Go 的 reference time 格式字符串其参考时间固定为Mon Jan 2 15:04:05 MST 2006。timestamp_timezone默认UTC当定义了timestamp_path时必填。可设置为 Unix TZ 值如America/New_York、Local使用系统时区或UTC。一个完整示例来自 timestamp/telegraf.conf 与 timestamp/input.json[[inputs.file]] files [./testdata/timestamp/input.json] data_format json_v2 [[inputs.file.json_v2]] timestamp_path time timestamp_format unix_ms [[inputs.file.json_v2.object]] path measurements tags [name, units]{ time: 1555745371410, measurements: [ {name: temperature, value: 23.4, units: ℃}, {name: moisture, value: 5, units: %} ] }源码中Init()会预先通过time.LoadLocation校验timestamp_timezone并缓存到Locationparser.goparseCriticalPath则在校验timestamp_path命中非数组非对象值后强制要求timestamp_format非空并调用internal.ParseTimestamp完成转换parser.go。testdata 中的 timestamp、timestamp_ns、timestamp_rfc3339 三个用例分别覆盖了毫秒、纳秒与 RFC3339 格式测试代码在目录名以timestamp开头时还会额外校验解析出的时间戳见 parser_test.go。field 与 tag单值/数组提取field与tag代表行协议中的字段与标签。它们用于从 JSON 中任意位置收集单个值或同类型、同名的一组值若 GJSON 路径返回单个值则产生一条包含该 field/tag 的行协议若路径返回数组则数组中每个值各生成一条独立行协议数组查询使用#字符语法见 GJSON Arrays。需要特别注意的是对象object由object配置表单独处理。如果field/tag的路径返回的是一个对象它会被忽略——因为field与tag不处理数据间的关系每条配置都被当作独立的数据点处理必须在日志中提示改用object收集见 parser.go 与expandArray中的对象分支 parser.go。field与tag的核心区别是tag的值永远是字符串类型而field可以是多种类型。field 支持的行协议类型有float、int、uint、string、bool。field 配置项path必填指向非数组/非对象值的合法 GJSON 路径。rename可选重命名 field 名不设置时使用查询路径的最后一个词作为名称源码见 parser.go路径按.切分取末段并把空格替换为下划线。type可选float、int、uint、string、bool。不设置时不强制类型保留 JSON 原始类型bool、float 或 string。optional可选路径在 JSON 中不匹配时抑制报错。应谨慎使用因为它移除了路径校验的安全网。典型场景使用inputs.mqtt_consumer且预期会收到多种不同结构的 JSON 时对应 testdata 中的 optional 与 optional_objects 用例。注意源码中field配置项实际是rename见DataSet结构体 parser.goREADME 中提到的name在 TOML 配置里写作rename。tag 配置项path必填指向非数组/非对象值的合法 GJSON 路径。rename可选重命名 tag 键不设置时默认使用查询路径最后一个词。optional可选行为同field。与 object 组合时的全局语义当field/tag配置与object配置同时使用时顶层定义的field/tag表现为全局字段/标签如果object收集到的是一个值数组则这条全局 field/tag 会被加到每一条结果行协议上而不考虑它在原始 JSON 中的位置README 原文即此说明行为可在expandArray中通过mergeMetric与cartesianProduct的组合看到见 parser.go。实例fields_and_tags配置 fields_and_tags/telegraf.conf 与输入 fields_and_tags/input.json[[inputs.file]] files [./testdata/fields_and_tags/input.json] data_format json_v2 [[inputs.file.json_v2]] [[inputs.file.json_v2.tag]] path fields.status [[inputs.file.json_v2.field]] path fields.json.#.duration rename json_duration [[inputs.file.json_v2.field]] path fields.duration type int输入 JSON 中fields.json是一个包含两个元素的数组fields.json.#.duration返回[100, 60]两个值因此产生两条行协议同时顶层 tagfields.status值为 200会被附加到两条结果上全局 fieldfields.durationint 类型也同样附加。这里展示了#通配数组元素、rename重命名以及type强制类型三个核心用法。更多组合见 fields_and_tags_complex、nested_and_nonnested_tags 与 nested_tags 等目录。object从 JSON 对象收集数据object配置表用于从 JSON 对象中收集值处理对象内部键值之间的结构关系。TOML 中以双中括号数组表定义可以定义任意多个object每个对象独立产出行协议。path 与 optionalpath必填收集对象的 GJSON 路径查询。optional可选路径不匹配时抑制错误其余注意事项同前。时间戳相关键timestamp_key可选指定 JSON 中哪个键的值作为时间戳。对于嵌套键需要用下划线连接各级父键例如父键a下嵌套b下的time写作a_b_time。timestamp_format定义了timestamp_key时必填取值同前unix、unix_ms、unix_us、unix_ns或 Go reference time。timestamp_timezone默认UTC定义了timestamp_key时必填。object 级时间戳的处理位于expandArray中当result.SetName与objectConfig.TimestampKey匹配时通过internal.ParseTimestamp解析并调用result.Metric.SetTime(timestamp)见 parser.go。实例来自 object_timestamp/telegraf.conf 与 object_timestamp/input.json[[inputs.file]] files [./testdata/object_timestamp/input.json] data_format json_v2 [[inputs.file.json_v2]] measurement_name metric [[inputs.file.json_v2.object]] path events tags [id] timestamp_key time timestamp_format 2006-01-02T15:04:05Z{ events: [ {id: 100, value: 100.123, time: 2020-12-31T23:59:59Z}, {id: 101, value: 200.001, time: 2010-06-15T12:30:00Z} ] }包含与排除included_keys / excluded_keys / tagsincluded_keys可选仅将列表中的键写入行协议默认包含对象内全部数据。excluded_keys可选排除列表中的键嵌套键同样用下划线连接父键表示。tags可选把列表中的 JSON 键作为 tag 而非 field 输出。若某键的值是数组或对象其所有嵌套值都会变成 tag。源码中isIncluded会自动把tags列表并入included_keys因此加入tags列表的键无需再重复写进included_keys同时当值是数组/对象时还会检查included_keys中的条目是否为该键的子元素前缀匹配见 parser.go。isExcluded则做全等匹配parser.go。object 内的 field/tag 子表field可选数组表与顶层field表基本相同但有两点差异路径支持数组和对象它是对象表下的子表因此遵循原始 JSON 的结构关系即值的位置会体现出来。适用场景想按included_keys的方式把某个值作为 field 添加但希望使用 GJSON 路径语法定位。tag可选数组表与顶层tag表的差异同上。需要注意一旦定义了field/tag子表它们会成为对象结果中仅有的 field/tag外加included_keys列出的键。如果这些子路径的结果不在根对象路径返回的 object/array 之内该值不会出现在结果中。实现上子表路径会在processObjects中相对于根对象路径返回的 JSON 片段scopedJSON单独求值并缓存到subPathResults再通过existsInpathResults在展开数组时按索引匹配见 parser.go 与 parser.go。相关用例见 subfieldtag_in_object、subfieldtag_in_object_2 与 object_fields_with_same_path。修改产出的行协议disable_prepend_keys可选禁止把父键前缀到嵌套结果的键名上默认会前置父键如book_title。注意开启后可能出现重名互相覆盖。renames可选map将 JSON 键映射为期望的名称默认使用原键名对嵌套结果名称需包含前置的各级父键。对应源码combineObject中的重命名匹配parser.go。fields可选map将 JSON 键映射为期望类型int、string、bool、float若某键值为数组或对象其所有嵌套值都会被转换为该类型。对应 parser.go。数组与对象的展开规则json_v2 对数组与对象的高层处理原则README 原文数组数组中的每一个元素都被当作一条独立的行协议对象对象中的每一个键值对都被当作同一条行协议的一部分。在处理嵌套数组与对象时上述规则递归生效。当一个对象包含多个数组作为值时这些数组会各自展开为独立行协议其中只包含该对象中非数组的值。经典示例multiple_arrays_in_object输入 JSON来自 multiple_arrays_in_object/input.jsonbook对象包含字符串数组chapters、对象数组characters与数字数组random。配置来自 multiple_arrays_in_object/telegraf.conf[[inputs.file]] files [./testdata/multiple_arrays_in_object/input.json] data_format json_v2 [[inputs.file.json_v2]] [[inputs.file.json_v2.object]] path book tags [title] disable_prepend_keys true按 README 的简化说明期望输出为每一条都携带非数组的titletag 与authorfieldfile,titleThe\ Lord\ Of\ The\ Rings authorTolkien,chaptersA Long-expected Party file,titleThe\ Lord\ Of\ The\ Rings authorTolkien,chaptersThe Shadow of the Past file,titleThe\ Lord\ Of\ The\ Rings authorTolkien,nameBilbo,specieshobbit file,titleThe\ Lord\ Of\ The\ Rings authorTolkien,nameFrodo,specieshobbit file,titleThe\ Lord\ Of\ The\ Rings authorTolkien,random1 file,titleThe\ Lord\ Of\ The\ Rings authorTolkien,random2而 testdata 中实际的 expected.out 更复杂当对象内存在多个数组此处chapters、characters、random时它们会被展开并做笛卡尔积组合得到 2 × 2 × 2 8 条行协议。这正是 README 提示复杂示例请查看 testdata 目录的原因——展开与组合逻辑在源码中由expandArrayparser.go递归生成节点、combineObjectparser.go合并对象键值、cartesianProductparser.go完成不同数组元素的交叉组合。类型转换Types每个 field 都可以显式定义类型规则如下显式定义类型时解析器强制执行该类型尽可能把数据转换为目标类型无法转换则解析失败未定义类型时使用 JSON 中的默认类型int、float、string。可设置的类型值与转换规则README 原文intbool、float 或包含合法数字的字符串可转换为 intuintbool、float 或包含合法数字的字符串可转换为 uintstring任意数据都可格式化为字符串float包含合法数字的字符串或整数可转换为 floatbool字符串true/false大小写不敏感或整数值0/1可转换为 bool。源码中的convertTypeparser.go完整实现了这些转换字符串经strconv.ParseUint/ParseInt/ParseFloat/ParseBool转换bool 转换为 int/uint 时为 1/0float 值为 0 或 1 时转换为对应 bool转换失败均返回带字段名的明确错误。另外当目标类型为string且值是对象或数组时会直接返回其原始 JSON 片段input.Raw——这意味着可以用type string把整个对象或数组整体输出为字符串字段。相关用例见 types、string_type_objects 与 large_numbers。源码实现要点深入 parser.go可以看到几个值得了解的实现细节BOM 处理与合法性校验parseCriticalPath先用utfbom.Skip剥离 UTF-8 BOM再用gjson.Valid校验 JSON 合法性非法输入直接报错parser.go。线程安全Parser内部持有parseMutexParse()非线程安全当前实现用互斥锁串行化整条关键路径parser.go 与 parser.go。时间戳 NULL 校验timestamp_path命中 JSON 的 null 值时会返回明确错误the timestamp path ... returned NULLparser.go。null 值处理expandArray对值为null的 JSON 值直接忽略不产生字段parser.go对应 testdata 中的 null 用例。默认标签解析器实现了SetDefaultTagsparseCriticalPath末尾会把DefaultTags追加到所有结果上parser.go。配置校验空配置在Init()直接报no configuration provided顶层timestamp_timezone无效时按 config 序号报错parser.go。测试与 testdata 目录parser_test.go 中的TestMultipleConfigs是核心测试它遍历 testdata 下的所有子目录读取每个目录的telegraf.conf、输入 JSON 与expected.out或expected.err加载配置、运行inputs.file采集并与期望行协议比对目录名以timestamp开头的用例还会额外校验时间戳精度忽略毫秒级舍入差异。这意味着 testdata 中每个目录都是一份可复现的端到端示例非常适合作为学习 json_v2 用法的活教材基础 field/tagfields_and_tags、fields_and_tags_complex对象与嵌套object、object_multiple、complex_nesting、nested_objects_optional时间戳timestamp、timestamp_ns、timestamp_rfc3339、multiple_timestamps错误与容错wrong_path含期望报错expected.err、optional、optional_objects特殊场景measurement_name_int、null、large_numbers、multiple_json_input多份 JSON 输入、benchmark。使用建议与注意事项从 GJSON 语法入手json_v2 的一切能力都建立在 GJSON 路径之上建议先在 GJSON playground 验证路径表达式如#数组通配、#(namex)#过滤等再写入配置。顶层 field/tag 是全局的与 object 配合时它们会附加到每条行协议上且不体现原始 JSON 位置关系需要按结构定位时使用 object 下的field/tag子表。optional是一把双刃剑它能容忍多结构 JSON如 MQTT 消息流但也会吞掉路径书写错误建议仅在确实需要时开启。嵌套键命名约定对象内的timestamp_key、included_keys、excluded_keys、renames、fields、tags等涉及嵌套键时统一用下划线连接父键。数组场景优先评估 XPath当前官方警告指出涉及数组时应避免使用 json_v2 而优先考虑 XPath 解析器请结合你的数据形态选择解析器。【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表