Fork me on GitHub

数据加工

日志服务中数据加工模块的学习

日志服务-数据加工

定义

数据加工功能是一个托管的、高可用、可拓展的数据加工服务,主要的应用场景是

  • 数据的规整、富化
  • 分发、汇总
  • 重建索引等

3个步骤

数据加工功能通过3个步骤来完成对日志数据的加工处理:

  1. 通过协同消费组对源日志库的日志数据进行读取消费
  2. 通过编写加工规则对读取的每一条日志进行处理
  3. 通过设置目标Logstore将加工后的日志数据输出到指定的目标日志库中

笔记:数据加工功能支持的区域:支持除了华北1(青岛)以外的所有区域

基本概念

  1. ETL(Extract, Transform, Load)

    ETL是数据分析领域中对数据进行加载、转换、输出,主要是对数据进行数据转换

  2. 事件、数据、日志

    在数据加工过程中,事件、数据等都是日志,例如事件时间就是日志等

  3. 源Logstore

    数据加工中,从中读取数据再进行加工的Logstore是源Logstore;一个加工任务仅支持一个源Logstore;但是一个源Logstore可以对应多个任务

  4. 目标Logstore

    数据加工中,数据写入的Logstore是目标Logstore

  5. 加工规则

    数据加工脚本,日志服务DSL编排的逻辑代码的集合

  6. LOG DSL

    日志服务专用语言,LOG specific language,是日志服务数据加工中使用的一种Python兼容的脚本语言。

  7. 维表
    用于做富化的数据的某些维度信息的外部数表格叫做维表,例如公司用户账户列表、产品列表、地理位置信息库等

  8. 富化/映射

    日志包含的信息不完整时,需要借助外部信息进行完善,对日志的一个或多个字段通过映射完善出更多信息的过程叫做富化或者映射。

  9. 分裂

    日志信息比较复杂,同时包含多条信息时,将一条日志分裂成多条日志的过程叫做分裂。

使用场景

数据规整

数据规整(一对一),从一个Logstore中读取日志数据,加工之后再输出到另一个Logstore中

数据分派

数据分派(一对多),从一个Logstore中读取日志,进行加工后再分别输出到不同的Logstore中

多源汇集

多源汇集(多对一),分别从不同的Logstore中读取日志数据,进行加工后再输出到一个指定的Logstore中

常规加工

全面覆盖数据加工的典型模式,包括过滤、分裂、转换、富化

  • 过滤(filter):将指定的日志过滤掉。
  • 分裂(split):将一条日志分裂成多条。
  • 转换(transform):字段操作、内容转换等。
  • 富化(enrich):关联外部资源,丰富字段信息等。

加工原理

​ 日志服务提供的数据加工功能,通过编排内置的两百多个函数,使用协同消费组对日志数据进行消费,实现对日志数据的加工处理。

调度原理

​ 数据加工功能使用协同消费组对源日志库的日志数据进行流式消费,将每条日志通过加工规则处理后再输出。

源日志—>消费组—>目标日志

  • 调度机制:调度启动一个或者多个实例,每个实例扮演一个角色去消费一个或者多个Logstore的shard
  • 运行实例:根据用户配置从分配的Shard中读取源日志数据,经过加工规则处理后再输出到目标Logstore
  • 任务停止:
    • 当用户没有配置任务的终点时间时,运行实例默认不会退出,则加工任务不会停止。
    • 当用户配置了任务的终点时间时,运行实例处理到配置的终点时间所接收的日志后会自动退出,加工任务停止。
    • 当任务因为某些原因被停止,再次启动时,默认会从上次保存的消费位置继续消费。

规则引擎原理

基础操作

4个函数定义4个步骤。规则中定义的每个事件函数会顺序执行,每一个函数会对每个事件处理和修改,返回一个处理后的事件。

  • 设置字段信息
  • 步骤设置条件,不满足条件的时间会跳过本次操作
1
2
3
4
e_set("log_type", "access_log")
e_drop_fields("__action")
e_if(e_search("ret: pass"), e_set("result", "pass"))
e_if(e_search("ret: unknown"), DROP)

输出、复制、分裂
1
2
3
4
e_coutput("archive_Logstore") )
e_split("log_type")
e_if(e_search("log_type: alert"), e_output("alert_Logstore") )
e_set("result", "pass")
  • 输出事件:特殊的停止处理。若提前输出事件到指定目标并删除该事件,后续操作停止
  • 复制输出事件:复制当前事件进行输出,原事件会继续处理
  • 分裂并行:步骤2中的两条事件除字段值不同之外,其余完全相同;分裂后的每条事件会对后续事件进行处理

