本文档介绍如何将自定义的 SLS MetricStore(时序库)接入云监控2.0 UModel体系,实现指标数据的统一建模、查询和管理。通过 UModel 的 MetricSet 建模,可以将分散的时序指标数据与业务实体关联,构建完整的可观测数据体系。
统一数据模型:通过 MetricSet 对指标数据进行结构化建模,提供一致的数据访问体验。
实体关联:对现有实体可观测的增强,将指标数据与业务实体关联。
统一查询:支持 SPL 和自定义分析查询,无需关心底层存储细节。
注意事项
Domain 命名规范:新增的 UModel domain 配置不建议与内置 domain(如
apm、k8s、acs等)一致,避免系统升级后被误删。权限要求:确保当前用户对 MetricStore 有读取权限,否则查询时会返回权限错误。
UModel 唯一:确保新增节点的 <kind, domain, name>在 UModel 全局唯一。
前置要求
SLS MetricStore:已创建 MetricStore,并有指标数据写入。
指标数据:了解 MetricStore 中的指标名称、标签结构。
操作步骤
步骤一:定义 SLS MetricStore 存储
创建 sls_metricstore.yaml 文件,定义指标数据的物理存储位置:
kind: sls_metricstore
schema:
url: "umodel.aliyun.com"
version: "v0.1.0"
metadata:
name: "custom.metrics.storage"
display_name:
zh_cn: "自定义指标存储"
en_us: "Custom Metrics Storage"
description:
zh_cn: "自定义业务指标的物理存储配置"
en_us: "Physical storage configuration for custom business metrics"
domain: custom
spec:
region: "cn-hangzhou" # SLS Project 所在区域
project: "my-observability" # SLS Project 名称
store: "business-metrics" # MetricStore 名称配置参数说明:
参数名 | 类型 | 必填 | 描述 | 示例值 |
| string | 是 | 存储类型标识 | 固定值: |
| string | 是 | SLS 服务区域 | cn-hangzhou |
| string | 是 | SLS Project 名称 | my-observability |
| string | 是 | MetricStore 名称 | business-metrics |
步骤二:定义 MetricSet
您可以选择以下两种方式:
关联现有 MetricSet:如果系统中已有合适的 MetricSet 定义,可直接在步骤 3 中将其关联到您的 MetricStore
新建 MetricSet:如果需要自定义指标结构,按以下方式创建
metric_set.yaml文件,定义指标数据的结构、标签和查询方式:kind: metric_set schema: url: "umodel.aliyun.com" version: "v0.1.0" metadata: name: "custom.metric.business" display_name: zh_cn: "业务监控指标" en_us: "Business Monitoring Metrics" description: zh_cn: "自定义业务监控指标集,包含请求量、响应时间、成功率等核心指标" en_us: "Custom business monitoring metrics including request count, response time, success rate" domain: custom spec: query_type: prom # 查询语法类型:prom(MetricStore 使用 PromQL) labels: dynamic: true # 推荐设置为true:动态生成标签 filter: 'business_request_total' # 用于动态标签生成的指标名 keys: # 标签字段列表,定义所有需要的维度字段 - name: service_name display_name: zh_cn: 服务名称 en_us: Service Name type: string filterable: true analysable: true pattern: ".*" - name: endpoint display_name: zh_cn: 接口名称 en_us: Endpoint type: string filterable: true analysable: true pattern: ".*" - name: region display_name: zh_cn: 地域 en_us: Region type: string filterable: true analysable: true pattern: ".*" metrics: # 请求总数指标 - name: request_count # 指标名称,唯一标识 display_name: zh_cn: 请求次数 en_us: Request Count description: zh_cn: 服务接收到的请求总次数 en_us: Total number of requests received by the service generator: 'sum(increase(business_request_total{}[1m]))' # 定义指标的查询表达式(PromQL) aggregator: sum # 定义按维度(Label)聚合时的聚合算子, 聚合方式:sum、avg、max、min等 data_format: KMB # 数据格式化:KMB、percent、byte、ms、s golden_metric: true # 是否为黄金指标(建议 3-5 个) interval_us: [60000000] # 采集间隔(微秒) type: gauge # 平均响应时间指标 - name: avg_response_time display_name: zh_cn: 平均响应时间 en_us: Average Response Time description: zh_cn: 服务请求的平均响应时间 en_us: Average response time of service requests generator: | sum(rate(business_response_seconds_sum{}[1m])) / sum(rate(business_response_seconds_count{}[1m])) data_format: ms unit: 'ms' golden_metric: true interval_us: [60000000] type: gauge # 成功率指标 - name: success_rate display_name: zh_cn: 成功率 en_us: Success Rate description: zh_cn: 服务请求的成功率百分比 en_us: Success rate percentage of service requests generator: | (sum(increase(business_request_total{status="success"}[1m])) / sum(increase(business_request_total{}[1m]))) * 100 data_format: percent unit: '%' golden_metric: true interval_us: [60000000] type: gauge # 错误数指标 - name: error_count display_name: zh_cn: 错误次数 en_us: Error Count description: zh_cn: 服务请求的错误次数 en_us: Number of failed requests generator: 'sum(increase(business_request_total{status="error"}[1m]))' aggregator: sum data_format: KMB golden_metric: false interval_us: [60000000] type: gaugeLabels 配置:
属性名
类型
说明
推荐值
dynamicboolean
是否动态生成标签
强烈推荐设置为 true
filterstring
用于动态标签生成的指标过滤器
选择一个有代表性的指标名
keysarray
标签字段列表
定义所有需要的维度字段
Metrics 配置:
属性名
类型
必填
说明
namestring
是
指标名称,唯一标识
generatorstring
是
定义指标的查询表达式, 查询表达式(PromQL)
aggregatorstring
否
定义按维度(Label)聚合时的聚合算子, 聚合方式:
sum、avg、max、min等data_formatstring
是
数据格式化:
KMB、percent、byte、ms、sgolden_metricboolean
否
是否为黄金指标(建议 3-5 个)
interval_usarray
否
采集间隔(微秒)
更多配置细节,请参考文档:Metrics 建模。
步骤三:创建 Storage Link(存储链接)
创建 storage_link.yaml 文件,建立 MetricSet 与 SLS MetricStore 的关联:
kind: storage_link
schema:
url: "umodel.aliyun.com"
version: "v0.1.0"
metadata:
name: "custom.metric.business_storage_link"
display_name:
zh_cn: "业务指标存储链接"
en_us: "Business Metrics Storage Link"
description:
zh_cn: "将业务监控指标集链接到 SLS MetricStore"
en_us: "Link business metrics to SLS MetricStore"
domain: custom
spec:
src:
domain: custom
kind: metric_set
name: custom.metric.business
dest:
domain: custom
kind: sls_metricstore
name: custom.metrics.storage步骤四:上传配置
将配置文件通过以下方式上传到 UModel 系统:
登录云监控2.0控制台。
进入目标工作空间,在左侧导航栏选择UModel探索。
在UModel 探索页面,单击页面右上角
,在弹出框中单击上传 UModel YAML /JSON。在批量上传 UModel的弹窗中,单击
选择文件,或将文件拖拽到上传框中:sls_metricstore.yaml、metric_set.yaml、storage_link.yaml。文件上传后,单击立即导入。
导入成功后,单击页面右上角提交。
在提交预览页面,检查内容无误后,单击确认内容符合预期,执行变更。在变更情况弹框中,单击确定。
在UModel探索页面,确认 MetricSet、StorageLink和SLS MetricStore已创建。
步骤五:验证配置
进入实体探索,单击SPL,输入SPL语句验证是否生效:
1. 验证 MetricSet 创建成功
.umodel | where kind = 'metric_set' and json_extract_scalar(metadata, '$.name') = 'custom.metric.business'2. 验证数据可查询
.metric_set with(domain='custom', name='custom.metric.business') | limit 10数据查询
MetricStore 接入 UModel 后,支持两种查询方式:SPL 查询,SPL(Search Processing Language)是 SLS 提供的统一查询语言,可以直接查询 MetricSet 中的指标数据。
查询入口:在实体探索页面,单击SPL,在右侧输入框中输入查询语句。
基础查询语法
-- 查询 MetricSet 基础语法
.metric_set with(
domain='域名',
name='数据集名称',
source='metrics',
metric='指标名',
[其他可选参数]
)示例:
基础查询:查询
api_request_duration指标,不做聚合直接返回所有指标,Step使用Auto模式。.metric_set with( domain='rum', name='rum.metric.api', source='metrics', metric='api_request_duration', aggregate=false )聚合查询:查询 request_count 指标,并聚合 service 和 operation 维度,过滤条件为 service_id = “hwx28v3j7p@9949e3dbf79e9a082105c”,查询步长为1分钟。
.metric_set with( domain='apm', name='apm.metric.apm.operation', source='metrics', metric='request_count', query_type='range', step='1m', aggregate=true, aggregate_labels=['service', 'operation'], query='service_id = "hwx28v3j7p@9949e3dbf79e9a082105c"' )聚合后分析:查询 error_rate 指标,进行统一聚合,并调用异常检测 SPL 进一步分析。
.metric_set with( domain='apm', name='apm.metric.apm.service', source='metrics', metric='error_rate', step='1m', aggregate='true' ) | extend slice_index = find_first_index(__ts__, x -> x > 1756904640000000000) | extend len = cardinality(__ts__) | extend ret = series_cnn_anomalies(__value__) | extend anomalies_score_series = ret.anomalies_score_series, anomalies_type_series = ret.anomalies_type_series, error_msg = ret.error_msg | project __labels__, __name__, __ts__, __value__, anomalies_score_series, anomalies_type_series, error_msg,len,slice_index | extend __ts__ = slice(__ts__, slice_index, len - slice_index), __value__ = slice(__value__, slice_index, len - slice_index), anomalies_score_series = slice(anomalies_score_series, slice_index, len - slice_index), anomalies_type_series = slice(anomalies_type_series, slice_index, len - slice_index) | extend anomay_cnt = CARDINALITY(FILTER(anomalies_score_series, x -> x > 0.5)), anomaly_sorce = array_sum(FILTER(anomalies_score_series, x -> x > 0.5)) | extend sort_score = anomaly_sorce / cast(anomay_cnt as double) | sort sort_score desc , anomay_cnt desc
面向实体(EntitySet)数据查询
查询 service_id 等于 order-service 的request_count 指标
.entity_set with(domain='apm', name='apm.service', query='service_id = "order-service"') | entity-call get_metric('apm', 'apm.metric.apm.service', 'request_count', 'range', '1m')查询 request_count 指标,进行统一聚合,并调用异常检测 SPL 进一步分析。
.entity_set with(domain='apm', name='apm.service', query='service_id = "order-service"') | entity-call get_metric('apm', 'apm.metric.apm.service', 'request_count', 'range', '1m') | extend slice_index = find_first_index(__ts__, x -> x > 1756904640000000000) | extend len = cardinality(__ts__) | extend ret = series_cnn_anomalies(__value__) | extend anomalies_score_series = ret.anomalies_score_series, anomalies_type_series = ret.anomalies_type_series, error_msg = ret.error_msg | project __labels__, __name__, __ts__, __value__, anomalies_score_series, anomalies_type_series, error_msg,len,slice_index | extend __ts__ = slice(__ts__, slice_index, len - slice_index), __value__ = slice(__value__, slice_index, len - slice_index), anomalies_score_series = slice(anomalies_score_series, slice_index, len - slice_index), anomalies_type_series = slice(anomalies_type_series, slice_index, len - slice_index) | extend anomay_cnt = CARDINALITY(FILTER(anomalies_score_series, x -> x > 0.5)), anomaly_sorce = array_sum(FILTER(anomalies_score_series, x -> x > 0.5)) | extend sort_score = anomaly_sorce / cast(anomay_cnt as double) | sort sort_score desc , anomay_cnt desc