TICKScript は、データ処理、または ETL、イベント監視、変更追跡などを含むタスクの実行に使用されます。アラートはそのアプリケーションの 1 つにすぎません。ドメイン固有言語 (DSL) です。
ノードはそのコア コンポーネントであり、データを取得して処理するための基本的なコンポーネントです。batch、stream、query、from、eval、alert などはすべてノードです。直感的には、組み込み関数として理解できます。その中で、バッチとストリームは、データを取得するための最も基本的なノードです。
パイプラインは、ノードが相互に連携する方法です. データは常に 1 つのノードから別のノードに流れ、最終的なデータ処理パスは DAG を形成します. 各ノードは DAG 内のノードとして理解でき、ノード間のフローはエッジです。
文法: TICKScript の記述仕様。
ラムダ式: TICKScript はデータを処理する必要があるため、何らかの計算を行うことは避けられず、ラムダ式を使用して計算を記述します。
文法
スクリプトの構文は多くの言語を参照しており、主なものは golang であり、文字列テンプレート、期間など、golang から多くの概念を借用しています。
TICKScript は 2 つの構文サブセットを使用します。1 つは influxQL で、もう 1 つは Lambda 式です。
変数とリテラル
言葉 |
使用法 |
真実 |
リテラルブール値「true」。 |
間違い |
リテラルブール値「false」。 |
と |
標準のブール論理積演算子。 |
また |
標準ブール論理和演算子。 |
ラムダ: |
続くものがラムダ式として解釈されることを示すフラグ。 |
だった |
変数宣言を開始します。 |
dbrp |
データベース宣言を開始します |
オペレーター |
使用法 |
例 |
+ |
加算と文字列連結 |
3 + 6、合計 + カウント、および 'foo' + 'bar' |
- |
減算 |
10 - 1、合計 - エラー |
* |
乗算 |
3 * 6、比率 * 100.0 |
/ |
分割 |
36 / 4、エラー / 合計 |
== |
同等性の比較 |
1 == 1、日付 == 今日 |
!= |
不等式の比較 |
結果 != 0、ID != 「テストベッド」 |
< |
未満の比較 |
4 < 5、タイムスタンプ < 今日 |
<= |
以下の比較 |
3 <= 6、フロー <= 平均 |
> |
より大きい比較 |
6 > 3.0、デルタ > シグマ |
>= |
以上の比較 |
9.0 >= 8.1、数量 >= しきい値 |
=~ |
正規表現一致。正しい値は正規表現でなければなりません またはそのような式を保持する変数。 |
tag =~ /^cz\d+/, goの規則性参照 |
!~ |
正規表現が一致しません。正しい値は正規表現でなければなりません またはそのような式を保持する変数。 |
タグ !~ /^sn\d+/, go の規則性参照 |
! |
論理的でない |
!TRUE, !(cpu_idle > 70) |
と |
論理積 |
レート < 20.0 AND レート >= 10 |
また |
論理和 |
ステータス > 警告またはデルタ > シグマ |
表 3 – 連鎖演算子
オペレーター |
使用法 |
例 |
| | |
新しいノードのインスタンスを作成し、それをその上のノードにチェーンするチェーン メソッド呼び出しを宣言します。 つまり、データ処理パイプラインです。 |
ストリーム |from() |
. |
プロパティ メソッド呼び出しを宣言し、それが属するノードの内部プロパティを設定または変更します。 これは、現在の変数に属性を追加または変更することと同じです。一部のメソッドは、パイプラインまたは . 演算子を使用して実装できるため、パイプラインとの違いに注意してください。 |
から() .データベース (mydb) |
@ |
ユーザー定義関数 (UDF) 呼び出しを宣言します。基本的には、新しい UDF ノードをパイプラインに追加するチェーン メソッドです。 |
から() ... @MyFunc() |
言語には . で始まるグローバル組み込み変数がいくつかあり、次のように{{}} を文字列で ラップすることでアクセスできます。
変数 |
例証する |
{ {.ID}} |
構成インターフェースで設定されたアラーム名 |
{ {.Name}} |
データベース名 |
{ {.タスク名}} |
クロノグラフで始まるランダムなコードの文字列、読んでも意味がない |
{ {.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.
Nodes:
有很多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信息就会丢失,所以在这些情形下,不适合使用。
influxQL 在 TICKScript中的使用
在TICKScript中,influxQL一般在query中使用,而且它只支持如下结构:
SELECT {<FIELD_KEY> | <TAG_KEY> | <FUNCTION>([<FIELD_KEY>|<TAG_KEY])} FROM <DATABASE>.<RETENTION_POLICY>.<MEASUREMENT> WHERE {<CONDITIONAL_EXPRESSION>}
可以看到,它只支持select, from, where三个关键结构,并不支持其它结构。
Lambda表达式
简单示例:
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 reports whether substr is within s. |
|
StrContainsAny reports whether any Unicode code points in chars are within s. |
|
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 tests whether the string s begins with prefix. |
|
StrHasSuffix tests whether the string s ends with suffix. |
|
StrIndex returns the index of the first instance of sep in s, or -1 if sep is not present in s. |
|
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 returns the index of the last instance of sep in s, or -1 if sep is not present in s. |
|
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 returns the length of the string. |
|
StrReplace returns a copy of the string s with the first n non-overlapping instances of old replaced by new. |
|
StrSubstring returns a substring based on the given indexes, strSubstring(str, start, stop) is equivalent to str[start:stop] in Go. |
|
StrToLower returns a copy of the string s with all Unicode letters mapped to their lower case. |
|
StrToUpper returns a copy of the string s with all Unicode letters mapped to their upper case. |
|
StrTrim returns a slice of the string s with all leading and trailing Unicode code points contained in cutset removed. |
|
StrTrimLeft returns a slice of the string s with all leading Unicode code points contained in cutset removed. |
|
StrTrimPrefix returns s without the provided leading prefix string. If s doesn’t start with prefix, s is returned unchanged. |
|
StrTrimRight returns a slice of the string s, with all trailing Unicode code points contained in cutset removed. |
|
StrTrimSpace returns a slice of the string s, with all leading and trailing white space removed, as defined by Unicode. |
|
StrTrimSuffix returns s without the provided trailing suffix string. If s doesn’t end with suffix, s is returned unchanged. |
|
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. |