本文介绍SLS DSL的基础语法。

注释

对语法进行解释说明,需要以井号(#)开头。示例如下:
#设置日志的默认主题(放在行首的注释)。
e_set("__topic__", "access_log")   #设置日志的默认主题(放在行尾的注释)。

换行

函数调用的参数列表过长时,需要换行。
  • 如果函数结构中存在半角逗号(,),可以直接在半角逗号(,)的地方进行换行。
  • 如果某个字符串过长需要换行,可以使用反斜线(\)换行。
示例如下:
e_set("__topic__", "v1",
        "type", "v2",       #使用半角逗号(,)分隔时,直接换行。
        "length", 100)
e_set("__topic__", "this is a very long long long .........." \  #使用反斜线(\)换行。
                            "......long text")

函数调用方式

  • 基本调用方式
    e_set("abc", "xyz")
    说明 编写数据加工语句时,传入参数类型和数量需要与函数语法匹配。
  • 基本变参调用
    str_replace(值, old [,new [,count] ]) 
    说明 函数参数中包含如上形式的方括号([])时,其参数例如newcount比较特殊,属于可选参数,但不能使用命名参数形式调用且只能顺序调用。
    #错误示例
    str_replace("a-b-c", "-", new='%')
    str_replace("a-b-c", "-", new='%', count=1)
    #正确示例
    str_replace("a-b-c", "-", '%')
    str_replace("a-b-c", "-", '%', 2)
  • 命名参数调用方式
    有默认值的参数叫做命名参数,例如e_set("abc", "xyz", mode="fill")中的mode
    • 某些函数的命名参数在特定条件下必须传入值,具体请参见每个函数的参数说明。
    • 传递参数值的方式为:mode=...
    • 有多个命名参数时,对传递顺序没有严格要求,例如e_csv("data", ["f1", "f2", "f3"], sep='#', quote="|")e_csv("data", ["f1", "f2", "f3"], quote="|", sep='#')相同。
    说明 在函数中,命名参数始终排在非命名参数的后面。
  • 组合调用
    将函数的返回值作为其他函数参数的取值,需要确保两个数据的数据类型一致。例如:
    e_set("abc", v("xyz"))
    e_set("abc", str_lower(v("xyz")))
  • 变参

    某些函数支持变参传递。v("f1", ....)表示可以传递更多参数,例如v("f1", "f2", "f3")

    传入命名参数时,命名参数需要放在最后,例如v("f1", "f2", "f3", "f4", mode="fill")

操作符

  • 比较运算符

    SLS DSL标准模式支持大小比较运算符,包括>、<、>=、<=、!=、==。您也可以使用日志服务提供的比较运算函数来实现相同效果。
    • 直接使用比较运算符
      #下面是一些使用样例,当大小比较结果为True时,丢弃日志。
      e_if(3 > 2, DROP)       # 3大于2时,丢弃。
      e_if(3 < 2, DROP)       # 3小于2时,丢弃。
      e_if(3 >= 2, DROP)      # 3大于等于2时,丢弃。
      e_if(3 <= 2, DROP)      # 3小于等于2时,丢弃。
      e_if(3 == 2, DROP)      # 3等于2时,丢弃。
      e_if(3 != 2, DROP)      # 3不等于2时,丢弃。
      e_if(1 < 2 < 3, DROP)   # 2大于1且2小于3时,丢弃。
      e_if(0 < ct_int(v('x')) < 100, DROP) # 字段x的值大于0且小于100时,丢弃。
    • 使用日志服务提供的比较运算函数
      场景操作 函数 示例
      判断等于== op_eq op_eq(v("name"), "xiao ming")
      判断不等于!= op_ne op_ne(v("name"), "xiao ming")
      大于> op_gt op_gt(ct_int(v("age")), )
      大于等于>= op_ge op_ge(ct_int(v("age")), 18)
      小于< op_lt op_lt(ct_int(v("age")), 18)
      小于等于<= op_le op_le(ct_int(v("age")), 18)
  • 逻辑运算符

    SLS DSL标准模式支持逻辑运算符,包括and、or和not。您也可以使用日志服务提供的逻辑运算函数来实现相同效果。
    • 直接使用逻辑运算符
      #下面是一些使用样例,当逻辑运算的结果为True时,丢弃日志。
      e_if(True and False, DROP)     # 结果为False
      e_if(True or False, DROP)      # 结果为True
      e_if(True and not False, DROP) # 结果为True
      e_if(3 > 2 and 1 < 3, DROP)    # 结果为True
      e_if(ct_int(v('x')) > 100 or ct_int(v('y')) < 100, DROP) # 字段x的值大于100或者字段y的值小于100
    • 使用日志服务提供的逻辑运算函数
      场景操作 函数 示例
      逻辑且and op_and op_and(op_gt(v("age"), 18), op_lt(v("age"), 31))
      逻辑或or op_or op_or(op_le(v("age"), 18), op_gt(v("age"), 65))
      逻辑否not op_not op_not(op_gt(v("age"), 18))
  • 其他操作符

    由于SLS DSL标准模式下不直接支持以下操作符。日志服务提供对应的函数来实现相同的效果。
    场景操作 函数 示例
    + op_add op_add(v("age"), 2)
    - op_sub op_sub(v("age"), 2)
    * op_mul op_mul(v("size"), 2)
    ** op_pow op_pow(v("size"), 2)
    整除// op_div_floor op_div_floor(v("bytes"), 1024)
    取模% op_mod op_mod(v("age"), 10)
    取负- op_neg op_neg(v("profit"))
    判断存在in op_in op_in(["pass", "ok"], v("result"))
    判断不存在not in op_not_in op_not_in(["pass", "ok"], v("result"))
    字符串切片[ ...] op_slice op_slice(v("message"), 0, 20)
    例如设置字段a的值为3600*6
    # * 
    e_set("a", 3600 * 6)           #非法
    e_set("a", op_mul(3600, 6))    #合法
    
    # /
    e_set("bytes_kb", v("bytes") / 1024)                 #非法
    e_set("bytes_kb", op_div_floor(v("bytes"), 1024))    #合法

真假判断

有些函数会接收条件,根据条件的值来决定事件的逻辑。条件可以是一个固定值或者表达式返回的值。

SLS DSL支持对任意类型值进行判断,如下表格是各种类型值的真假条件。
数据类型 True的条件 False的条件
布尔 True,true False,false
None 总是False
数值 非0或非0.0 0或0.0
字符串 非空 空串
字节 非空 空字节
元组 非空 空元组
列表 非空 空列表
字典 非空 空字典
表格 存在即为True 空对象(None)
日期时间 存在即为True 空对象(None)
如下为丢弃事件示例:
e_if(True, DROP)                     #输入True时,丢弃。
e_if(1, DROP)                        #输入1时,丢弃。
e_if(v("abc"), DROP)                 #存在字段abc且字段不为空时,丢弃。
e_if(str_isdigit(v("abc")), DROP)    #存在字段abc且字段的内容都是数字时,丢弃。