CnOps 社区
首页开源项目实践文章视频课程常见问答开发者工具
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具

CnOps 社区

愿景

CnOps 社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页实践文章UModel进阶 - UModel PaaS API 设计理念与实践

UModel进阶 - UModel PaaS API 设计理念与实践

#UModel进阶#日志#指标#api#运维#自动化

CNOps | 2026-05-23

背景

基于 UModel 构建的可观测系统,访问可观测数据需要上层应用感知 EntitySet、DataSet、Storage、Filter 等多个概念,给 UI、算法、客户等使用方带来了较高的开发和维护成本。

典型场景:查询 APM 服务的请求量指标

假设上层应用需要实现查询某个 APM 服务的请求量指标,开发者需要经历以下步骤:

开发者需要了解的知识

  1. 实体关联:服务实体关联哪个 MetricSet?
  2. 存储路由:MetricSet 使用哪个 MetricStore?Region/Project/存储名称是什么?
  3. 字段映射:Entity 的 service_id 对应存储的哪个字段(如 acs_arms_service_id)?
  4. 查询语法:如何编写 PromQL 表达式 rate(arms_app_requests_count_raw{...}[1m])?
  5. SPL 拼接:如何组装成完整的查询语句?

完整的开发步骤

Step 1: 查询 UModel 元数据
↓ 找到 service EntitySet 关联的 MetricSet
↓ 如果 DataLink 中包含 FilterByEntity,还需根据实体数据过滤

Step 2: 解析 MetricSet 配置
↓ 根据 StorageLink 获取底层 MetricStore 连接信息
↓ 获取 Region/Project/MetricStore 名称

Step 3: 查看字段映射
↓ 从 DataLink 中获取字段映射表
↓ 确认 service_id → acs_arms_service_id

Step 4: 构造 PromQL 表达式
↓ 根据指标定义拼接查询表达式
↓ 处理聚合规则、时间窗口

Step 5: 拼接并执行查询
↓ 使用正确的 label 和 MetricStore
↓ 拼接完整的 SPL 语句并执行
 

最终查询语句示例:

.metricstore with(region='cn-hangzhou', project='cms-xxx', metricstore='metricstore-apm')
|prom-call promql_query_range('sum by (acs_arms_service_id) (rate(arms_app_requests_count_raw{acs_arms_service_id="xxx"}[1m]))','1m')

痛点

痛点 1:概念复杂,学习门槛高

问题描述:

  • 开发者必须深入理解 UModel 架构:EntitySet、DataSet、DataLink、StorageLink、Filter 等多个概念
  • 需要了解 DataSet 与 Storage 的关联关系、Filter 路由逻辑、字段映射规则
  • 新人上手困难,老手也容易遗漏细节

影响:开发效率低,维护成本高

痛点 2:复杂场景实现困难

问题描述:

  • 存储路由查找:需要理解多个 MetricSet 之间的选择逻辑
  • 字段映射处理:Entity 字段 → 存储字段的映射规则复杂
  • 过滤条件筛选:FilterByEntity 规则匹配逻辑难以掌握
  • 多次查询拼接:需要多次查询元数据,再构建数据查询

影响:增加代码复杂度,出错概率高

痛点 3:底层存储语法逃不掉

问题描述:

  • MetricSet 可能由 MetricStore 或 LogStore 实现,查询方式完全不同(PromQL vs SPL)
  • 不同存储提供商(ARMS MetricStore、Aliyun Prometheus)语法有差异
  • 开发者仍需精通底层查询语言

影响:同样的需求需要编写不同的代码,无法统一

痛点 4:多次查询交互,效率低

问题描述:

  • 先查询 UModel Meta 获取配置 → 再根据 Meta 查询数据
  • 需要自己处理数据拼接和关联
  • 每个使用方都要实现类似逻辑,代码重复度高

影响:集成成本高,查询延迟大,出错概率增加

目标与架构

设计目标

针对上述四大痛点,UModel PaaS API 的设计目标是屏蔽底层复杂性,统一访问接口,使上层应用更加专注业务逻辑实现:

痛点解决方案
痛点 1:概念复杂提供统一的 SPL 高维度抽象,屏蔽底层细节
痛点 2:复杂场景自动处理路由、映射、过滤,框架自动完成复杂工作
痛点 3:底层存储语法设计两种模式(Table + Object),统一查询语言
痛点 4:多次查询交互一次查询完成所有工作,减少网络往返

