Lambda 表达式
TICKscript 使用 lambda 表达式来定义数据点的转换,以及定义充当过滤器的布尔条件。Lambda 表达式包装了数学运算、布尔运算、内部函数调用或所有三者的组合。TICKscript 尝试与 InfluxQL 类似,您在 InfluxQL WHERE
子句中使用的大多数表达式都可以在 TICKscript 中用作表达式,但具有其自己的语法
- 所有字段或标签标识符都必须用双引号引起来。
- 相等性的比较运算符是
==
而不是=
。
TICKscript 中的所有 lambda 表达式都以 lambda:
关键字开头。
.where(lambda: "host" == 'server001.example.com')
在某些节点中,lambda 表达式的结果可以使用属性设置器 .as()
捕获到新字段中作为命名结果。这样,它们可以在管道中进一步的其他节点中使用。
lambda 表达式的内部函数可以是无状态的或有状态的。有状态意味着每次评估函数时,内部状态都会更改,并将持续到下一次评估。
例如,内置函数 sigma
计算运行平均值和标准差,并返回当前数据点偏离平均值的标准差数。
示例 1 – sigma 函数
sigma("value") > 3.0
每次评估表达式时,它都会更新运行统计信息,然后返回偏差。示例 1 中的简单表达式评估为 false
,而它接收到的数据点流保持在运行平均值的 3.0
个标准差范围内。一旦处理的值偏离平均值超过 3.0
个标准差,它就会评估为 true
。这样的表达式可以在 TICKscript 内部使用,以定义强大的警报,如下面的示例 2 所示。
示例 2 – 带有 lambda 表达式的 TICKscript
stream
|from()
...
|alert()
// use an expression to define when an alert should go critical.
.crit(lambda: sigma("value") > 3.0)
关于意外类型转换的注意事项
请注意,在 TICKscript 中声明的数值遵循 语法 文档中引入的字面量解析规则。它们的类型可能不适合它们将要使用的函数或操作。包含小数的数值将被解释为浮点数。不带小数的数值将被解释为整数。当整数和浮点数在同一表达式中使用时,如果需要浮点结果,则整数值需要使用 float()
类型转换函数。不遵守此规则可能会产生意外的结果。例如,当使用 lambda 表达式计算 0 到 1 之间类型的浮点数比率以用于生成百分比时;当字段类型为整数时,可能会假设子集字段可以除以总字段以获得比率(例如 subset/total * 100
)。这种整数除以整数的运算将导致整数值 0。此外,将此类运算的结果乘以字面量 100
(整数)也会导致 0。将整数值强制转换为浮点数将导致 0 到 1 范围内的有效比率,然后乘以字面量 100.0
(浮点数)将导致有效的百分比值。正确编写后,这样的操作应如下所示
eval(lambda: float("total_error_responses")/float("total_responses") * 100.0)
.
如果在日志中出现 E! mismatched type to binary operator...
类型的错误,请检查以确保运算符两侧的字段类型相同且为所需的类型。
简而言之,为确保字段值的类型正确,请使用内置类型转换函数(请参阅 下方)。
内置函数
有状态函数
计数
计数不接受任何参数,但返回表达式被评估的次数。
count() int64
Sigma
计算给定值偏离运行平均值的标准差数。每次评估表达式时,都会更新运行平均值和标准差。
sigma(value float64) float64
Spread
计算传递给它的所有值的运行范围。范围是接收到的最大值和最小值之间的差。
spread(value float64) float64
无状态函数
类型转换函数
Bool
通过 Golang 的 strconv.ParseBool 函数将字符串转换为布尔值。数字类型也可以转换为布尔值,其中 0 -> false 和 1 -> true。
bool(value) bool
Int
通过 Golang 的 strconv.ParseInt 或简单的 int64()
强制转换将字符串或 float64 转换为 int64。字符串被假定为十进制数。持续时间转换为纳秒单位的 int64。布尔值转换为 int64,其中 false -> 0 和 true -> 1。
int(value) int64
Float
通过 Golang 的 strconv.ParseFloat 或简单的 float64()
强制转换将字符串或 int64 转换为 float64。布尔值转换为 float64,其中 false -> 0.0 和 true -> 1.0。
float(value) float64
String
通过 Golang 的 strconv.Format* 函数将布尔值、int64 或 float64 转换为字符串。持续时间转换为持续时间的字符串表示形式。
string(value) string
Duration
将 int64 或 float64 转换为持续时间,假设单位在第二个参数中指定。字符串转换为 TICKscript 中持续时间字面量的形式的持续时间。
duration(value int64|float64, unit duration) duration
duration(value string) duration
Existence
IsPresent
根据指定的字段或标签键是否存在返回布尔值。用于过滤掉缺少指定字段或标签的数据。
|where(lambda: isPresent("myfield"))
如果 myfield
是有效的标识符,则返回 TRUE
,否则返回 FALSE
。
时间函数
time
字段
在每个表达式中,time
字段包含当前数据点的时间。以下函数可用于 time
字段。每个函数都返回一个 int64。
函数 | 描述 |
---|---|
unixNano(t time) int64 | 自 1970 年 1 月 1 日 UTC(Unix 时间)以来经过的纳秒数 |
minute(t time) int64 | 小时内的分钟:范围 [0,59] |
hour(t time) int64 | 一天内的小时:范围 [0,23] |
weekday(t time) int64 | 一周内的工作日:范围 [0,6],0 是星期日 |
day(t time) int64 | 一个月内的天数:范围 [1,31] |
month(t time) int64 | 一年内的月份:范围 [1,12] |
year(t time) int64 | 年份 |
用法示例
lambda: hour("time") >= 9 AND hour("time") < 19
如果数据点一天中的小时介于 0900 小时和 1900 小时之间,则以上表达式的计算结果为 true
。
Now
返回当前时间。
now() time
用法示例
lambda: "expiration" < unixNano(now())
数学函数
以下数学函数可用。每个函数都通过等效的 Go 函数实现(仅在下表中链接以供参考)。
字符串函数
以下字符串操作函数可用。每个函数都通过等效的 Go 函数实现(仅在下表中链接以供参考)。
函数 | 描述 |
---|---|
strContains(s, substr string) bool | StrContains 报告 substr 是否在 s 中。 |
strContainsAny(s, chars string) bool | StrContainsAny 报告 chars 中的任何 Unicode 代码点是否在 s 中。 |
strCount(s, sep string) int64 | StrCount 计算 s 中 sep 的非重叠实例数。如果 sep 是空字符串,则 Count 返回 1 + s 中 Unicode 代码点的数量。 |
strHasPrefix(s, prefix string) bool | StrHasPrefix 测试字符串 s 是否以 prefix 开头。 |
strHasSuffix(s, suffix string) bool | StrHasSuffix 测试字符串 s 是否以 suffix 结尾。 |
strIndex(s, sep string) int64 | StrIndex 返回 sep 在 s 中首次出现的索引,如果 sep 在 s 中不存在,则返回 -1。 |
strIndexAny(s, chars string) int64 | StrIndexAny 返回 chars 中任何 Unicode 代码点在 s 中首次出现的索引,如果 chars 中没有 Unicode 代码点在 s 中存在,则返回 -1。 |
strLastIndex(s, sep string) int64 | StrLastIndex 返回 sep 在 s 中最后一次出现的索引,如果 sep 在 s 中不存在,则返回 -1。 |
strLastIndexAny(s, chars string) int64 | StrLastIndexAny 返回 chars 中任何 Unicode 代码点在 s 中最后一次出现的索引,如果 chars 中没有 Unicode 代码点在 s 中存在,则返回 -1。 |
strLength(s string) int64 | StrLength 返回字符串的长度。 |
strReplace(s, old, new string, n int64) string | StrReplace 返回字符串 s 的副本,其中前 n 个非重叠的 old 实例被 new 替换。 |
strSubstring(s string, start, stop int64) string | StrSubstring 基于给定的索引返回子字符串,strSubstring(str, start, stop) 等效于 Go 中的 str[start:stop]。 |
strToLower(s string) string | StrToLower 返回字符串 s 的副本,其中所有 Unicode 字母都映射为小写。 |
strToUpper(s string) string | StrToUpper 返回字符串 s 的副本,其中所有 Unicode 字母都映射为大写。 |
strTrim(s, cutset string) string | StrTrim 返回字符串 s 的切片,其中删除了 cutset 中包含的所有前导和尾随 Unicode 代码点。 |
strTrimLeft(s, cutset string) string | StrTrimLeft 返回字符串 s 的切片,其中删除了 cutset 中包含的所有前导 Unicode 代码点。 |
strTrimPrefix(s, prefix string) string | StrTrimPrefix 返回不带提供的前导 prefix 字符串的 s。如果 s 不以 prefix 开头,则返回不变的 s。 |
strTrimRight(s, cutset string) string | StrTrimRight 返回字符串 s 的切片,其中删除了 cutset 中包含的所有尾随 Unicode 代码点。 |
strTrimSpace(s string) string | StrTrimSpace 返回字符串 s 的切片,其中删除了所有前导和尾随空格,如 Unicode 所定义。 |
strTrimSuffix(s, suffix string) string) | StrTrimSuffix 返回不带提供的尾随 suffix 字符串的 s。如果 s 不以 suffix 结尾,则返回不变的 s。 |
regexReplace(r regex, s, pattern string) string | RegexReplace 将输入字符串中正则表达式的匹配项替换为输出字符串。例如,regexReplace(/a(b*)c/, ‘abbbc’, ‘group is $1’) -> ‘group is bbb’。如果未找到匹配项,则返回原始字符串。 |
示例
.where(lambda: !strContains("fstype", 'nfs') OR !strContains("fstype", 'cifs'))
人类可读的字符串函数
HumanBytes
将带有字节单位的 int64 或 float64 转换为表示字节数的人类可读字符串。
humanBytes(value) string
条件函数
If
根据第一个参数的值返回其操作数的结果。第二个和第三个参数必须返回相同的类型。
示例
|eval(lambda: if("field" > threshold AND "field" != 0, 'high', 'normal'))
.as('value')
在上面的示例中,字段 value
的值将是字符串 high
或 normal
,具体取决于作为第一个参数传递的条件。
if
函数的返回类型与其第二个和第三个参数的类型相同。
if(condition, true expression, false expression)
此页内容对您有帮助吗?
感谢您的反馈!
支持和反馈
感谢您成为我们社区的一份子!我们欢迎并鼓励您提供关于 Kapacitor 和本文档的反馈和错误报告。要获得支持,请使用以下资源