创建加工规则

4大步骤

  • 登录日志服务控制台,单击Project名称
  • 进入加工模式:单击加工后的加号+
  • 编写加工规则

加工规则demo

1
2
3
4
5
6
7
# e_kv表示通过quote等自动提取多个源字段中的键值对信息
# e_if是条件与操作的配对组合,根据条件判断,满足条件的依次进行相应操作
# e_search函数使用查询字符串判断事件的字段值是否满足特定条件,返回True或False

e_kv("http_host")
e_if(e_search("status==200"),e_compose(e_set("__topic__","login_success_event"),e_output(name="200-target", project="project1", logstore="200_log"))) # e_set函数的作用是更新事件字段的值;e_set("province","上海") 日志内容中会增加province字段
e_if(e_search("status==400"),e_compose(e_set("__topic__","login_fail_event"),e_output(name="400-target", project="project1", logstore="400_log")))
  1. 设置查询的时间范围
  2. 在编辑框内编辑加工规则
  3. 单击数据预览,查看加工结果;首次预览,需要输入AccessKey鉴权

img

  • 保存加工结果

img

加工配置项

配置项 说明
规则名称 保存加工任务的规则名称。
AccessKey 对当前Logstore原始数据进行数据加工的AccessKey。
AccessKey Secret 对当前Logstore原始数据进行数据加工的AccessKey Secret。
目标名称 存储目标的逻辑名称。
目标Project 加工结果存储的目标Project名称,目前只支持相同地域的Project。
目标Logstore 加工结果存储的目标Logstore名称。
AccessKey 用于将加工结果写入目标Logstore的AccessKey。
AccessKey Secret 用于将加工结果写入目标Logstore的AccessKey Secret。
时间范围(日志接收时间为准) 加工范围3种类型:
1. 所有:对Logstore中的数据从开始位置持续加工,直到加工任务被手动停止。
2.某时间开始:指定开始时间点,从该时间点对应的位置开始加工,直到加工任务被手动停止。
3.特定时间范围:指定任务的起止时间,加工任务执行到指定时间后自动停止。
高级参数配置 对于加工规则代码中需要使用的密码信息,如数据库连接密码等,可以使用Key-Value的形式保存在密钥对中,在代码中通过变量引用${key}的方式进行使用。

数据加工完整过程

数据加工语法

日志服务语言LOG DSL(Domain Specific Language)是日志服务数据加工使用的与Python兼容的脚本。

LOG DSL基于Python提供两百多个内置函数来简化数据加工模式。

特点

  1. 自由编排:对各种逻辑进行复杂组合,满足大部分的加工场景需求

自由编排

  1. 动态分发:将数据按照特定的逻辑分发到不同的目标Logstore

  2. 灵活富化

    • 支持从本地资源或外部资源(包括OSS、RDS、日志服务Logstore)来获取富化数据。

    • 支持字典、表格的常规映射,搜索表格的高级映射。

    • 外部资源加载支持自动刷新。

  3. 函数多样化

    • 控制函数
      • 支持基于条件判断后的流程分支,包括if-elseifswitchcompose等。
      • 通过调用e_search等简单搜索函数对不同类型的日志进行灵活加工。
    • 事件操作函数
    • 字段操作函数
    • 字段赋值函数
    • 字段值提取函数
    • 映射富化函数
    • 表达式函数
      • 事件搜索
      • 基本操作函数
      • 转换函数
      • 算术函数
      • 字符串函数
      • 日期时间函数

数据结构

