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 – 带有 λ 表达式的 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 该函数不接受任何参数,但返回表达式被评估的次数。
count() int64
西格玛
计算给定值与运行均值之间的标准差数量。每次计算该表达式时,运行均值和标准差都会更新。
sigma(value float64) float64
扩散
计算传入的所有值的运行范围。范围是 接收到的最大值和最小值之间的差。
spread(value float64) float64
无状态函数
类型转换函数
布尔
通过Golang的 strconv.ParseBool函数将字符串转换为布尔值。数字类型也可以转换为布尔值,其中0 -> false,1 -> true。
bool(value) bool
整数
通过Golang的
strconv.ParseInt或简单的
int64() 强制转换,将字符串或float64转换为int64。字符串被假定为十进制数字。时间持续时间被转换为以纳秒为单位的int64。布尔值被转换为int64,其中false -> 0,true -> 1。
int(value) int64
浮点数
通过Golang的
strconv.ParseFloat 或简单的
float64() 强制转换,将字符串或int64转换为float64。
布尔值被转换为float64,其中 false -> 0.0 和 true -> 1.0。
float(value) float64
字符串
将 bool、int64 或 float64 值通过 Golang 的 strconv.Format* 函数转换为字符串。 持续时间被转换为持续时间的字符串表示。
string(value) string
持续时间
将int64或float64转换为持续时间,假设单位如第二个参数所指定 字符串被转换为TICKscript中持续时间字面量的形式。
duration(value int64|float64, unit duration) duration
duration(value string) duration
存在
存在
根据指定的字段或标签键是否存在返回布尔值。用于过滤掉缺少指定字段或标签的数据。
|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() 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中第一次出现的索引,如果s中不存在sep,则返回-1。 |
| strIndexAny(s, chars string) int64 | StrIndexAny 返回 chars 中任意 Unicode 码点在 s 中的第一次出现的索引,如果 s 中不包含 chars 的 Unicode 码点,则返回 -1。 |
| strLastIndex(s, sep string) int64 | StrLastIndex 返回 sep 在 s 中最后一次出现的索引,如果 sep 不在 s 中则返回 -1。 |
| strLastIndexAny(s, chars string) int64 | StrLastIndexAny 返回字符 chars 在 s 中最后一个 Unicode 代码点的索引,如果 s 中不存在字符 chars 的 Unicode 代码点,则返回 -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返回去掉提供的前导前缀字符串后的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 返回去掉提供的尾部后缀字符串的 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'))
人类字符串函数
人类字节
将一个带有字节单位的 int64 或 float64 转换为一个可人类阅读的字符串,表示字节数。
humanBytes(value) string
条件函数
如果
根据第一个参数的值返回操作数的结果。第二个和第三个参数必须返回相同的类型。
示例:
|eval(lambda: if("field" > threshold AND "field" != 0, 'high', 'normal'))
.as('value')
上面例子中字段 value 的值将是字符串 high 或 normal,具体取决于作为第一个参数传递的条件。
该if函数的返回类型与它的第二个和第三个参数的类型相同。
if(condition, true expression, false expression)