日志服务支持投递日志数据至MaxCompute中进行存储与分析。本文介绍如何创建MaxCompute投递任务(新版)。
前提条件
已创建日志服务Project、Logstore并完成日志采集。具体操作,请参见创建项目Project、创建Logstore和数据采集概述。
已在日志服务Project所在地域创建MaxCompute分区表。更多信息,请参见创建表。
注意事项
目前仅华北2(北京)、华北3(张家口)、华东1(杭州)、华东2(上海)、华东2金融云(上海)、华南1(深圳)、华南1金融云(深圳)、西南1(成都)、中国(香港)、德国(法兰克福)、马来西亚(吉隆坡)、美国(弗吉尼亚)、美国(硅谷)、日本(东京)、新加坡、印度尼西亚(雅加达)和英国(伦敦)地域支持使用MaxCompute投递(新版)。其它地域,请提交工单申请。
对于char类型或varchar类型的字段,如果其值长度超过指定长度,那么投递到MaxCompute后,超过部分会被截断。
例如长度限制为3,字段值为012345,则投递到MaxCompute后,值为012。
对于string类型、char类型或varchar类型的字段,如果其值为空字符串,那么投递到MaxCompute后,值为Null。
对于datetime类型的字段,其值格式必须为YYYY-MM-DD HH:mm:ss(DD和HH之间可以存在多个空格)。字段值格式错误时,不会导致投递错误,但投递到MaxCompute后,值为Null。
对于date类型的字段,其值格式错误时,不会导致投递错误,但投递到MaxCompute后,值为Null。
对于decimal类型的字段,如果其值中的小数位长度超过指定长度,会被四舍五入截断;如果整数位超过指定长度,系统会将整条日志作为脏数据丢弃,并增加错误计数。
投递过程中,默认丢弃脏数据。
对于日志中不存在的值,投递到MaxCompute后,可能为默认值或Null。
如果创建MaxCompute表时指定了默认值,那么投递到MaxCompute后,值为默认值。
如果创建MaxCompute表时未指定默认值,但是允许值为Null,那么投递到MaxCompute后,值为Null。
由于MaxCompute的限制,最大投递并发数为64,即最多支持64个并发同时写入MaxCompute。MaxCompute单分区的最大流量为10 MB/s。
操作步骤
登录日志服务控制台。
在Project列表区域,单击目标Project。
在
页签中,单击目标Logstore左侧的>,选择 。将鼠标悬浮在MaxCompute(原ODPS)上,单击+。
在MaxCompute投递功能面板中,配置如下参数,然后单击确定。
创建投递任务后,一般情况下日志数据会在写入Logstore后的1个小时导入到MaxCompute,导入成功后即可在MaxCompute内查看到相关数据。更多信息,请参见日志投递MaxCompute后,如何检查数据完整性。
| log_source | log_time | log_topic | time | ip | thread | log_extract_others | log_partition_time | status | +------------+------------+-----------+-----------+-----------+-----------+------------------+--------------------+-----------+ | 10.10.*.* | 1642942213 | | 24/Jan/2022:20:50:13 +0800 | 10.10.*.* | 414579208 | {"url":"POST /PutData?Category=YunOsAccountOpLog&AccessKeyId=****************&Date=Fri%2C%2028%20Jun%202013%2006%3A53%3A30%20GMT&Topic=raw&Signature=******************************** HTTP/1.1","user-agent":"aliyun-sdk-java"} | 2022_01_23_20_50 | 200 | +------------+------------+-----------+-----------+-----------+-----------+------------------+--------------------+-----------+
数据模型映射
将日志服务中的日志投递到MaxCompute表中时,涉及两个服务之间的数据模型映射问题,相关注意事项与示例如下所示。
MaxCompute表至少包含一个数据列和一个分区列。
日志服务保留字段建议使用__partition_time__、__source__、__topic__。
一个MaxCompute表的分区数最大值为60000个,当分区数超出最大值后无法再写入数据。
系统保留字段__extract_others__有曾用名_extract_others_,可兼容使用。
MaxCompute分区列的值不支持配置为MaxCompute的保留字和关键字。更多信息,请参见保留字与关键字。
MaxCompute分区表的分区不能为空。MaxCompute分区列必须要配置确定的字段(系统保留字段或日志内容的字段),旧版投递需要满足通过cast运算符将string类型字段值转换为对应分区列类型(若转换失败导致的空分区列,日志会在投递中被丢弃)。
日志服务中一个日志字段只能映射到一个MaxCompute表的列(数据列或分区列),不支持字段冗余。
MaxCompute数据列、分区列与日志服务字段的映射关系示例如下所示,其中日志服务保留字段详情请参见保留字段。
MaxCompute列类型 | 列名(MaxCompute) | 数据类型(MaxCompute) | 日志字段名称(日志服务) | 字段类型(日志服务) | 字段说明 |
数据列 | log_source | string | __source__ | 保留字段 | 日志来源。 |
log_time | bigint | __time__ | 保留字段 | 日志时间,Unix时间戳格式,对应数据模型中的Time域。 | |
log_topic | string | __topic__ | 保留字段 | 日志主题。 | |
time | string | time | 日志内容字段 | 解析自日志,对应数据模型中的key-value。在很多时候Logtail采集的数据的__time__与time取值相同。 | |
ip | string | ip | 日志内容字段 | 解析自日志。 | |
thread | string | thread | 日志内容字段 | 解析自日志。 | |
log_extract_others | string | __extract_others__ | 保留字段 | 未在配置中进行映射的其他日志字段会通过key-value序列化到JSON中,该JSON是一层结构,不支持字段内部JSON嵌套。 | |
分区列 | log_partition_time | string | __partition_time__ | 保留字段 | 由日志中的__time__字段对齐计算而得,分区粒度可配置。 |
status | string | status | 日志内容字段 | 解析自日志,该字段取值支持枚举,保证分区数目不超过上限。 |
投递模式说明
目前,MaxCompute投递(新版)支持实时投递和批投递两种模式。
实时投递:即时读取Logstore中的数据,投递到MaxCompute。
批投递:读取Logstore中早于当前时间5分钟~10分钟之间的数据,并投递到MaxCompute中。
设置投递模式为批投递后,如果您要设置开始时间范围中的起始时间或结束时间,则必须按照5分钟对齐。例如
2022-05-24 16:35:00
是正确设置,2022-05-24 16:36:00
为非法设置。另外,批投递支持投递__receive_time__字段。__receive_time__字段表示日志被日志服务接收的时间,您可通过时间分区格式设置其格式,最大精确到半小时。关于时间分区格式的说明,请参见参考信息。
如果您要投递该字段,只能在MaxCompute分区列中添加该字段。
参考信息
__partition_time__字段
将日志时间作为分区字段,通过时间筛选数据是MaxCompute常见的过滤数据的方法。
格式
__partition_time__是根据日志服务中__time__字段的值计算得到的,结合时区配置以及分区时间格式,生成时间字符串。为避免触发MaxCompute单表分区数目的限制,日期分区列的值按照1800秒(半小时)对齐。
例如:日志服务的日志时间为27/Jan/2022 20:50:13 +0800,日志服务据此计算出保留字段__time__为1643287813(Unix时间戳),不同配置下的时间分区列取值如下所示。
分区时间格式
__partition_time__
%Y_%m_%d_%H_%M_00
2022_01_27_20_30_00
%Y_%m_%d_%H_%M
2022_01_27_20_30
%Y%m%d
20220127
使用方法
使用__partition_time__ 筛选数据,可以避免全表扫描。例如查询2022年1月26日一天内日志数据,查询语句如下所示。
select * from {ODPS_TABLE_NAME} where log_partition_time >= "2022_01_26" and log_partition_time < "2022_01_27";
__extract_others__字段和__extract_others_all__字段
__extract_others__字段中包含日志字段中未映射的所有字段(不包括__topic__、__tag__:*和__source__)。
__extract_others_all__字段中包含日志字段中未映射的所有字段(包括__topic__、__tag__:*和__source__)。