核心设计原则

  • 自动化处理:自动路由、字段映射、查询转换
  • 统一 SPL 语法:所有数据类型使用一致接口
  • 面向对象编程:实体方法调用、关系导航
  • AI 友好:反射能力,支持 AI Agent 自主探索

设计理念:两层抽象

访问 UModel 数据时,需要单独通过 SPL 去访问指标、日志、链路等各种数据,每种数据都有不同的访问方式,没有统一的抽象。

UModel PaaS API 采用两层抽象的设计思路:

第一层抽象:Table 模式(表格化抽象)

将所有数据——指标、日志、链路、性能剖析——统一抽象成表格结构,所有查询都是针对表格数据进行操作。

价值:统一了查询语言,开发者不需要关心底层是 PromQL 还是 SLS SPL,都用同一套 SPL 语法。

第二层抽象:Object 模式(对象级抽象)

表格模式解决了数据访问的统一性,但还不够。我们还需要以实体为中心的抽象。

传统方式:查询一个服务的指标,需要知道这个服务关联哪个 MetricSet、字段如何映射、过滤条件怎么写…

Object 模式:只需要说"这个服务,给我它的指标",系统自动处理字段映射、过滤条件、存储路由。

价值:面向对象的思想,把实体当成对象,把查询当成方法调用:service.get_metric()。

第三层能力:元数据查询(反射能力)

提供动态能力发现、配置验证等高级功能,让 AI Agent 可以自主探索、自主决策。

价值:AI Agent 能够通过反射能力动态发现实体的能力边界,实现真正的智能运维。

架构分层

1. 存储层统一:EntityStore/LogStore/MetricStore → SPL

自动完成存储路由、字段映射(service_id → acs_arms_service_id)、过滤、查询语法的转换。上层应用对存储切换无感知。

2. 数据层统一:Table 模式

直接访问 DataSet,声明式查询,支持完整 SPL Pipeline。


.metric_set with(domain='apm', name='service.request', query=`service_id='xxxx'`) | stats avg(latency)

.log_set with(domain='apm', name='service.error_log' query=`service_id='xxx'`) | where level="ERROR"

3. 对象层统一:Object 模式

以实体为中心,自动处理底层细节,支持动态能力发现和配置检查。

# 数据访问
.entity_set with(domain='apm', name='apm.service', ids=['404e5d6be468f6dfaeef37a014322423']) 
| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '', false) 

# 能力发现(Agent 自主决策的关键)
.entity_set with(domain='apm', name='service') | entity-call __list_method__()

# 配置检查
.entity_set with(domain='apm', name='service') | entity-call __inspect__()

API 说明

UModel PaaS API 提供三大核心能力,满足不同场景的查询需求:

  1. Table 模式 - 直接访问数据集,适合批量数据分析
  2. Object 模式 - 以实体为中心,适合实体详情查询和关系分析
  3. 元数据查询 - 反射能力和配置验证,支持 AI Agent 和开发调试

Table 模式

Table 模式(Phase 1)提供直接访问 DataSet(MetricSet、LogSet、TraceSet 等)的能力,返回表格化的可观测数据,适用于不依赖实体关系的数据查询场景。

如:直接查询某个 MetricSet 中的指标数据,或查询某个 LogSet 中的日志,无需关联实体信息。

# 读取 apm.metric.apm.service MetricSet对应的avg_request_latency_seconds的指标,
# 并对该指标进行异常检测
.metric_set with(domain='apm', name='apm.metric.apm.service', metric='avg_request_latency_seconds', source='metrics')
| extend r = series_decompose_anomalies(__value__) 
| extend anomaly_b =r.anomalies_score_series , anomaly_type = r.anomalies_type_series , __anomaly_msg__ = r.error_msg 
| extend x = zip(anomaly_b, __ts__, anomaly_type, __value__) 
| extend __anomaly_rst__ = filter(x, x-> x.field0 > 0) 
| project __entity_id__, __labels__, __anomaly_rst__, __anomaly_msg__

核心特点:

  • 直接访问:直达 DataSet,无需查询实体元数据
  • 语法简洁:类似 SQL 的 SPL 语法,易于理解
  • 全量数据:返回 DataSet 中符合条件的所有数据

语法:.<type> with(domain, name, ...) | <SPL Pipeline>, 更多参数说明请参考文档: Phase 1 Table模式

