本文档为您介绍数据加工规则错误的原因以及排查处理方法。
读取源LogStore数据成功后,加工引擎开始对源LogStore的日志事件进行加工。
-
该环节产生错误主要是由于在数据加工过程中,全部或者部分日志事件不适配加工规则,从而引发的逻辑错误。
-
如果加工规则中涉及RDS、LogStore等外联资源的加载,则也有可能会产生资源的加载或刷新错误。
本文档主要介绍逻辑错误排查方法,资源加载错误的排查方法请参见资源加载错误。
错误影响
在日志事件加工阶段,与加工规则冲突的日志事件会引发报错,错误分成WARNING和ERROR级别(通过加工日志的logging.levelname体现)。
-
对于ERROR级别的错误, 该日志事件会丢弃。加工后的输出结果中将不包含这些日志事件,并继续加工其他的日志事件,不会重试。
-
对于WARNING级别的错误(例如某些事件与正则规则不匹配),会跳过当前DSL的这一步,进行下一步。
错误排查方法
-
查看错误日志的
logging.levelname字段,确定日志的错误级别。 -
查看错误日志的
message字段,定位是哪些日志事件报错。具体请参见错误日志查看方式。 -
查看错误日志的
reason字段,确定这些日志事件的报错原因。
根据报错原因,为这些异常日志事件增添逻辑,可使用e_if、e_switch等流程控制函数,捕获并处理这些错误。以下为一条错误日志示例,其中 message 字段显示了出错的日志事件详情,reason 字段显示了报错原因 integer division or modulo by zero:
07-26 16:21:48
__source__:
__tag__:__job_name__: etl-preview-1564110081-604324
__tag__:__schedule_type__: DryRun
__topic__: __etl-log-status__
etl_context: {
"project": "ali-licheng-test-uk2",
"logstore": "source_logstore",
"shard_id": "2"}
event_id: transorm_data:process:fail
extra_info_params: {"src_event": {"__time__": "1563266137", "__topic__": "", "__source__": xxx, "__tag__:__client_ip__": xxx,
"__tag__:__receive_time__": "1563774221", "body_bytes_sent": "740", "client_ip": "1.2.3.4", "host": "m.abcd.com", "status": "403"}}
logging: {"process": "34", "levelname": "ERROR", "funcName": "_transform_events_to_logstore", "module": "logclient_operator", "threadName": "MainThread",
"thread": "139890150307648", "processName": "ForkProcess-1"}
message: [ali-licheng-test-uk2/source_logstore/2]transform_data: fail to process event: {"__time__": "1563266137", "__topic__": "", "__source__": xxx,
"__tag__:__client_ip__": xxx, "__tag__:__receive_time__": "1563774221", "body_bytes_sent": "740", "client_ip": "1.2.3.4", "host": "m.abcd.com", "status": "403"},
detail=integer division or modulo by zero
reason: integer division or modulo by zero
常见错误排查
日志事件中存在异常值
除数为0
#部分日志事件字段b的值为0,引发除数为0的错误
e_set("c", op_div_floor(v("a"), v("b")))
-
错误日志:
{ "reason": "error when calling : floordiv\nDetail: integer division or modulo by zero", } -
排查方法:
检查报错的日志事件,确认它们的字段
b的值是否为0。如果是,此处则是由除数为0引发的错误。 -
解决方案:
只有日志事件的字段
b为0时才会报错。因此可以增添e_if逻辑来捕获b的字段值为0的异常情况。e_if_else(op_eq(v("b"), "0"), e_set("c", v("a")), e_set("c", op_div_floor(v("a"), v("b")))
不合法的时间戳格式
#部分日志事件的字段a的值不是合法的时间戳格式,引发报错
e_set("b", dt_fromtimestamp(v("a")))
-
错误日志:
{ "reason": "error when calling : int\nDetail: invalid literal for int() with base 10: '异常值'", } -
排查方法:
检查报错的日志事件,查看字段
a的值是否为合法的时间戳格式(数值型字符串)。 -
解决方案:
增加判断逻辑,如果字段
a的值不是合法的时间戳格式,则将这条日志事件输出到target2中。e_if_else(str_isdigit(v("a"))),e_set("b", dt_fromtimestamp(v("a"))), e_output("target2"))
数值运算前未进行数据类型转换
加工规则样例:
e_set("a", 10)
e_set("b", 10)
e_set("c", op_mul(v("a"), v("b")))
-
错误日志:
{ "reason": "error when calling : mul\nDetail: can't mulltiply sequence by non-int of type' str'", } -
原因分析:
LOG DSL处理过程中,日志事件中的各个字段值都是以字符串形式存储。上述规则样例中,
v("a")和v("b")都是字符串类型,直接传递给op_mul会引发报错。 -
排查方法:
检查LOG DSL规则,是否在做数值计算前未进行数据类型转换。
-
解决方案:
使用
ct_int函数进行数据类型转换,将字符串型转化为整型后,再传递给op_mul函数。e_set("a", 10) e_set("b", 10) e_set("c", op_mul(c_int(v("a")), c_int(v("b"))))