日志服务数据加工:错误排查指南

  1. 云栖社区>
  2. 阿里云存储服务>
  3. 博客>
  4. 正文

日志服务数据加工:错误排查指南

成喆 2019-08-06 21:34:14 浏览7572

通用错误排查步骤

数据加工任务启动后,加工结果根据路由规则发送到对应的Logstore。如果加工任务失败, 目标logstore没有日志产生或者加工延迟过大等异常,可以通过如下方式排查:

1) 确认目标logstore是否有写入

检查目标logstore最近是否有日志写入. 正确的方法是如下操作目标Logstore的写入预览:
image
image

注意
通过logstore的查询的方式可能并不准确, 因为:

  • 数据加工是基于日志接收时间进行加工, 可能正在加工历史日志, 当前查询的时间范围与日志的写入时间并不一定一致.
  • 日志服务在写入历史日志时的索引到可以查询有需要一定延迟(通常几分钟). 数据加工如果正在写入历史日志, 那么查询界面立刻查询可能查询不到.

2) 查看加工任务状态

  1. 查看当前任务的进度, 尤其是是否已经启动, 参考 任务管理。对于时间区间固定的任务,加工到结束位置之后会自动结束。
  2. 查看对应任务的消费组, 检查其是否状态是否开启并有所更新.
    image

image

  1. 参考错误日志查看方式, 查看是否有异常发生. 在参考错误排查进一步找到原因并解决.

3) 查看源logstore是否有数据产生

通过查看加工任务, 确认当前加工任务的时间范围内, 源logstore是否存在日志.

  • 如果是时间配置没有设置结束时间, 检查源Logstore是否有新日志产生,如果没有新日志产生, 且特定时间范围内没有日志且没有历史日志存在,加工无法进行。
  • 如果选择的是历史时间, 确认历史特定时间范围内, 源logstore是否有日志.

正确的检查方法如下:
点击加工任务的修改规则, 选择对应的时间范围来查看是否有原始日志.

4) 查看加工规则是否异常

检查加工规则代码中是否存在异常, 例如:

  1. 修改了日志的时间,导致在当前时间范围内查询不到。
  2. 或者加工规则在特定条件下丢弃了日志.

例如如下代码会丢弃所有字段name不存在或者为空的日志, 而前置逻辑中是构建字段name, 如果前置逻辑存在问题, 导致字段name没有正确构建的话, 所有日志都不会产出.

# ....前置逻辑.
#  .... 构建字段name...

e_keep(e_search('name: "?"'))
  1. 如果存在从第三方拉取数据做富化的逻辑, 需要确认是否第三方的数据过大, 数据加工任务正在处于初始化状态, 导致迟迟未能开始消费数据.

例如如下:

e_dict_map(res_rds_mysql(..database="userinfo", table="user"), "username", ["city", "school", "age"])

正确的检查方法如下:
点击加工任务的修改规则, 选择对应的时间范围, 并点击预览来查看结果.

如果能够重现, 可以通过注释掉特定语句重试预览来调试.

5) 确认shard数量是否符合预期

如果发现加工速度过慢, 可以考虑是否源logstore与目标logstore的规划不符合性能预期, 建议参考性能优化指南来增加源logstore或目标logstore的shard数量.

错误日志查看方式

错误日志可以在如下几个地方查询:

1)在Logstore internal-etl-log

加工任务产生的日志会存储在internal-etl-log 这个Logstore中(该Logstore在执行数据加工任务后由系统自动生成)

  • internal-etl-log属于专属logstore, 不会收取任何费用, 用户无法修改其配置, 也无法写入其他数据,
  • 该Logstore在执行数据加工任务后由系统自动生成.
  • internal-etl-log中每个日志事件的__topic__字段显示了加工任务的状态,可通过该字段判断对应的加工任务是否产生了错误。
  • 具体的错误信息在每一个日志事件的messagereason字段查看,如下图所示
    image

2)在数据加工诊断仪表盘的异常详情处

3)预览阶段错误日志会直接显示在控制台

  • 预览阶段只是模拟加工规则的操作,以及预览预期的加工结果,并不会真的对源logstore和目标logstore进行修改,因此预览阶段遇到的各类错误都不会对源日志事件产生影响(不会丢弃、修改日志等)。

预览限制