数据集说明示例
.metric_set获取指标数据

* 获取 apm 域下 apm.metric.apm.service MetricSet 中 avg_request_latency_seconds 指标

.metric_set with(domain='apm', name='apm.metric.apm.service', metric='avg_request_latency_seconds', source='metrics')

* 获取 apm 域下 apm.metric.apm.service MetricSet 中指标的标签列表

.metric_set with(domain='apm', name='apm.metric.apm.service', metric='avg_request_latency_seconds', source='labels')

.log_set获取日志数据

* 获取 apm 域下 apm.log.apm.service LogSet 的日志数据

.log_set with(domain='apm', name='apm.log.apm.service') | where trace='ERROR'

* 使用查询条件获取日志

.log_set with(domain='apm', name='apm.log.apm.service', query='service_id="xxx" and level="ERROR"') | where msg like "%OutOfMemory%"

.trace_set获取链路数据

* 获取 apm 域下 apm.trace.apm.service TraceSet 的链路数据

.trace_set with(domain='apm', name='apm.trace.apm.service') | where duration > 1000

* 统计链路调用次数

.trace_set with(domain='apm', name='apm.trace.apm.service', query='service_id="xxx"') | stats pv=count(1) by service_name

.profile_set获取性能剖析数据

* 获取 apm 域下 apm.profile.apm.service ProfileSet 的性能数据

.profile_set with(domain='apm', name='apm.profile.apm.service') | where profile_type='cpu'

* 获取 CPU 使用率最高的 Top 10

.profile_set with(domain='apm', name='apm.profile.apm.service', query='service_id="xxx"') | stats avg(cpu_usage) by function

Object 模式

Object 模式(Phase 2)提供以实体为中心的面向对象查询能力,自动处理实体与数据的关联关系、字段映射、关系查询等复杂逻辑,适用于需要实体上下文的业务场景。

如:查询某个具体服务的指标、日志、链路数据,或查询与该服务有调用关系的其他服务,系统自动完成字段映射和数据过滤。

# 查询特定服务的请求延迟指标,自动处理字段映射和 FilterByEntity
.entity_set with(domain='apm', name='apm.service', ids=['21d5ed421ae93973d67a04af551b48b8']) 
| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '30s', false)
| project __entity_id__, __ts__, __value__, __labels__

核心优势:

  • 零配置过滤:自动处理 FilterByEntity,无需手动拼接过滤条件
  • 字段映射透明:自动转换 service_id → acs_arms_service_id 等映射
  • 面向对象语义:entity.get_metric(),符合开发者思维习惯

语法:.entity_set with(domain, name, id, query) | entity-call <方法>(<参数>) | <SPL pipeline>, 更多参数说明请参考文档: Phase 2 Object模式

方法说明示例
get_metric获取实体关联的指标数据,支持指定 metric、step、聚合等参数
  • 获取实体的请求延迟指标

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '30s', false)

  • 获取实体的请求量并聚合

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_metric('apm', 'apm.metric.apm.service', 'request_count', 'range', '1m', true)

get_log获取实体关联的日志数据,支持后续 SPL 过滤和搜索
  • 获取实体的错误日志

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_log('apm', 'apm.log.apm.service') | where level='ERROR'

  • 搜索特定关键字的日志

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_log('apm', 'apm.log.apm.service') | where msg like "%OutOfMemory%"

get_trace获取实体关联的链路追踪数据,用于分析服务调用链
  • 获取实体的所有链路

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_trace('apm', 'apm.trace.apm.service')

  • 分析慢调用链路

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_trace('apm', 'apm.trace.apm.service') | where duration > 1000

get_profile获取实体关联的性能剖析数据,用于 CPU、内存等性能分析
  • 获取实体的性能剖析数据

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_profile('apm', 'apm.profile.apm.service')

  • 分析 CPU 热点

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call get_profile('apm', 'apm.profile.apm.service') | where profile_type='cpu' | top 10

元数据查询方法

元数据查询方法提供动态发现和反射能力,用于查询实体的关联关系、数据集配置、支持的方法等元数据信息,既可以帮助开发者理解实体能力,也是实现 AI Agent 自主决策和配置验证的关键基础。

如:查询某个服务实体支持哪些方法(__list_method__())、关联了哪些数据集(list_data_set())、与哪些其他服务有调用关系(list_related_entity_set())、配置是否正确(__inspect__())。