基本数据结构
类型 说明
整数 如1、2、3、4等,用于设置字段值或者函数的参数传递。例如:e_set("f1", 100)赋值字段f1的值为100。
浮点 如1.5、2.3等,用于设置字段值或者函数的参数传递。例如:e_set("f1", 1.5)赋值字段f1的值为1.5。
字符串(String) 字符串形式较多,例如:"abc"'abc' 相同。当字符串中包含"时,可以使用'abc"xyz'。使用\进行反转"abc\"xyz"也可以,但是相对繁琐一些。
\表示反转,所以"\\abc\\xyz"表示\abc\xyzr"\\10.64.1.1\share\folder""\\\\10.64.1.1\\share\\folder"相同,都是表示字符串\\10.64.1.1\share\folder
多字节字符串以unicode表示,例如中文的长度是2。正则表达式也是以字符串形式表示。说明 函数e_search接收的搜索字符串里面的字符串用双引号括起来,不支持单引号。e_search("domain: '/url/test.jsp'")是错误的,正确的是e_search('domain: "/url/test.jsp"')
字节 b'abc'不同于字符串的内存编码形式,作为某些特殊函数的接收或者返回类型。
Nonenull表示无。许多函数的命名参数的默认值是None,表示特定的默认行为。说明 空字符串与None和null的数据类型不同。
列表(List) 也称数组如[1,2,3,4]。某些函数参数接收的是列表,例如:e_dict_map("dict data", ["f1", "f2", "f3"], ...)。某些函数返回结果的是列表,例如当json_select选择了一个数组时会返回列表。
元组(tuple) 如(1,2,3,4)。和列表功能一样,某些函数参数接收的是元组。
字典(Dict) 形式为{"key": "value", "k2": "v2", ...}的键值对组合。关键字一般是字符串且不能重复,值可以是以上的各种类型。以哈希方式存储, 查找时无序。
事件是一种特殊的字典。某些函数接收特定格式的字典。例如{"key": [1,2, 3], "ke": {"k3": "va3"} }。字典结构也应用于字典映射的输入数据。
布尔(Bool) TrueFalsetruefalse
表格 多列的表格结构,可以从外部资源中加载多行CSV格式内容构建,或者从RDS,Logstore中加载多列数据获取。
主要用于映射富化或其他高级配置场景。
日期时间对象 表示日期时间的内存对象,可以转换为Unix字符串或者格式化的时间字符串,或者传递给其他dt_类函数进行进一步转换。
事件类型

基本类型:数据加工将日志以字典结构进行处理

元字段:__time__、__topic__、__source__

标签:__tag__,日志存在标记,用于区分字段

固定标示
标示 类型 说明
true Bool 真,等价于True
false Bool 假,等价于False
null None 无,等价于None
F_TAGS 字符串 TAG字段正则表达式,等价于"__tag__:.+"
F_META 字符串 TAG__topic____source__字段的正则表达式表示,等价于__tag__:.+|__topic__|__source__
F_TIME 字符串 __time__字段的名称,等价于__time__
F_PACK_META 字符串 pack meta字段的正则表达式表示形式,等价于"__pack_meta__|__tag__:__pack_id__"
F_RECEIVE_TIME 字符串 服务器接收日志的时间的tag字段,等价于"__tag__:__receive_time__"
JSON对象

一般指JSON表达式函数json_select或者json_parse解析提取后的对象,实际是基本数据结构的形式

语法

  1. 注释:以#开头
  2. 换行:在逗号,或者使用\进行换行
  3. 操作符:LOG 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_in(["pass", "ok"], v("result"))
逻辑且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))
判断等于== 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)
字符串切片[ ...] op_slice op_slice(v("message"), 0, 20)
  1. 真假判断:LOG DSL的条件判断支持对任意类型值进行判断
数据类型 True的条件 False的条件
布尔 True,true False,false
None - 总是False
数值 非0或非0.0 0或0.0
字符串 非空 空串
字节 非空 空字节
元组 非空 空元组
列表 非空 空列表
字典 非空 空字典
表格 存在即为True 空对象(None)
日期时间 存在即为True 空对象(None)

函数

主要是包含全局操作函数表达式函数

全局操作函数

全局操作函数可以分为两类:

函数分类 描述 样例
流程控制函数 用于步骤流程控制,接收事件,基于条件控制调用其他事件函数完成事件处理。 e_ife_switche_if_else等。
事件处理函数 对事件进行加工的函数 。返回0到多条事件。 函数样例如下:e_drop_fields丢弃事件字段。e_kv提取并添加事件的键值对。e_dict_map给事件做富化。

表达式函数

表达式函数大概可以分为四类:

函数分类 描述 样例
事件检查函数 接收事件,提取或检索返回特定信息的函数,不会修改传递的事件。 函数v返回事件字段的值。函数e_searche_match返回事件是否符合特定的条件。
资源函数 连接本地或外部资源,接收特定参数配置并返回数据,一般是字典、表格等类型。 OSS、RDS、Logstore资源函数。
控制函数 用于表达式的逻辑操作,接收特定参数并基于条件做控制,调用其他表达式函数返回结果。 op_andop_orop_notop_ifop_coalesce等。
其他表达式函数 接受固定或者其他函数的调用结果,返回特定的值。 字符串、时间、类型转换函数等。

功能对比

函数类型 全局步骤 接收 返回 修改事件 组合调用
全局操作函数 支持 自动接收事件 0到多条事件 支持大部分情况 支持
表达式函数 不支持 除个别函数支持,大部分不直接处理事件。 特定数据结构 不支持 支持

日期时间格式化指令

