按内容动态分流

数据分发是指通过数据加工任务,将一份源日志按照预设的SPL规则处理后,写入一个或多个目标Logstore,支持跨账号、跨地域写入。日志服务提供两种分发模式:

  • 静态分发:目标ProjectLogstore在任务配置时固定指定,最多支持20个输出目标,适用于目标Logstore固定的场景。

  • 动态分发:根据日志中的业务字段(如 tenant_idservicelevel 等)动态生成目标地址,并替换固定配置的ProjectLogstore。适用于目标ProjectLogstore根据业务日志内容命名的场景。

核心机制

动态分发不是绕过静态分发,而是在其基础上进行字段值的替换

  • __tag__:__sls_etl_output_project__ :替换固定配置的目标Project

  • __tag__:__sls_etl_output_logstore__: 替换固定配置的目标库

因此,固定配置在动态分发时的作用是提供执行上下文(账号 + 地域 + 权限),而非最终写入路径。

说明

动态分发无法改变目标Region和跨账号权限边界,这些必须在配置固定目标ProjectLogstore时正确设置。

常见场景包括:

  • 多租户数据隔离:SaaS平台根据租户ID(tenant_id)将不同租户的日志分别存储,便于后续的权限控制、计量计费和数据分析。

  • 按环境分流日志:根据环境标识(prodstagingdev)将日志自动分流到对应环境的Logstore,以简化调试和监控流程。

  • 按业务模块分类:将复杂应用中不同业务模块(如订单、支付、用户)的日志分发到独立的Logstore,进行专项存储和分析。

准备源Logstore数据

确保源 Logstore 已接入原始日志,并包含可用于路由的关键字段。

{
  "timestamp": "2025-04-05T10:00:00Z",
  "method": "POST",
  "uri": "/api/v1/orders",
  "status": 200,
  "tenant_id": "t-7a8b9c",
  "service": "order-service",
  "log_type": "access",
  "user_id": "u-12345"
}

关键路由字段说明:

  • tenant_id:租户唯一标识,用于决定目标 Project,实现租户级隔离。

  • service:微服务名称,用于构建目标Logstore名称,假设系统包含:

    • user-service

    • order-service

    • payment-service

    • auth-service

编写SPL规则实现动态路由

  1. 登录日志服务控制台

  2. 单击源Project名称,进入源Project。

  3. 在左侧导航栏,单击image任务管理

  4. 数据加工页签下,单击创建数据加工任务,选择源日志库,单击确认

  5. 选择数据的时间范围,并输入SPL规则。

仅动态指定Project(固定Logstore)

适用于多租户平台,每个租户有相同结构的 Logstore。SPL规则如下:

* 
| extend "__tag__:__sls_etl_output_project__" = concat('saas-tenant-', tenant_id)
// 目标 Logstore 使用静态配置值,例如 'access-log'

调试SPL并配置默认存储目标:

  1. 原始日志中选择日志数据加入测试数据

  2. 测试数据页签中,单击调试SPL,查看加工结果

  3. 当加工结果符合预期后,单击保存数据加工(新版)

  4. 创建数据加工任务(新版)面板中,存储目标配置如下:

    • 目标Region选择动态Project所在地域。

    • 目标Project可设为该地域下任意已存在的Project(将被覆盖)。

    • 目标库必须准确(不会被覆盖)。

    • 必须确保动态Project存在且有权访问。

    image

  5. 验证分发结果:启动任务后,在各目标 Logstore 查询数据,确认路由是否生效。示例:

    输入日志特征

    实际写入位置

    tenant_id=t-7a8b9c

    Project: saas-tenant-t-7a8b9c, Logstore: 指定目标库

    tenant_id=t-xyz123

    Project: saas-tenant-t-xyz123, Logstore: 指定目标库

仅动态指定Logstore(固定Project)

适用于在同一 Project 内按服务或级别分类日志。SPL规则如下:

* 
| extend "__tag__:__sls_etl_output_logstore__" = concat(service,'-logs')
// 目标 Project 使用静态配置值,例如 'central-project'

调试SPL并配置默认存储目标:

  1. 原始日志中选择日志数据加入测试数据

  2. 测试数据页签中,单击调试SPL,查看加工结果

  3. 当加工结果符合预期后,单击保存数据加工(新版)

  4. 创建数据加工任务(新版)面板中,存储目标配置如下:

    • 目标Region:选择固定Project所在地域。

    • 目标Project:确保该Project下存在指定的动态Logstore;

    • 目标库可设为目标Project任意已存在的Logstore(将被覆盖)。

    image

  5. 验证分发结果:启动任务后,在各目标 Logstore 查询数据,确认路由是否生效。示例:

    输入日志特征

    实际写入位置

    service=user-service

    Project:目标Project

    Logstore:user-service-logs

    service=order-service

    Project:目标Project

    Logstore:order-service-logs

    service=payment-service

    Project:目标Project

    Logstore:payment-service-logs

    service=auth-service

    Project:目标Project

    Logstore:auth-service-logs

同时动态指定ProjectLogstore

适用于完全由日志驱动的全自动路由场景。SPL规则如下:

*
-- 动态指定输出目标 Project(按租户隔离) 
| extend "__tag__:__sls_etl_output_project__" = concat('saas-tenant-', tenant_id) 
-- 动态指定输出目标 Logstore(格式:服务名-logs)
| extend "__tag__:__sls_etl_output_logstore__" = concat(service, '-logs') 

调试SPL并配置默认存储目标:

  1. 原始日志中选择日志数据加入测试数据

  2. 测试数据页签中,单击调试SPL,查看加工结果

  3. 当加工结果符合预期后,单击保存数据加工(新版)

  4. 创建数据加工任务(新版)面板中,存储目标配置如下:

    说明

    即使所有字段都将被动态覆盖,也必须配置一个“默认存储目标” —— 它的作用不是容错,而是提供:

    • 目标地域

    • 执行角色

    • 目标Region:选择动态Project所在地域。

    • 目标Project目标库可设为该地域下任意已存在的ProjectLogstore(均会被覆盖);

    • 必须确保动态ProjectLogstore存在且有权访问。

    image

  5. 验证分发结果:启动任务后,在各目标 Logstore 查询数据,确认路由是否生效。

    基于tenant_id 和 service 字段实现多租户日志自动隔离:同一租户的日志都存储在同一Project下,且根据service字段存入不同的Logstore。示例:

    输入日志特征

    实际写入位置

    tenant_id=t-1001service=user-service

    Project:saas-tenant-t-1001

    Logstore:user-service-logs

    tenant_id=t-1002service=payment-service

    Project:saas-tenant-t-1002

    Logstore:payment-service-logs