预览阶段的数据加工相较于真实的ETL加工任务而言,存在一些限制:

1)不能发现源logstore秘钥权限的部分缺失

  • 预览阶段不会创建消费组进行消费,因此消费组权限没有进行检查。

2)不能发现加工规则中输出目标的名称错误

  • 预览阶段不会对写入目标做真正的写入操作,因此不会检查配置项中是否配置了相关的输出目标。

3)不能发现输出目标的配置错误

  • 这里的配置错误包含输出目标的 project/logstore/秘钥权限等信息配置错误。
  • 因为预览阶段不会对写入目标做真正的写入操作,因此不会检查输出目标的配置信息是否正确。

4)不能完整覆盖所有数据

  • 预览阶段默认只从源logstore中拉取1000条数据进行加工,不会覆盖所有数据。
  • 如果拉取的1000条数据在加工后没有加工结果产生(数据都被加工规则过滤掉了),则会持续拉取数据五分钟,直到有加工结果产生为止。

错误排查

概述

当发生错误时, 分析错误产生在数据加工任务的哪个环节,能帮助用户更高效地定位错误位置。

根据数据加工原理, 数据加工任务的主要四个环节如下图所示
image
以上四个环节的每一个环节都有可能产生错误,其原因、影响和排查方式各不相同。

启动加工引擎

  • 该环节产生错误主要是由于在启动加工引擎过程, 检测到用户编写的LOG DSL规则存在错误,导致加工引擎内部的安全检查(security check)不通过。
  • 在该阶段产生错误时,加工任务会一直重试,直到被手动停止或重试成功。如果重试成功(修改为正确的加工规则),加工任务会继续正常工作,不会产生日志的丢失或冗余(重复)。
  • 该环节的错误排查指南参考加工引擎启动错误排查指南

读取源logstore数据

  • 该环节产生的错误主要是由于对源logstore的访问异常。访问异常的原因可能是源logstore信息配置错误、网络错误、源logstore信息发生变化等。
  • 在该阶段产生错误时,加工任务会一直重试,直到被手动停止或重试成功。如果重试成功,加工任务会继续正常工作,不会产生日志的丢失。
  • 如果是已经读取部分数据后才报错,会保存断点并一直重试,重试成功后,从断点处继续读取,不会有数据的丢失与重复. 如果重试过程中停止, 不会有数据丢失与重复.
  • 该环节的错误排查指南参考源logstore日志数据读取错误排查指南

加工日志事件

  • 该环节产生错误主要是由于在数据加工过程中, 部分(也可能是全部)日志事件不适配加工规则,从而引发的错误。
  • 在该阶段产生错误时,不适配加工规则的日志事件会丢弃(跳过),加工后的输出结果中将不包含这些日志事件。
  • 该环节的错误排查指南参考日志事件加工错误排查指南

输出到目标logstore(s)

  • 该环节产生错误主要是由于对目标logstore的访问异常。访问异常的原因可能是由于目标logstore信息配置错误、网络错误、目标logstore信息发生变化等原因。
  • 在该阶段产生错误时,加工任务会一直重试,直到被手动停止或重试成功。如果重试成功,加工任务会继续正常工作,不会产生日志的丢失。
  • 如果是已经输出部分数据后才报错(例如配置了多个目标, 一个目标成功, 另外一个目标失败),会保存断点并一直重试,重试成功后,不会有数据的丢失与冗余. 但如果这时停止加工任务, 再重启加工时, 会从断点继续, 不会有数据丢失, 但可能会有数据的冗余(重复输出)。
  • 该环节的错误排查指南参考目标logstore输出错误排查指南

加工引擎启动错误排查指南

数据加工任务的第一个环节便是启动加工引擎。该环节产生错误主要是由于在启动加工引擎过程, 检测到用户编写的LOG DSL规则存在错误,导致加工引擎内部的security check不通过。
image

错误日志

在加工引擎启动过程中,如果检测到用户编写的LOG DSL规则存在错误,会报如下形式的错误:

{
  "errorMessage": "ETL config doesn't pass security check, detail: XXXXXX"
}
  • 错误日志可以在数据加工诊断报表的异常详情中或者Logstore: internal-etl-log中查看。

