How UModel PaaS API Simplifies Observability Queries with Unified Entity Search
This article explains how the UModel PaaS API abstracts complex observability concepts—such as EntitySet, DataSet, StorageLink, and Filter—into a unified, object‑oriented query interface, offering Table, Object, and metadata modes, code examples, UI and SDK usage, and AI‑agent integration for efficient, low‑maintenance monitoring.
Background
UModel‑based observability systems require applications to understand multiple concepts (EntitySet, DataSet, StorageLink, Filter) to query metrics, logs, or traces. This creates high development and maintenance costs.
Pain Points
Complex concepts : steep learning curve for developers.
Scenario difficulty : multiple steps are needed to map an entity to its storage, construct a PromQL expression, and execute the query.
Different query languages : metric stores use PromQL while log stores use SPL.
Repeated interactions : developers must fetch metadata, build queries, and stitch results repeatedly.
Design Goals
The UModel PaaS API is designed to hide the underlying complexity and provide a unified access interface so that upper‑layer applications can focus on business logic.
Core Design Principles
Automatic handling of storage routing, field mapping, and query translation.
Unified SPL syntax for all data types.
Object‑oriented programming model (entity methods).
AI‑friendly reflection capabilities for agents.
Two‑Layer Abstraction
1. Table Mode (Phase 1)
All observable data (metrics, logs, traces) are abstracted as tables. Queries are written in a SQL‑like SPL syntax, for example:
.metric_set with(domain='apm', name='apm.metric.apm.service', query='service_id="xxx"') | stats avg(latency)Features: direct access to the underlying DataSet, concise syntax, and full data retrieval.
2. Object Mode (Phase 2)
Developers query by entity, e.g. service.get_metric(). The system automatically resolves the entity‑to‑MetricSet mapping, performs field conversion, and applies filters.
.entity_set with(domain='apm', name='apm.service', ids=['21d5ed...']) | entity-call get_metric('apm','apm.metric.apm.service','avg_request_latency_seconds','range','30s',false) | project __entity_id__, __ts__, __value__, __labels__Advantages: zero‑configuration filtering, transparent field mapping, and object‑oriented semantics.
3. Metadata Query
Dynamic discovery and configuration validation methods such as __list_method__(), list_data_set(), list_related_entity_set(), and __inspect__() enable AI agents to explore entity capabilities and verify setups.
.entity_set with(domain='apm', name='apm.service') | entity-call __list_method__()API Usage
UI
In the CloudMonitor 2.0 console users can enter SPL queries directly, enable DryRun mode, and view results.
.entity_set with(domain='apm', name='apm.service', ids=['21d5ed...']) | entity-call get_metric('apm','apm.metric.apm.service','avg_request_latency_seconds','range','',false)SDK (Go)
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() (*cms20240330.Client, error) {
cred, err := credential.NewCredential(nil)
if err != nil { return nil, err }
cfg := &openapi.Config{Credential: cred}
cfg.Endpoint = tea.String("cms.cn-hangzhou.aliyuncs.com")
return cms20240330.NewClient(cfg)
}
func main() {
client, err := CreateClient()
if err != nil { panic(err) }
req := &cms20240330.GetEntityStoreDataRequest{Query: tea.String(".entity_set with(domain='apm', name='apm.service', ids=['21d5ed...']) | entity-call get_metric('apm','apm.metric.apm.service','avg_request_latency_seconds','range')"), From: tea.Int32(1762244123), To: tea.Int32(1762244724)}
resp, err := client.GetEntityStoreData(tea.String("o11y-demo-cn-hangzhou"), req)
if err != nil { panic(err) }
fmt.Printf("length: %d", len(resp.Body.Data))
}Advanced Scenarios
Time‑Series Anomaly Detection
Integrate the series_decompose_anomalies operator for one‑line anomaly detection:
.entity_set with(domain='apm', name='apm.service', ids=['21d5ed...']) | 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__Supported anomaly types: SPIKE_UP, SPIKE_DOWN, TREND_SHIFT_UP, TREND_SHIFT_DOWN, LEVEL_SHIFT_UP, LEVEL_SHIFT_DOWN.
Cross‑Store Data Join
Join custom business LogStore data with UModel entities:
.let failed_log = .logstore with(project='xxx', logstore='xxxx', query='*') | project trace_id, msg;
.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 msgAI Agent Integration
Wrap the API in MCP Tools and use the reflection method __list_method__() so an AI agent can discover available methods (e.g., get_metric, get_log, list_related_entity_set) and autonomously perform root‑cause analysis.
References
Phase 1 Table Mode – https://help.aliyun.com/zh/cms/cloudmonitor-2-0/phase-1-table-mode
Phase 2 Object Mode – https://help.aliyun.com/zh/cms/cloudmonitor-2-0/phase-2-object-mode-service-discovery
Aliyun OpenAPI – GetEntityStoreData: https://api.aliyun.com/api/Cms/2024-03-30/GetEntityStoreData
MCP Tools Documentation – https://modelcontextprotocol.io/docs/getting-started/intro
Alibaba Cloud Observability
Driving continuous progress in observability technology!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