ANSI C标准规定了解析或者格式化日期时间字符串的指令。

指令 含义 示例 注释
%a 工作日的缩写。 Sun,...,Mon 当前以en-US为展示,暂不支持其他locale。
%A 工作日的全拼。 Sunday,...,Monday 当前以en-US为展示,暂不支持其他locale。
%w 以十进制数显示的工作日,其中0表示星期日,6表示星期六 0,1,2,3,4,5,6
%d 补0后,以十进制数显示月份中的一天。 01,02,...,31 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%b 本地月份的缩 Jan,Feb,...,Dec 当前以en-US为展示,暂不支持其他locale。
%B 本地月份的全拼。 January,February,..., December 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%m 补0后,以十进制数显示的月份。 01,02,...,12 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%y 补0后,以十进制数表示的不带世纪的年份。 00,01,...,99 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%Y 十进制数表示的带世纪的年份。 0001,0002,...,2013,2014,...,9998,9999 解析年时,范围是[1,9999],如果年小于1000,必须用0填充为4位数。例如0180表示公元180年。
%H 24小时制,由0填充的十进制。 00,01,...,23 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%I 12小时制,由0填充的十进制。 01,02,...,12 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%p 本地化的AM或PM。 AM,PM 当前以en-US为展示,暂不支持其他locale。解析时,%p仅影响%I小时部分。
%M 补0后,以十进制数显示的分钟。 00,01,...,59 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%S 补0后,以十进制数显示的秒。 00,01,...,59 不支持闰秒。解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%f 微秒,由0填充的十进制。 000000,000001,..., 999999 当用于解析微秒时, %f可以接受0-6个字符的数字串。
%z UTC偏移形式:±HHMM[SS[.ffffff]]。日期时间不含时区时为空串。 (empty),+0000,-0400,+1030,+063415,-030712.345216 不包含时区的日期时间对象, %z%Z会被替换为空串。%z格式化为±HHMM[SS[.ffffff]]时,并不要求必须提供分钟。解析时支持分号分隔的字符串,+01:00:00,另外Z等于+00:00
%Z 时区名。日期缺少时区时为空串。 (empty),UTC,EST,CST
%j 每年的第几天 001,002,...,366 解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%U 每年的第几周,星期天是每周第一天。一年中第一个星期天前的日子都被视为week 0。 00,01,...,53 解析时,%U%W仅用于计算。解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%W 每年的第几周,星期一是每周第一天。一年中第一个星期一前的日子都被视为week 0。 00,01,...,53 解析时,%U%W仅用于计算。解析时%d、%m、%H、%I、%M、%S、%J、%U、%W、%V、%y不要求开头0补齐。
%c 本地化的日期和时间表示。 Tue Aug 16 21:30:00 1988 当前以en-US为展示,暂不支持其他locale。
%x 本地化的日期表示。 08/16/88 当前以en-US为展示,暂不支持其他locale。
%X 本地化的时间表示。 21:30:00 当前以en-US为展示,暂不支持其他locale。
%% 字面的'%'字符。 %

数据加工仪表盘

总览指标

  • 读日志数总计:从源Logstore各Shard读取到的日志条数总计。
  • 投递日志数总计:从源Logstore各Shard读取日志并成功投递到目标LogStore的日志条数总计。
  • 失败日志数总计:从源Logstore各Shard读取日志并在加工过程中发生失败的日志条数总计。
  • 投递日志数占比:成功投递到目标Logstore的日志条数占源Logstore读取到日志条数的比例。

img

加工速率指标

统计每分钟窗口内,数据加工处理的日志条数,包括四条指标。

  • accept:从源Logstore读到的日志条数。
  • dropped:从源Logstore读到并按代码预期丢弃的日志条数。
  • delivered:从源Logstore读到并成功投递目标Logstore的日志条数。
  • failed:从源Logstore各Shard读取到日志并在加工过程中发生失败的日志条数。

消费延迟与速率指标

统计每分钟窗口内,加工任务读取源Logstore时每个Shard的指标。

  • 消费延迟:当前时间,该Shard最近的已完成日志时间(日志写入日志服务时间)。
  • 消费速率:Shard在该分钟窗口内平均每秒钟读取到的日志条数。

活跃shard指标

展示最近一段时间内发生的,Shard级别每秒处理的日志行数(accept、dropped、delivered、failed)

本文标题:数据加工

发布时间:2020年04月29日 - 10:04

原始链接:http://www.renpeter.cn/2020/04/29/%E6%95%B0%E6%8D%AE%E5%8A%A0%E5%B7%A5.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea