Telegraf Scale 处理器插件:字段数值区间缩放与因子偏移的完整配置指南
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
processors.scale是 Telegraf 提供的数值变换类处理器插件(从 v1.27.0 开始可用),用于将指标字段的取值从一段输入区间线性映射到另一段输出区间,或者直接使用"因子 + 偏移"的方式对字段值做线性变换。本文以 plugins/processors/scale/README.md 为骨架,结合 scale.go 源码与 scale_test.go 测试用例,完整讲解两种缩放模式的数学公式、TOML 配置项、字段通配过滤、类型转换规则、启动校验与错误处理,帮助你安全地把传感器量程换算、单位归一化、量纲平移等场景落到 Telegraf 管道中。
插件定位与适用场景
scale在 Telegraf 插件体系中归属于transformation(数据变换)类别,运行于所有支持的平台上(💻 all)。作为处理器(Processor),它作用于输入插件产生指标之后、聚合器(Aggregator)处理之前,与rename、strings、converter等处理器处于同一处理阶段。
典型的应用场景包括:
- 将 0~1 的归一化读数换算为 0~100 的百分比;
- 把摄氏温度量程映射为华氏量程(或反之)式的线性换算;
- 用
factor+offset对电压、电流等原始采样值做传感器标定修正; - 在告警与可视化之前统一不同数据源的量纲。
它处理的是字段(field)级别的数值,不修改指标名(measurement)和标签(tag),且只对命中fields列表的字段生效,其余字段原样保留。
两种缩放模式的数学原理
插件在内部把两种模式统一抽象为线性变换:
result = scale * (value - shift_in) + shift_out模式一:输入区间 → 输出区间(min/max)
按照 README 给出的公式,将一个输入区间[input_minimum, input_maximum]映射到输出区间[output_minimum, output_maximum]:
result = (value - input_minimum) * (output_maximum - output_minimum) / (input_maximum - input_minimum) + output_minimum对照源码 scale.go 中的实现,插件在Init()阶段预先计算:
s.scale = (*s.OutMax - *s.OutMin) / (*s.InMax - *s.InMin) s.shiftOut = *s.OutMin s.shiftIn = *s.InMin即斜率scale = (output_maximum - output_minimum) / (input_maximum - input_minimum),随后每次处理时执行process():
return s.scale*(value-s.shiftIn) + s.shiftOut这与 README 中的数学公式完全等价,并且因为斜率和偏移在启动时一次性算好,运行时每条指标只做一次乘法和两次加减,性能开销极小。
模式二:因子 + 偏移(factor/offset)
第二种模式直接对输入值做线性标定:
result = factor * value + offset同样映射到统一的scale/shiftIn/shiftOut三参数模型:scale = factor(未指定时默认为 1.0),shiftIn = 0,shiftOut = offset(未指定时默认为 0.0)。源码见 scale.go。
[!IMPORTANT]两种模式不可混用。如果一个
scaling中既出现了input_minimum等区间参数,又出现了factor/offset,Init()会直接报错(详见下文"启动校验与错误处理")。
配置项详解
基础结构
# Scale values with a predefined range to a different output range. [[processors.scale]]与大多数 Telegraf 处理器一致,[[processors.scale]]外层可以配合全局配置选项(如alias、order、log_level、metric filtering)一起使用。
scaling 子表
插件通过scalings子表数组支持在一份配置中定义多组不同的缩放规则,每组针对不同的字段集合。每组scaling支持的参数如下:
| 参数 | 类型 | 说明 | 是否必填 |
|---|---|---|---|
input_minimum | float | 预期的最小输入值 | 区间模式下必填 |
input_maximum | float | 预期的最大输入值 | 区间模式下必填 |
output_minimum | float | 期望的最小输出值 | 区间模式下必填 |
output_maximum | float | 期望的最大输出值 | 区间模式下必填 |
factor | float | 缩放输入值的系数 | 因子模式下可只填其一 |
offset | float | 缩放后叠加的偏移量 | 因子模式下可只填其一 |
fields | []string | 应用该缩放的字段名(或通配过滤规则)列表 | 必填 |
对照 sample.conf 中的完整注释版示例:
# Scale values with a predefined range to a different output range. [[processors.scale]] ## It is possible to define multiple different scaling that can be applied ## do different sets of fields. Each scaling expects the following ## arguments: ## - input_minimum: Minimum expected input value ## - input_maximum: Maximum expected input value ## - output_minimum: Minimum desired output value ## - output_maximum: Maximum desired output value ## alternatively you can specify a scaling with factor and offset ## - factor: factor to scale the input value with ## - offset: additive offset for value after scaling ## - fields: a list of field names (or filters) to apply this scaling to ## Example: Scaling with minimum and maximum values # [[processors.scale.scaling]] # input_minimum = 0.0 # input_maximum = 1.0 # output_minimum = 0.0 # output_maximum = 100.0 # fields = ["temperature1", "temperature2"] ## Example: Scaling with factor and offset # [[processors.scale.scaling]] # factor = 10.0 # offset = -5.0 # fields = ["voltage*"]注意:scalings是数组表([[processors.scale.scaling]]),因此可以连续书写多个[[processors.scale.scaling]]块,对不同的字段组应用不同的变换。
fields 字段的通配过滤
fields支持 glob 通配模式(*、?、{}、[]、!等字符),底层由 filter/filter.go 的filter.Compile()编译为过滤匹配器。例如fields = ["voltage*"]会匹配所有以voltage开头的字段;也可以显式列出多个精确字段名,如["temperature1", "temperature2"]。
在Init()阶段插件还会扫描所有scaling中声明过的字段过滤规则,如果同一个字段名在多组缩放中重复使用,会输出一条警告日志("Filter field ... used twice in scalings"),提示规则存在歧义,见 scale.go。
字段值类型转换规则
README 明确说明:输入字段在可能的情况下会被转换为浮点值。转换由 internal/type_conversions.go 的internal.ToFloat64()完成,它支持:
- 各种整型与无符号整型(
int/int8/int16/int32/int64、uint/uint8…); float32/float64;- 字符串(
strconv.ParseFloat解析,如"0.5"); []byte与实现了fmt.Stringer的类型;- 布尔值(
true→ 1.0,false→ 0.0)。
从 scale_test.go 的测试数据可以看到,int64(0)、uint64(1)、字符串"0.5"、float32(-0.5)等异构类型都能被统一换算为浮点结果。
无法转换的字段会被忽略并保留原始值。scaleValues()在ToFloat64失败时会记录一条错误日志(Error converting ... to float)并continue,不会让该字段消失,也不会中断整条指标的后续处理,见 scale.go。因此,字符串型、结构体或其他无法解析为数字的字段会原样通过,这在混合类型的指标上非常安全。
关键行为:数值不会被裁剪(clipping)
README 用醒目的 NOTE 强调:
Neither the input nor output values are clipped to their respective ranges!
即输入值超出[input_minimum, input_maximum]不会被钳制,计算结果超出[output_minimum, output_maximum]也不会被截断,插件只做纯线性映射。
这一点在测试用例Out of range tests中得到直接验证(scale_test.go):当input_minimum=-1, input_maximum=1, output_minimum=0, output_maximum=100时,输入-2得到-50,输入2得到150,均超出了输出区间但如实输出。
这带来一个重要的使用前提:如果你需要将越界值强制收敛到目标区间内(例如归一化到 0~100 供告警阈值使用),需要自行叠加clip处理器或在消费端做边界处理;否则越界数据会以线性外推的形式继续向下游传递。
启动校验与错误处理
Scale.Init()在配置加载阶段执行一系列严格校验(scale.go),对应错误场景全部由 scale_test.go 的TestErrorCasesMinMax覆盖:
| 校验条件 | 报错信息 | 说明 |
|---|---|---|
完全未定义scalings | no valid scaling defined | 至少需要一组缩放规则 |
| 区间参数与 factor/offset 同时出现 | cannot use factor/offset and minimum/maximum at the same time | 两种模式互斥 |
| 只设置了部分 min/max 参数 | all minimum and maximum values need to be set | 区间模式的四个值必须齐全 |
| 未设置任何缩放参数 | no scaling defined | 每组scaling至少声明一种模式 |
input_minimum == input_maximum | input minimum and maximum are equal | 斜率分母为零 |
output_minimum == output_maximum | output minimum and maximum are equal | 无意义的退化区间 |
这些错误会在 Telegraf 启动(配置解析)阶段被捕获并导致启动失败,从而避免运行期出现除零或错误映射。错误信息中会附带对应的fields列表,方便快速定位是哪一组scaling配置有误。
处理流程与性能特征
Apply()按"指标 → 缩放组 → 字段"三层循环处理:
- 遍历每条指标(
Apply(in ...telegraf.Metric)); - 对每个
scaling组,取该指标的全部字段(metric.FieldList()); - 用
fieldFilter.Match(field.Key)判断字段是否命中; - 命中后经
internal.ToFloat64转浮点,再执行预计算好的线性变换process()。
由于斜率和偏移量都在Init()阶段预计算完成,运行期每条命中字段仅需一次浮点乘加运算,非常适合高频指标管道。scale属于纯函数式就地变换,不缓存状态、不依赖时间窗口,因此也可以放心地配合多实例、并行处理(parallel)等场景使用。
TestTracking(scale_test.go)还验证了插件与 Telegraf 的指标追踪(tracking metric)机制兼容:缩放处理后的指标在输出确认(Accept)后,投递回执能够正确、完整地返回,不会因字段改写而破坏消息确认链路。
综合示例:将 0~50℃ 的温度读数映射为 50~100 的评分
以 README 的 Example 为例,假设输入插件采集到temperature指标,cpu字段取值 25:
[[processors.scale.scaling]] input_minimum = 0.0 input_maximum = 50.0 output_minimum = 50.0 output_maximum = 100.0 fields = ["cpu"]按公式计算:25 → (25 - 0) * (100 - 50) / (50 - 0) + 50 = 75.0,指标从
- temperature, cpu=25变为
+ temperature, cpu=75.0这个示例同样被TestTracking复现(输入 42 → 92、99 → 149、1 → 51),说明 README 的演示与实际运行行为完全一致。
再看一个多组缩放 + 通配过滤的完整配置,同时演示两种模式共存:
[[processors.scale]] ## 把归一化读数换算为百分比 [[processors.scale.scaling]] input_minimum = 0.0 input_maximum = 1.0 output_minimum = 0.0 output_maximum = 100.0 fields = ["usage", "load*"] ## 对电压采样做传感器标定:value * 10 - 5 [[processors.scale.scaling]] factor = 10.0 offset = -5.0 fields = ["voltage*"]全局配置选项与处理器编排
scale与其他所有 Telegraf 插件一样支持 docs/includes/plugin_config.md 描述的全局与插件级配置,用于修改指标、标签、字段、创建别名以及配置插件执行顺序,完整说明见 docs/CONFIGURATION.md。
针对处理器阶段,几个常用选项包括:
alias:为插件实例命名,便于日志区分与多实例复用;order:指定处理器执行顺序(从 1 开始);未指定order时按配置文件中的出现顺序执行,且未指定order的处理器优先于指定了order的处理器;log_level:覆盖该插件的日志级别(error/warn/info/debug);- metric filtering:通过
namepass、fieldpass、tagpass等参数限定只处理部分指标,被排除的指标原样传给下游。
在编排时注意:scale属于处理器阶段,运行于输入插件之后、聚合器之前(见 docs/CONFIGURATION.md 中的 Processor Plugins 说明)。如果你的管道同时包含多个处理器,且缩放结果会影响后续处理(例如缩放后再做阈值匹配或字段重命名),请用order显式固定执行序列。
使用注意事项小结
- 区间模式四参数必须齐全,且
input_minimum != input_maximum、output_minimum != output_maximum,否则启动校验失败; - 因子模式与区间模式互斥,不可在同一组
scaling中混用; - 数值不会被裁剪:越界的输入会线性外推到输出区间之外,需要钳制请自行处理;
- 字段过滤支持 glob 通配(如
voltage*),同一字段避免在多组缩放中重复声明,否则会告警; - 无法转浮点的字段原样保留并记录错误日志,不会影响其他字段;
- 缩放在指标数据流上就地完成,结果字段值类型统一为浮点(
float64)。
参考与深入阅读
- 插件文档与配置模板:plugins/processors/scale/README.md、plugins/processors/scale/sample.conf
- 核心实现:plugins/processors/scale/scale.go
- 行为与错误场景测试:plugins/processors/scale/scale_test.go
- 字段值转浮点实现:internal/type_conversions.go
- 字段通配过滤实现:filter/filter.go
- 全局与处理器级配置选项:docs/CONFIGURATION.md
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考