> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # 查询指标 Mastra 通过三种界面公开相同的五种 OLAP 查询(`getMetricAggregate`、`getMetricBreakdown`、`getMetricTimeSeries`、`getMetricPercentiles` 以及 discovery helper):进程内 store accessor、运行时 HTTP API 和 `mastra api metric` CLI。三者接受相同的 Zod 验证输入结构,因此你可以从一次性的 CLI 调查转向编程式仪表板 Tool,而无需重新学习 API。 \*\*对于 AI Agent:\*\*运行 `npx mastra api metric aggregate '{"name":"mastra_agent_duration_ms","aggregation":"avg"}'` 直接查询 Agent 平均延迟,无需编写临时脚本。查询本地指标需要运行中的 Mastra server,并配置支持 OLAP 的可观测性存储;使用 `npx mastra dev` 启动本地 server,或通过 `--url` 传入可访问 server 的 base URL。构造其他查询前,请运行 `npx mastra api metric aggregate --schema`。使用 `npx skills add mastra-ai/skills --skill mastra` 安装 Mastra Skill,获取完整的 API CLI 发现、目标选择、schema、身份验证和错误处理指南。 ## 何时使用 - 在 Studio 之外构建自定义仪表板或 KPI 卡片。 - 为 token 成本或延迟超过阈值时触发的定时告警提供数据。 - 为 Agent 提供读取自身性能指标并在聊天中解释这些指标的 Tool。 - 从终端使用 `mastra api metric ...` 进行一次性调查。 有关可观测性存储本身的设置,请参阅[指标概览](https://mastra.zisheng.pro/docs/observability/metrics/overview)。可查询的指标名称列表请参阅[自动指标参考](https://mastra.zisheng.pro/reference/observability/metrics/automatic-metrics)。 > **备注:** 指标查询由 observability domain 提供,它需要支持 OLAP 的存储(本地使用 DuckDB,生产环境使用 ClickHouse)。设置方法请参阅[指标概览](https://mastra.zisheng.pro/docs/observability/metrics/overview)。如果未配置可观测性存储,`getStore('observability')` 返回 `null`。 ## 使用界面 ### 进程内 在 Tool、server 路由或 Workflow 步骤内,从 Mastra storage 获取可观测性存储: ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const agentLatencyTool = createTool({ id: 'agentLatency', description: 'Average agent latency over the last hour.', inputSchema: z.object({}), execute: async (_input, context) => { const observability = await context.mastra!.getStorage()!.getStore('observability') if (!observability) { throw new Error('Observability domain is not configured (requires DuckDB or ClickHouse)') } const result = await observability.getMetricAggregate({ name: ['mastra_agent_duration_ms'], aggregation: 'avg', filters: { timestamp: { start: new Date(Date.now() - 60 * 60 * 1000) }, }, }) return { averageMs: result.value } }, }) ``` 当配置的后端不支持 OLAP 查询时,`getStore('observability')` 返回 `null`。 ### HTTP `mastra dev` server(以及任何已部署的 Mastra 运行时)在 `/api/observability/metrics/*` 下公开相同查询。Aggregate、breakdown、time series 和 percentile endpoint 使用 `POST` 接收 JSON body。Discovery endpoint 使用带查询参数的 `GET`。 ```bash curl -sS -X POST http://localhost:4111/api/observability/metrics/aggregate \ -H "content-type: application/json" \ -d '{"name":["mastra_agent_duration_ms"],"aggregation":"avg"}' ``` 可用路由: - `POST /api/observability/metrics/aggregate` - `POST /api/observability/metrics/breakdown` - `POST /api/observability/metrics/timeseries` - `POST /api/observability/metrics/percentiles` - `GET /api/observability/metrics`(原始行,分页) - `GET /api/observability/discovery/metric-names` - `GET /api/observability/discovery/metric-label-keys` - `GET /api/observability/discovery/metric-label-values` `@mastra/client-js` SDK 将相同路由包装为 `mastraClient.getMetricAggregate(...)`、`getMetricBreakdown(...)` 等方法。 ### CLI `mastra api metric ...` 使用一个 JSON 参数调用相同 endpoint,因此 Agent 或 shell 脚本无需编写代码即可获取指标: ```bash mastra api metric aggregate \ '{"name":["mastra_agent_duration_ms"],"aggregation":"avg"}' \ --url http://localhost:4111 ``` CLI 默认以托管的 Mastra 可观测性(`https://observability.mastra.ai`)为目标。传入 `--url http://localhost:4111` 可查询本地 `mastra dev` server。完整命令列表请参阅 [`mastra api metric aggregate`](https://mastra.zisheng.pro/reference/cli/mastra) 及其附近条目。 ## 查询 ### `getMetricAggregate` 返回单个标量,是 KPI 卡片的构建基础。 输入: - `name`:一个或多个指标名称的数组。 - `aggregation`:`'sum' | 'avg' | 'min' | 'max' | 'count' | 'count_distinct' | 'last'` 之一。 - `filters`:可选的[过滤器对象](#filtering)。 - `comparePeriod`:可选的 `'previous_period' | 'previous_day' | 'previous_week'`,用于周期对比。 响应: - `value`、`previousValue`、`changePercent`。 - 对于 token 指标,还包括 `estimatedCost`、`costUnit`、`previousEstimatedCost`、`costChangePercent`。 ```typescript const observability = await mastra.getStorage()!.getStore('observability') const cost = await observability!.getMetricAggregate({ name: ['mastra_model_total_input_tokens', 'mastra_model_total_output_tokens'], aggregation: 'sum', comparePeriod: 'previous_day', }) console.log(cost.value, cost.estimatedCost, cost.costUnit, cost.changePercent) ``` ### `getMetricBreakdown` 按一个或多个维度对行分组,并聚合每个组,是 top-N 表格(例如“按 Agent 划分的 token”)的构建基础。 输入: - `name`:指标名称数组。 - `groupBy`:用于分组的字段数组(例如 `['entityName']`)。 - `aggregation`:与上文相同的枚举。 - `limit`:server 端 top-K 上限。高基数 `groupBy` 必须提供。 - `orderDirection`:`'ASC' | 'DESC'`(默认为 `DESC`)。 - `filters`:可选。 响应:`groups[]`,每项包含 `dimensions`(组键到值的记录)、`value` 和 `estimatedCost`。 ```typescript const byAgent = await observability!.getMetricBreakdown({ name: ['mastra_model_total_input_tokens'], groupBy: ['entityName'], aggregation: 'sum', limit: 10, orderDirection: 'DESC', }) ``` ### `getMetricTimeSeries` 按固定间隔对值分桶,是折线图和柱状图的构建基础。 输入: - `name`:指标名称数组。 - `interval`:`'1m' | '5m' | '15m' | '1h' | '1d'` 之一。 - `aggregation`:与上文相同的枚举。 - `groupBy`:可选。省略时,多个指标名称会合并为一个序列。要将指标分开,请为每个指标分别调用一次。 - `filters`:可选。 响应:`series[]`,每项包含 `name`、`costUnit`,以及由 `{ timestamp, value, estimatedCost }` 组成的 `points[]`。 ```typescript const inputTokens = await observability!.getMetricTimeSeries({ name: ['mastra_model_total_input_tokens'], aggregation: 'sum', interval: '1h', filters: { timestamp: { start: new Date(Date.now() - 24 * 60 * 60 * 1000) }, }, }) ``` ### `getMetricPercentiles` 返回按时间分桶的百分位值,是延迟图表的构建基础。 输入: - `name`:单个指标名称(字符串,而不是数组)。 - `percentiles`:`0` 到 `1` 之间的数字数组,例如 `[0.5, 0.95, 0.99]`。 - `interval`:与 `getMetricTimeSeries` 相同的枚举。 - `filters`:可选。 响应:`series[]`,每项包含 `percentile` 和由 `{ timestamp, value }` 组成的 `points[]`。 ```typescript const latency = await observability!.getMetricPercentiles({ name: 'mastra_agent_duration_ms', percentiles: [0.5, 0.95], interval: '1h', }) ``` ### Discovery 使用这些 endpoint 填充下拉列表,或为 Agent 提供可用于过滤的值菜单。所有 discovery 路由都使用 `GET`,位于 `/api/observability/discovery/` 下。 **指标专用**(也作为 `mastra api metric` 子命令公开): | 方法 | 参数 | 路径后缀 | CLI | | ---------------------- | ------------------------------------------- | --------------------- | -------------------------------- | | `getMetricNames` | `{ prefix?, limit? }` | `metric-names` | `mastra api metric names` | | `getMetricLabelKeys` | `{ metricName }` | `metric-label-keys` | `mastra api metric label-keys` | | `getMetricLabelValues` | `{ metricName, labelKey, prefix?, limit? }` | `metric-label-values` | `mastra api metric label-values` | **与 Trace 和日志共享**(仅 HTTP,没有专用 CLI 子命令): | 方法 | 参数 | 路径后缀 | | ----------------- | ----------------- | --------------- | | `getEntityTypes` | `{}` | `entity-types` | | `getEntityNames` | `{ entityType? }` | `entity-names` | | `getServiceNames` | `{}` | `service-names` | | `getEnvironments` | `{}` | `environments` | | `getTags` | `{ entityType? }` | `tags` | ## 过滤 每个查询都接受相同的 `filters` 对象。最常用的字段包括: - `name`:限制为特定指标名称。(Aggregate/breakdown/time series 顶层的 `name` 已经实现此功能。当需要在单个查询中混合多个指标时,请使用 `filters.name`。) - `timestamp`:`{ start, end, startExclusive, endExclusive }`。两个边界均可选。省略 `end` 表示“直到现在”。 - `provider`、`model`、`costUnit`:用于 token 和成本指标。 - `labels`:精确匹配指标标签的键值,例如持续时间指标使用 `{ status: 'error' }`。 - 关联字段:`entityType`、`entityName`、`parentEntityName`、`rootEntityName`、`userId`、`organizationId`、`resourceId`、`runId`、`sessionId`、`threadId`、`requestId`、`executionSource`、`environment`、`serviceName`、`experimentId`、`tags`。 相同的 `filters` 结构适用于三种界面: ```typescript // In-process await observability!.getMetricAggregate({ name: ['mastra_tool_duration_ms'], aggregation: 'avg', filters: { entityName: 'weatherTool', labels: { status: 'error' } }, }) ``` ```bash # CLI mastra api metric aggregate \ '{"name":["mastra_tool_duration_ms"],"aggregation":"avg","filters":{"entityName":"weatherTool","labels":{"status":"error"}}}' \ --url http://localhost:4111 ``` ```bash # HTTP curl -sS -X POST http://localhost:4111/api/observability/metrics/aggregate \ -H "content-type: application/json" \ -d '{"name":["mastra_tool_duration_ms"],"aggregation":"avg","filters":{"entityName":"weatherTool","labels":{"status":"error"}}}' ``` ### 始终提供时间范围 `filters.timestamp` 是可选的,但对于针对生产存储运行的任何查询,都应将其视为必需。可观测性表通常按事件时间分区(TimescaleDB 则分块)。提供 `timestamp.start`(最好也提供 `end`)后,后端可以裁剪到与范围重叠的分区,通常只有一两个。没有时间范围时,planner 必须扫描每个分区;在保留一年数据的情况下可能有数百个片段,这是基于 Postgres 的存储中 OLAP 查询变慢最常见的原因。 临时查询的安全默认值是过去 24 小时;告警和仪表板应匹配其实际评估窗口: ```typescript await observability!.getMetricAggregate({ name: ['mastra_agent_duration_ms'], aggregation: 'p95', filters: { timestamp: { start: new Date(Date.now() - 24 * 60 * 60 * 1000) }, }, }) ``` 此建议适用于所有后端(ClickHouse、Postgres v-next、DuckDB),但对 Postgres v-next 尤其重要,因为每缺少一个时间边界都会直接增加一次分区扫描。 ## 示例:构建自定义 KPI 卡片 以下 Tool 返回过去一小时的输入 token 数量和预估成本。Agent 或仪表板可以将其作为 `structuredContent` 调用,而无需重新实现查询。 ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const tokenKpiTool = createTool({ id: 'tokenKpi', description: 'Returns input-token volume and estimated cost for the last hour.', inputSchema: z.object({}), outputSchema: z.object({ inputTokens: z.number().nullable(), estimatedCost: z.number().nullable(), costUnit: z.string().nullable(), changePercent: z.number().nullable(), }), execute: async (_input, context) => { const observability = await context.mastra!.getStorage()!.getStore('observability') if (!observability) { throw new Error('Observability domain is not configured (requires DuckDB or ClickHouse)') } const result = await observability.getMetricAggregate({ name: ['mastra_model_total_input_tokens'], aggregation: 'sum', filters: { timestamp: { start: new Date(Date.now() - 60 * 60 * 1000) }, }, comparePeriod: 'previous_period', }) return { inputTokens: result.value, estimatedCost: result.estimatedCost ?? null, costUnit: result.costUnit ?? null, changePercent: result.changePercent ?? null, } }, }) ``` ## 相关内容 - [指标概览](https://mastra.zisheng.pro/docs/observability/metrics/overview) - [自动指标参考](https://mastra.zisheng.pro/reference/observability/metrics/automatic-metrics) - [CLI:`mastra api metric ...`](https://mastra.zisheng.pro/reference/cli/mastra) - [Studio 可观测性](https://mastra.zisheng.pro/docs/studio/observability)