TICKScript是用来做数据处理的,或者说用来执行任务的,包括ETL、事件监控、变化跟踪等,alert只是其应用之一。它是一种Domain Specific Language(DSL)。
Node是它最核心的组件,是获取和处理数据的基本组件。如batch, stream, query, from, eval, alert等,都是node。直观上看可以理解为一种内置函数。其中batch和stream是获取数据的最基本node。
pipeline是Nodes之间相互协作的方式,数据总是从一个node流向另一个node,最后的数据处理路径会形成一个DAG。每个node都可以理解为dag中的一个节点,而node之间的一次流动则是一个边(edge)。
语法:TICKScript的编写规范。
Lambda表达式:因为TICKScript要处理数据,免不了要做一些运算,lambda表达式便是用来进行运算描述的。
脚本的语法参考了很多语言,其中主要的是golang,并且从golang中借鉴了很多概念,比如string template, duration之类。
TICKScript使用了两个语法子集,一个是influxQL,一个是Lambda表达式。
Word |
Usage |
TRUE |
The literal Boolean value “true”. |
FALSE |
The literal Boolean value “false”. |
AND |
Standard Boolean conjunction operator. |
OR |
Standard Boolean disjunction operator. |
lambda: |
Flags that what follows is to be interpreted as a lambda expression. |
var |
Starts a variable declaration. |
dbrp |
Starts a database declaration |
Operator |
Usage |
Examples |
+ |
Addition and string concatenation |
3 + 6, total + count and 'foo' + 'bar' |
- |
Subtraction |
10 - 1, total - errs |
* |
Multiplication |
3 * 6, ratio * 100.0 |
/ |
Division |
36 / 4, errs / total |
== |
Comparison of equality |
1 == 1, date == today |
!= |
Comparison of inequality |
result != 0, id != "testbed" |
< |
Comparison less than |
4 < 5, timestamp < today |
<= |
Comparison less than or equal to |
3 <= 6, flow <= mean |
> |
Comparison greater than |
6 > 3.0, delta > sigma |
>= |
Comparison greater than or equal to |
9.0 >= 8.1, quantity >= threshold |
=~ |
Regular expression match. Right value must be a regular expression or a variable holding such an expression. |
tag =~ /^cz\d+/,参考go的正则 |
!~ |
Regular expression not match. Right value must be a regular expression or a variable holding such an expression. |
tag !~ /^sn\d+/,参考go的正则 |
! |
Logical not |
!TRUE, !(cpu_idle > 70) |
AND |
Logical conjunction |
rate < 20.0 AND rate >= 10 |
OR |
Logical disjunction |
status > warn OR delta > sigma |
Table 3 – Chaining operators
Operator |
Usage |
Examples |
| |
Declares a chaining method call which creates an instance of a new node and chains it to the node above it. 也就是一个数据处理管道。 |
stream |from() |
. |
Declares a property method call, setting or changing an internal property in the node to which it belongs. 相当于给当前变量增加或修改属性。注意与管道的区别,因为有些方法即可以使用管道实现也可以通过.号操作符实现。 |
from() .database(mydb) |
@ |
Declares a user defined function (UDF) call. Essentially a chaining method that adds a new UDF node to the pipeline. |
from() ... @MyFunc() |
语言中有一些.开头的全局内置变量,可以在 字符串中通过{{}}包裹的方式来访问它们,如:
变量 |
说明 |
{{.ID}} |
在配置界面设置的报警名称 |
{{.Name}} |
database名称 |
{{.TaskName}} |
以chronograf开头的一串随机编码,没有阅读意义 |
{{.Group}} |
尚不清楚用途 |
{{.Tags}} |
触发报警时的tags条件具体内容 |
{{index .Tags "coin" }} |
取得触发报警时tags中指定字段的值,比如此例意为取tags中coin字段的值 |
{{.Level}} |
报警级别,目前发现的有OK和CRITICAL两个值,还有WARNNING,INFO两种值 |
{{.Fields}} |
触发报警时的fields的具体内容 |
{{ index .Fields "value" }} |
取得触发报警时,fields里指定字段的值,比如此例意为取得fields中value字段的值 |
{{.Time}} |
触发报警时的时间 |
{{ if eq .Level "OK" }}alive{{ else }}dead{{ end }} |
If…else…形式的判断语句也可以在{{}}中使用 |
{{ index .Fields "stat" | printf "%0.2f" }} |
还可以进行这种管道操作,注意可以使用printf |
在TICKScript中,字符串的定义可以使用',也可以使用''',但不能使用"。"可以在表示influxQL的字符中使用以包裹数据库名称等。来自文档的说明是:如果想在lambda表达式中访问一个tag或者field,需要使用双引号包裹字段名;如果是在一个函数调用中想把字段做为参数使用时,使用单引号。另外,通过as命名的新field可以在后续的操作中作为普通field一样遵守上述规则。
例:
lambda: "cpu" == 'cpu-total'
中, "cpu" 是指对字段的引用 ,而 'cpu-total' 则是字面值 。
声明:
Dbrp是数据库声名关键字,用来表示所使用的数据库和rp。一般写法为:
dbrp "mydb"."autogen"
在chronograf中,新建脚本时有一个下拉框可以用于指定dbrp,因为在脚本里不需要再作如上定义,否则会被认为重复定义。
其它都是普通的变量声明,使用var即可。如:
var abc='abc'
表达式:
表达式一般以一个node标识符或者表示另一个表达式的变量开始,然后后面就是一系列的管道(|)、点号(.)、UDF(@)进行的处理,见上文中表格的定义。虽然示例中会有换行与缩进,但实际上如果不担心阅读问题,完全可把一个表达式写在一行里,它并不学python。
Pipeline:
pipeline之前提到过,最基本的是两种,一种是stream,只能通过from方法来建立;一种是batch,只能通过query方法来建立。
通过influxOut()管道可以实现将处理结果写入指定的measurement.
有很多node貌似是通用的,大部分node都可以follow,比如count,mean,min,max之类。
AlertNode
文档链接:
https://docs.influxdata.com/kapacitor/v1.5/nodes/alert_node
Tips:
1. stateChangesOnly(10m) 这个方法的作用是只有当alert的状态发生改变的时候才发送报警。通过时间参数,可以控制即便没有发生状态改变,如果超过了参数中指定的时间,一个被触发的警报仍然会发出。
2. 对postHandler而言,topic方法可以通过在kapacitor的[[httppost]]段中定义的topic来使用预定义的post网关。可以通过指定消息模板来控制发送的内容的格式(尚未尝试)。
3. warnReset,infoReset,critReset这几个方法的作用有点奇怪,看文档描述也没看明白。
4. deadman是一个特殊用途的封装,用于统计一个脚本通道中的数据吞吐量,如:
deadman(100.0, 10s, lambda: hour("time") >= 8 AND hour("time") <= 17)
表示在10s内,满足lambda条件的数据数量如果低于100,则触发一个报警,返回一个alertNode.
WindowNode
文档链接:
https://docs.influxdata.com/kapacitor/v1.5/nodes/window_node/
看文档描述,window的period与every方法的确如词面意义,每多长时间,获取period窗口期内的数据。如果peroid比every长,则会拿到一些上次every期的数据。然后其作用是在pipeline中影响其后续的node。
whereNode
文档链接:
https://docs.influxdata.com/kapacitor/v1.5/nodes/where_node/
evalNode
Eval后面可以跟as,语法为:.eval(lambda: "age" * 10, "firstName" + ' ' + "lastName").as("a", "b")。在使用之后,只有新的字段会被保留,原来的字段会被抛弃,使用keep()可以指定保留其它字段。Keep()不带参数时,表示保留所有字段;而且keep只对field生效,time和tags都会带。
在as()方法后面使用tags()可以把一个生成的字段转化为tag。如:eval(lambda:xxxx).as('abc').tags('abc')。
batchNode和streamNode
batch和stream是最基本的node,分别必须通过后接queryNode和fromNode管道来取得数据。详见下面关于query和from的node。
queryNode
queryNode与formNode不同,可以不用chain windowNode就可以使用period和every方法。groupBy()方法里可以跟多个条件,其中可以有一个是time,语法跟influxQL是一样的。
值得注意的是,它还支持通过通配符匹配一系列measurements,然后groupByMeasurements()。
fromNode
fromNode的groupBy与queryNode的groupBy不太一样,它的groupBy会把分组数据拆到几个变量里,然后分开处理,在alert的时候,如果按某一维度进行groupBy,分组出来的结果会分成几个消息发送。
influxQLNode
这是一类特殊的node,因为在使用min,max,mean等方法时,会产生这个类型的node,所以需要特别记录一下。结果很简单,可以使用的方法常用的也就as()一个,用来重命名。处理的结果是一行。
在使用中,尝试对tag进行distinct的时候报错,看来这种统计方法只能对field使用。而且结果不是一行,而是每一个特异的值一行。
groupByNode
这个Node可以在很多场合下使用,用来对数据进分组,看起来更加灵活,但是一但使用它,之前在query或者form里的tag信息和group信息就会丢失,所以在这些情形下,不适合使用。
在TICKScript中,influxQL一般在query中使用,而且它只支持如下结构:
SELECT {
可以看到,它只支持select, from, where三个关键结构,并不支持其它结构。
简单示例:
var my_lambda = lambda: 1 > 0
var lazy_lambda = lambda: "usage_idle" < 95
lambda: "stat" > 70 OR "sigma" > 2.5
在做运算的时候需要注意一点,就是数制转换。在进行数学运算的时候,如果一个数字不带小数部分,就会被当作整数。整数相除结果会被作为整数。因为 3/4 这样会得到0而不是0.75. 要得到正确的结果,需要使用float()函数,即fload(3)/float(4),或者3.0/4.0也可以,这样就会得到一个float的结果;在处理字段运算的时候,没法通过加小数位.0的方式,所以只能使用float()函数。
统计
count()用于计算传入值的个数,sigma()用于计算传入值的标准差,spread()用于计算传入值的范围。
强制类型转化
bool(), int(), float(), string(), duration()把一个数字以纳秒为单位转化为时间
判存
isPresent()判断指定字段是否存在
时间函数
Function |
Description |
unixNano(t time) int64 |
the number of nanoseconds elapsed since January 1, 1970 UTC (Unix time) |
minute(t time) int64 |
the minute within the hour: range [0,59] |
hour(t time) int64 |
the hour within the day: range [0,23] |
weekday(t time) int64 |
the weekday within the week: range [0,6], 0 is Sunday |
day(t time) int64 |
the day within the month: range [1,31] |
month(t time) int64 |
the month within the year: range [1,12] |
year(t time) int64 |
the year |
数学函数
Function |
Description |
abs(x float64) float64 |
Abs returns the absolute value of x. |
acos(x float64) float64 |
Acos returns the arccosine, in radians, of x. |
acosh(x float64) float64 |
Acosh returns the inverse hyperbolic cosine of x. |
asin(x float64) float64 |
Asin returns the arcsine, in radians, of x. |
asinh(x float64) float64 |
Asinh returns the inverse hyperbolic sine of x. |
atan(x float64) float64 |
Atan returns the arctangent, in radians, of x. |
atan2(y, x float64) float64 |
Atan2 returns the arc tangent of y/x, using the signs of the two to determine the quadrant of the return value. |
atanh(x float64) float64 |
Atanh returns the inverse hyperbolic tangent of x. |
cbrt(x float64) float64 |
Cbrt returns the cube root of x. |
ceil(x float64) float64 |
Ceil returns the least integer value greater than or equal to x. |
cos(x float64) float64 |
Cos returns the cosine of the radian argument x. |
cosh(x float64) float64 |
Cosh returns the hyperbolic cosine of x. |
erf(x float64) float64 |
Erf returns the error function of x. |
erfc(x float64) float64 |
Erfc returns the complementary error function of x. |
exp(x float64) float64 |
Exp returns e**x, the base-e exponential of x. |
exp2(x float64) float64 |
Exp2 returns 2**x, the base-2 exponential of x. |
expm1(x float64) float64 |
Expm1 returns e**x - 1, the base-e exponential of x minus 1. It is more accurate than Exp(x) - 1 when x is near zero. |
floor(x float64) float64 |
Floor returns the greatest integer value less than or equal to x. |
gamma(x float64) float64 |
Gamma returns the Gamma function of x. |
hypot(p, q float64) float64 |
Hypot returns Sqrt(p*p + q*q), taking care to avoid unnecessary overflow and underflow. |
j0(x float64) float64 |
J0 returns the order-zero Bessel function of the first kind. |
j1(x float64) float64 |
J1 returns the order-one Bessel function of the first kind. |
jn(n int64, x float64) float64 |
Jn returns the order-n Bessel function of the first kind. |
log(x float64) float64 |
Log returns the natural logarithm of x. |
log10(x float64) float64 |
Log10 returns the decimal logarithm of x. |
log1p(x float64) float64 |
Log1p returns the natural logarithm of 1 plus its argument x. It is more accurate than Log(1 + x) when x is near zero. |
log2(x float64) float64 |
Log2 returns the binary logarithm of x. |
logb(x float64) float64 |
Logb returns the binary exponent of x. |
max(x, y float64) float64 |
Max returns the larger of x or y. |
min(x, y float64) float64 |
Min returns the smaller of x or y. |
mod(x, y float64) float64 |
Mod returns the floating-point remainder of x/y. The magnitude of the result is less than y and its sign agrees with that of x. |
pow(x, y float64) float64 |
Pow returns x**y, the base-x exponential of y. |
pow10(x int64) float64 |
Pow10 returns 10**e, the base-10 exponential of e. |
sin(x float64) float64 |
Sin returns the sine of the radian argument x. |
sinh(x float64) float64 |
Sinh returns the hyperbolic sine of x. |
sqrt(x float64) float64 |
Sqrt returns the square root of x. |
tan(x float64) float64 |
Tan returns the tangent of the radian argument x. |
tanh(x float64) float64 |
Tanh returns the hyperbolic tangent of x. |
trunc(x float64) float64 |
Trunc returns the integer value of x. |
y0(x float64) float64 |
Y0 returns the order-zero Bessel function of the second kind. |
y1(x float64) float64 |
Y1 returns the order-one Bessel function of the second kind. |
yn(n int64, x float64) float64 |
Yn returns the order-n Bessel function of the second kind. |
字符串处理函数
Function |
Description |
strContains(s, substr string) bool |
StrContains reports whether substr is within s. |
strContainsAny(s, chars string) bool |
StrContainsAny reports whether any Unicode code points in chars are within s. |
strCount(s, sep string) int64 |
StrCount counts the number of non-overlapping instances of sep in s. If sep is an empty string, Count returns 1 + the number of Unicode code points in s. |
strHasPrefix(s, prefix string) bool |
StrHasPrefix tests whether the string s begins with prefix. |
strHasSuffix(s, suffix string) bool |
StrHasSuffix tests whether the string s ends with suffix. |
strIndex(s, sep string) int64 |
StrIndex returns the index of the first instance of sep in s, or -1 if sep is not present in s. |
strIndexAny(s, chars string) int64 |
StrIndexAny returns the index of the first instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s. |
strLastIndex(s, sep string) int64 |
StrLastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s. |
strLastIndexAny(s, chars string) int64 |
StrLastIndexAny returns the index of the last instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s. |
strLength(s string) int64 |
StrLength returns the length of the string. |
strReplace(s, old, new string, n int64) string |
StrReplace returns a copy of the string s with the first n non-overlapping instances of old replaced by new. |
strSubstring(s string, start, stop int64) string |
StrSubstring returns a substring based on the given indexes, strSubstring(str, start, stop) is equivalent to str[start:stop] in Go. |
strToLower(s string) string |
StrToLower returns a copy of the string s with all Unicode letters mapped to their lower case. |
strToUpper(s string) string |
StrToUpper returns a copy of the string s with all Unicode letters mapped to their upper case. |
strTrim(s, cutset string) string |
StrTrim returns a slice of the string s with all leading and trailing Unicode code points contained in cutset removed. |
strTrimLeft(s, cutset string) string |
StrTrimLeft returns a slice of the string s with all leading Unicode code points contained in cutset removed. |
strTrimPrefix(s, prefix string) string |
StrTrimPrefix returns s without the provided leading prefix string. If s doesn’t start with prefix, s is returned unchanged. |
strTrimRight(s, cutset string) string |
StrTrimRight returns a slice of the string s, with all trailing Unicode code points contained in cutset removed. |
strTrimSpace(s string) string |
StrTrimSpace returns a slice of the string s, with all leading and trailing white space removed, as defined by Unicode. |
strTrimSuffix(s, suffix string) string) |
StrTrimSuffix returns s without the provided trailing suffix string. If s doesn’t end with suffix, s is returned unchanged. |
regexReplace(r regex, s, pattern string) string |
RegexReplace replaces matches of the regular expression in the input string with the output string. For example regexReplace(/a(b*)c/, ‘abbbc’, ‘group is $1’) -> ‘group is bbb’. The original string is returned if no matches are found. |