错误影响

  • 在加工引擎启动阶段产生错误时,加工任务会一直重试,直到被手动停止或重试成功。
  • 重试成功后(修正加工规则后),加工任务会继续正常工作,不会产生日志的丢失或冗余(重复)。

常见错误排查

1. LOG DSL基本语法错误

用户编写LOG DSL规则过程中,可能会因为粗心,错写了不符合LOG DSL语法的加工规则,如多或者少括号,逗号写成冒号等。

错误日志

{
  "errorMessage": "ETL config doesn't pass security check, detail: invalid syntax"
}
{
  "errorMessage": "ETL config doesn't pass security check, detail: unexpected EOF while parsing"
}
...

错误排查方法

  • 可根据错误日志中的traceback信息定位具体的语法错误位置。

  • 如下图所示,根据错误日志中的traceback信息可以看到这里的LOG DSL语法错误是将e_set("test", v("status"))错写为了e_set("test": v("status"))
    1.jpg

2. 非法使用运算符

LOG DSL中所有的操作都需要通过LOG DSL提供的函数来完成。数值运算、大小比较等操作都需要通过op_类的函数来完成,而不能直接使用+ - * / > <等运算符。

错误日志

{
  "errorMessage": "ETL config doesn't pass security check, detail: invalid type detected: <class `_ast.BinOp`> "
}

错误排查方法

  • 检查LOG DSL规则,确保所有的操作(运算、大小比较等)都使用了LOG DSL提供的函数来完成,没有使用LOG DSL提供的功能以外的非法运算符。

错误及解决样例

e_set("b", v("a") - 10) # 错误
e_set("b", op_sub(v("a"), 10)) # 正确

e_set("b", v("a") >= v("c")) # 错误
e_set("b", op_ge(v("a"), v("c"))) # 正确

3. 函数参数类型传递错误

如果传递给函数的参数类型和函数接收的参数类型不一致,会产生错误。

错误日志

{
  "errorMessage": "ETL config doesn't pass security check, detail: invalid call in detected: function_name"
}

错误排查方法

  • 可根据错误日志中的traceback信息定位产生错误的函数。

  • 如下图所示,根据错误日志中的traceback信息可以看到这里的产生错误的函数是dt_totimestap。于是可以去检查规则中的调用dt_totimestap的地方,看是否传递了正确类型的参数给该函数。
    2.jpg

错误及解决样例

#错误样例
e_set("time1", "2019-06-03 2:41:26")
e_set("time2", dt_totimestap(v("time1")))

#正确样例
e_set("time1", "2019-06-03 2:41:26")
e_set("time2", dt_totimestap(dt_parse(v("time1"))))

#正确样例
e_set("time1", "2019-06-03 2:41:26")
e_set("time2", dt_parsetimestamp(v("time1")))
  • dt_totimestap接收的参数类型是日期时间对象,此处v("time1")是字符串类型,因此此处传递了错误类型的参数给日期时间函数,引发报错。
  • 可以使用dt_parse函数来将字符串转化为日期时间对象,再传递给dt_totimestamp。也可以使用dt_parsetimestap函数来代替dt_totimestamp, 该函数可以接收字符串类型。

4. 非法使用变量定义赋值

LOG DSL语法中不支持变量定义赋值,变量值只能通过无状态方式调用传递。

错误日志

{
  "errorMessage": "ETL config doesn't pass security check, detail: invalid assign detected: variable_name"
}

错误排查方法

  • 检查LOG DSL规则中是否使用了变量定义赋值。
  • 可根据错误日志中的traceback信息定位产生错误的位置。

错误及解决样例

#错误样例
sum_value = op_add(v("a"), v("b"))
e_set("sum", sum_value)

#正确样例
e_set("sum", op_add(v("a"), v("b")))
  • 变量值只能通过无状态方式调用传递。

源Logstore读取错误排查指南

在加工引擎成功启动后,下一步是读取源Logstore的数据。数据加工引擎对源日志库采用流式读取,在加工过程中会持续不断的读取源logstore中的数据。
image

这个环节产生错误主要是由于对源logstore的访问异常。源Logstore访问异常的原因可能是:

  • 源logstore信息配置错误
  • 源logstore信息发生变化
  • 网络错误
  • ...