# 动态发现实体支持的所有方法(反射能力)
.entity_set with(domain='apm', name='apm.service') 
| entity-call __list_method__()

# 返回:方法列表及参数定义
# [
# {"name": "get_metric", "params": [...], "description": "获取指标数据"},
# {"name": "list_related_entity_set", "params": [...], "description": "查询关联实体"},
# ...
# ]

核心价值:

  • 反射能力:__list_method__() 让 AI Agent 能自主探索实体的能力边界
  • 配置验证:__inspect__() 一键检查 DataSet、Link、字段映射等配置完整性
  • 关系查询:list_related_entity_set() 快速获取拓扑关系,无需查询图数据库
  • 能力发现:list_data_set() 了解实体关联的所有观测数据类型

语法:.entity_set with(domain, name, id, query) | entity-call <方法>(<参数>), 更多参数说明请参考文档: Phase 2 Object模式

方法说明示例
list_data_set列出实体关联的所有数据集(MetricSet、LogSet 等),可按类型过滤
  • 列出实体的所有指标集

.entity_set with(domain='apm', name='apm.service') | entity-call list_data_set(data_set_types=['metric_set'])

  • 列出实体的所有数据集

.entity_set with(domain='apm', name='apm.service') | entity-call list_data_set()

list_related_entity_set列出与当前实体相关的其他实体,支持按关系类型和方向过滤
  • 列出服务调用的下游服务

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call list_related_entity_set(relations=['calls'], direction='out')

  • 列出与服务相关的所有实体

.entity_set with(domain='apm', name='apm.service', ids=['xxx']) | entity-call list_related_entity_set()

__list_method__动态发现实体支持的所有方法(反射能力),Agent 自主决策的核心

查看实体支持的方法列表

.entity_set with(domain='apm', name='apm.service') | entity-call __list_method__()

返回方法名、参数、返回值等完整定义

__inspect__检查实体及关联配置的完整性,包括 DataSet、Link、字段映射等
  • 全面检查实体配置

.entity_set with(domain='apm', name='apm.service') | entity-call __inspect__()

  • 只检查指标配置

.entity_set with(domain='apm', name='apm.service') | entity-call __inspect__(check_data_sets=true, data_set_types=['metric_set'])

查询方式

UI 方式

登录云监控 2.0 控制台,点击实体探索 -> SPL , 输入 SPL,如下图所示:

.entity_set with(domain='apm', name='apm.service', ids=['21d5ed421ae93973d67a04af551b48b8']) | entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '', false)

DryRun 模式

dryRun 模式返回对应的 Query,不执行当前 Query,也支持手动设置运行模式

# 开启dry_run模式
.set umodel_paas_mode='dry_run';
.entity_set with(domain='apm', name='apm.service') 
| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '', false) 

UI 开启 DryRun 模式

SDK 方式

通过阿里云 OpenAPI下载 SDK,代码如下

package main

import (
"fmt"
cms20240330 "github.com/alibabacloud-go/cms-20240330/v3/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea"
credential "github.com/aliyun/credentials-go/credentials"
"os"
)

func CreateClient() (_result *cms20240330.Client, _err error) {
credential, _err := credential.NewCredential(nil)
if _err != nil {
return _result, _err
}

config := &openapi.Config{
Credential: credential,
}
config.Endpoint = tea.String("cms.cn-hangzhou.aliyuncs.com")
_result = &cms20240330.Client{}
_result, _err = cms20240330.NewClient(config)
return _result, _err
}


func _main(args [ ]*string) (_err error) {

client, _err := CreateClient()
if _err != nil {
return _err
}


getEntityStoreDataRequest := &cms20240330.GetEntityStoreDataRequest{
Query: tea.String(".entity_set with(domain='apm', name='apm.service', ids=['21d5ed421ae93973d67a04af551b48b8']) | entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range') "),
From: tea.Int32(1762244123),
To: tea.Int32(1762244724),
}

if result, err := client.GetEntityStoreData(tea.String("o11y-demo-cn-hangzhou"), getEntityStoreDataRequest); err != nil {
return err
} else {
fmt.Printf("length: %d", len(result.Body.Data))
return nil
}
}

func main() {
err := _main(tea.StringSlice(os.Args[1:]))
if err != nil {
panic(err)
}
}

参数说明:

参数说明示例
workspace_name可观测 2.0 Workspace 名称o11y-demo-cn-hangzhou
spl执行 SPL 语句

.entity_set with(domain='apm', name='apm.service', ids=['21d5ed421ae93973d67a04af551b48b8'])

| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds')

from查询开始时间1762244123
To查询结束时间1762244724

程序运行

go build -o demo .

export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<YOUR_ACCESS_SECRET>
export ALIBABA_CLOUD_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>

./demo

示例

集成算子实现高阶能力: UModel 高阶查询 + 时序异常检测算子

通过 UModel 高阶 API 集成 SLS 时序异常检测算子 series_decompose_anomalies,一行查询实现智能异常检测。

如:监控某个 APM 服务的请求延迟,当出现异常(突刺、趋势变化、平台变化)时触发告警。

.entity_set with(domain='apm', name='apm.service', ids=['21d5ed421ae93973d67a04af551b48b8']) 
| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', 'range', '30s', false) 
| extend r = series_decompose_anomalies(__value__) 
| extend anomaly_b =r.anomalies_score_series , anomaly_type = r.anomalies_type_series , __anomaly_msg__ = r.error_msg 
| extend x = zip(anomaly_b, __ts__, anomaly_type, __value__) 
| extend __anomaly_rst__ = filter(x, x-> x.field0 > 0) 
| project __entity_id__, __labels__, __anomaly_rst__, __anomaly_msg__

返回结果

字段说明
__entity_id__发生异常的实体 ID
__labels__指标标签(JSON 格式)
__anomaly_rst__异常数组:[[异常分数, 时间戳(ns), 异常类型, 指标值], ...]
__anomaly_msg__检测状态(空=成功,非空=失败原因)

支持的异常类型:

  • SPIKE_UP / SPIKE_DOWN - 向上/向下突刺
  • TREND_SHIFT_UP / TREND_SHIFT_DOWN - 趋势上升/下降
  • LEVEL_SHIFT_UP / LEVEL_SHIFT_DOWN - 平台上升/下降

如下图:

数据互联互通:关联自定义 LogStore

在实际生产环境中,业务数据往往分散在多个存储中。例如:

  • UModel 中存储了 APM 服务的拓扑关系、指标、链路、日志
  • 业务系统的自定义日志存储在独立的 LogStore 中(如订单日志、支付日志、用户行为日志)

通过 UModel 高阶 API + SPL join 能力,可以打通 UModel 实体数据与自定义业务数据,实现:

  1. 统一视角分析:将应用性能问题与业务日志关联分析
  2. 快速定位问题:从服务异常快速定位到具体业务操作
  3. 端到端追踪:从业务请求到技术指标的全链路分析

典型场景:

  • 某个 APM 服务出现延迟异常 → 关联业务订单日志 → 定位到具体慢查询的订单 ID
  • 某个服务的错误日志激增 → 关联用户行为日志 → 分析是哪些用户操作触发了异常
  • 分析服务调用链路 → 关联业务流程日志 → 追踪完整的业务流转路径

示例:


# 场景:关联自定义的logstore日志信息

# SPL: 
# 1. 从业务LogStore中找到失败的traceId以及msg
.let failed_log = .logstore with(project=‘xxx’, logstore=‘xxxx’, query=‘*') 
| project trace_id, msg;

# 2. 查询服务的Trace数据
.let service_traces = .entity_set with(domain='apm', name='apm.service', ids=['xxxx']) 
| entity-call get_trace(‘apm‘, ’apm.trace.common’);

$failed_log | join $service_traces on trace_id = $service_traces.traceId | project msg

集成 AI Agent:通过反射能力实现自主决策

将 UModel PaaS API 封装为 MCP Tools,通过反射能力(__list_method__())让 AI Agent 具备自主探索和决策能力,实现智能运维分析。

如:用户问"为什么服务响应慢?",Agent 通过动态发现可用方法,自主完成根因分析。

# Agent 首先调用 __list_method__() 动态发现实体支持的方法
.entity_set with(domain='apm', name='apm.service') 
| entity-call __list_method__()

# 返回示例(Agent 根据返回的方法列表自主决策下一步操作):
# {
# "methods": [
# {"name": "get_metric", "params": [...], "description": "获取指标数据"},
# {"name": "get_log", "params": [...], "description": "获取日志数据"},
# {"name": "get_trace", "params": [...], "description": "获取链路数据"},
# {"name": "list_related_entity_set", "params": [...], "description": "查询关联实体"}
# ]
# }

文章大纲