错误影响

  • 在读取源Logstore产生错误时,加工任务会一直重试,直到被手动停止或重试成功。重试成功后,加工任务会继续正常工作。
  • 加工任务会保存之前成功的断点并一直重试。重试成功后,从断点处继续读取,不会产生数据的丢失和冗余。

常见错误排查

1. 为源logstore配置了非法的AccessKey

错误日志

非法的AccessKey主要分为两种:非法的AccessKeyId非法的AccessKeySecret

#非法的AccessKeyId
{
  "errorCode": "Unauthorized", 
  "errorMessage": "AccessKeyId not found: LTAIL3gUus8AEu11"
}
#非法的AccessKeySecret
{ 
  "errorCode": "SignatureNotMatch", 
  "errorMessage": "signature uJfAJbc0ji04gb+cXhh0qWtajpM= not match"
}

错误排查方法

  • 检查任务配置项中,源Logstore的AccessKeyIDAccessKeySecret是否存在、正确。

2. 源logstore信息发生变化

错误分析

  • 用户配置了正确的源logstore信息,可能也已经进行了部分加工任务,但是在数据加工的过程中,源logstore信息发生了变化,导致原有的配置信息无法访问源logstore。

错误日志

源logstore信息发生变化有主要是如下2种情况:

  • 源logstore被删除
{
  "errorMessage": "Logstore [logstore_name] does not exist."
}
  • 源logstore AccessKey信息发生变化
#非法的AccessKeyId
{
  "errorCode": "Unauthorized", 
  "errorMessage": "AccessKeyId not found: LTAIL3gUus8AEu11"
}
#非法的AccessKeySecret
{ 
  "errorCode": "SignatureNotMatch", 
  "errorMessage": "signature uJfAJbc0ji04gb+cXhh0qWtajpM= not match"
}

错误排查方法

  • 检查源Logstore是否被删除。
  • 检查源Logstore的AccessKey信息是否发生改变。

3. 网络错误

错误日志

{
  "errorCode": "LogRequestError",
  "errorMessage": "HTTPConnectionPool(host='your_host', port=80): Max retries exceeded with url: your_url (Caused by NewConnectionError: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'"
}

错误排查方法

  • 检查网络连接是否正常。

4. 读取不到源Logstore数据

此条不属于错误,没有报错信息。

规则错误排查指南

在成功读取源Logstore数据后,加工引擎开始对源Logstore的日志事件进行加工。
image

  • 该环节产生错误主要是由于在数据加工过程中, 部分(也可能是全部)日志事件不适配加工规则,从而引发的逻辑错误。
  • 除了逻辑错误之外,如果加工规则中涉及RDS、Logstore等外联资源的加载,则也有可能会产生资源的加载或刷新错误。

错误影响

  • 在日志事件加工阶段,与加工规则冲突的日志事件会引发报错,并被丢弃(跳过),加工后的输出结果中将不包含这些日志事件。
  • 加工任务会丢弃(跳过)与加工规则冲突的日志事件,并继续加工其他的日志事件,不会重试。
  • 需要注意的是,如果多条事件分裂自同一条事件(参考 事件分裂),只要其中有一条事件出错被丢弃,所有和该事件分裂自同一条源事件的其他事件也都会被丢弃。(在输出之前,这些事件都是以树结构互相关联,并不是互相独立的)

错误排查方法

  • 查看错误日志的messgae字段,定位是哪些日志事件报错。参考错误日志查看方式
  • 查看错误日志的reason字段,确定这些日志事件的报错原因。
  • 根据报错原因,为这些异常日志事件增添逻辑(可使用e_if, e_switch等流程控制函数),捕获并处理这些错误。
    111.png

常见逻辑错误样例

1. 日志事件中存在异常值

加工规则样例1

#部分日志事件字段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")))

加工规则样例2

#部分日志事件的字段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"))

2. 数值运算前未进行数据类型转换

加工规则样例

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规则,是否在做数值运算前未进行数据类型转换。(字符串转数值型等)

错误解决方案

e_set("a", 10)
e_set("b", 10)
e_set("c", op_mul(c_int(v("a")), c_int(v("b"))))
  • 使用ct_int函数进行数据类型转换,将字符串型转化为整型后,再传递给op_mul函数。

目标logstore输出错误排查指南

日志事件被加工完之后,会被输出到预先配置好的目标logstore中去。需要注意的是,LOG DSL引擎并不是加工一条日志就输出一条,而是会先将加工好的数据存放在一个缓存池中,等缓存池中的数据达到一定的量,再一并输出。
image

该环节产生错误主要是由于对目标logstore的访问异常。目标logstore访问异常的原因可能是:

  • 目标logstore信息配置错误
  • 目标logstore信息发生变化
  • 网络错误
  • ...

错误影响

  • 在输出到目标logstore阶段产生错误时,加工任务会一直重试,直到被手动停止或重试成功。如果重试成功,加工任务会继续正常工作,不会产生日志的丢失和冗余。
  • 如果是已经输出部分数据后才报错(例如配置了多个目标, 一个目标成功, 另外一个目标失败),会保存断点并一直重试,重试成功后,不会有数据的丢失与冗余. 如果这时停止加工任务, 再重启加工时, 会从断点继续, 不会有数据丢失, 但可能会有数据的冗余(重复输出)。

常见错误排查

1. 为目标logstore配置了非法的AccessKey

错误日志

非法的AccessKey主要分为两种:非法的AccessKeyId非法的AccessKeySecret

#非法的AccessKeyId
{
  "errorCode": "Unauthorized", 
  "errorMessage": "AccessKeyId not found: LTAIL3gUus8AEu11"
}
#非法的AccessKeySecret
{ 
  "errorCode": "SignatureNotMatch", 
  "errorMessage": "signature uJfAJbc0ji04gb+cXhh0qWtajpM= not match"
}

错误排查方法

  • 检查任务配置项,查看对应的目标Logstore的AccessKeyIDAccessKeySecret是否存在、正确。

2. 目标Project不存在

错误日志

{
  "errorCode": "ProjectNotExist", 
  "errorMessage": "The Project does not exist : your_project_name"
}

错误原因分析

错误日志提示 Project does not exist有三种可能的原因:

  • 任务配置项中的目标Project名称输入错误。
  • 目标Project名称输入正确,但是在加工任务过程中,对应的project被删除。
  • 目标Project和当前的Project不在同一地域内。

    • 目前LOG DSL只支持同一地域内的不同Project之间的数据传输,不支持不同地域下的Project之间的数据传输。

错误排查方法

  • 检查任务配置项中的目标Project名称是否输入有误。
  • 检查目标Project是否被删除。
  • 检查目标Project和当前Project是否在同一地域内。目前不支持不同地域下的Project之间的数据传输。

3. 输出目标不存在

加工规则样例

e_coutput("target1")

错误日志

{
  "errorMessage": "transform_data: output target target1 is not found in configurations"
}

错误原因分析

上述LOG DSL规则将日志事件输出到target1中,而错误日志提示 target1 is not found in configurations。说明该LOG DSL规则的配置中并没有定义和target1关联的目标project和logstore。

错误排查方法

  • 检查LOG DSL规则的配置项,确保配置项中定义了加工规则中涉及到的所有存储目标。

4. 目标logstore信息发生变化

错误分析

  • 用户配置了正确的目标ogstore信息,可能也已经进行了部分加工任务,但是在数据加工的过程中,目标logstore信息发生了变化,导致原有的配置信息无法访问目标logstore。

错误日志

目标logstore信息发生变化有主要是如下2种情况:

  • 目标logstore被删除
{
  "errorMessage": "Logstore [logstore_name] does not exist."
}
  • 目标logstore AccessKey信息发生变化
#非法的AccessKeyId
{
  "errorCode": "Unauthorized", 
  "errorMessage": "AccessKeyId not found: LTAIL3gUus8AEu11"
}
#非法的AccessKeySecret
{ 
  "errorCode": "SignatureNotMatch", 
  "errorMessage": "signature uJfAJbc0ji04gb+cXhh0qWtajpM= not match"
}

错误排查方法

  • 检查目标Logstore是否被删除。
  • 检查目标Logstore的AccessKey信息是否发生改变。

5. 网络错误

错误日志

{
  "errorCode": "LogRequestError",
  "errorMessage": "HTTPConnectionPool(host='your_host', port=80): Max retries exceeded with url: your_url (Caused by NewConnectionError: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'"
}

错误排查方法

  • 检查网络连接是否正常。

进一步参考

欢迎扫码加入官方钉钉群获得实时更新与阿里云工程师的及时直接的支持:
image