@lark-apaas/miaoda-cli 0.1.4-alpha.e76a6d6 → 0.1.4-alpha.f78c7e5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/api/deploy/index.js +1 -12
- package/dist/api/observability/api.js +10 -0
- package/dist/api/observability/index.js +2 -1
- package/dist/cli/commands/app/index.js +2 -83
- package/dist/cli/commands/index.js +5 -33
- package/dist/cli/commands/observability/index.js +62 -6
- package/dist/cli/commands/shared.js +5 -0
- package/dist/cli/handlers/app/index.js +1 -6
- package/dist/cli/handlers/observability/helpers.js +4 -0
- package/dist/cli/handlers/observability/index.js +3 -1
- package/dist/cli/handlers/observability/log.js +8 -2
- package/dist/cli/handlers/observability/source-stack.js +389 -0
- package/dist/cli/handlers/observability/trace.js +7 -1
- package/dist/utils/git.js +22 -0
- package/dist/utils/http.js +11 -13
- package/package.json +1 -1
- package/dist/api/deploy/modern-types.js +0 -23
- package/dist/api/deploy/modern.js +0 -70
- package/dist/api/deploy/plugin-instances-types.js +0 -6
- package/dist/api/deploy/plugin-instances.js +0 -30
- package/dist/cli/commands/deploy/modern.js +0 -48
- package/dist/cli/commands/skills/index.js +0 -63
- package/dist/cli/handlers/app/init.js +0 -84
- package/dist/cli/handlers/deploy/modern.js +0 -32
- package/dist/cli/handlers/skills/index.js +0 -7
- package/dist/cli/handlers/skills/status.js +0 -31
- package/dist/cli/handlers/skills/sync.js +0 -38
- package/dist/services/app/init/index.js +0 -12
- package/dist/services/app/init/install.js +0 -101
- package/dist/services/app/init/template.js +0 -86
- package/dist/services/deploy/modern/atoms/build.js +0 -54
- package/dist/services/deploy/modern/atoms/context.js +0 -30
- package/dist/services/deploy/modern/atoms/index.js +0 -17
- package/dist/services/deploy/modern/atoms/local-release.js +0 -27
- package/dist/services/deploy/modern/atoms/pre-release.js +0 -13
- package/dist/services/deploy/modern/atoms/save-plugin-instances.js +0 -72
- package/dist/services/deploy/modern/atoms/upload.js +0 -205
- package/dist/services/deploy/modern/check.js +0 -58
- package/dist/services/deploy/modern/constants.js +0 -13
- package/dist/services/deploy/modern/index.js +0 -16
- package/dist/services/deploy/modern/pipelines/index.js +0 -5
- package/dist/services/deploy/modern/pipelines/local.js +0 -75
- package/dist/services/deploy/modern/protocol.js +0 -43
- package/dist/services/deploy/modern/run-types.js +0 -4
- package/dist/services/deploy/modern/run.js +0 -13
- package/dist/services/deploy/modern/template-key-map.js +0 -22
- package/dist/services/skills/index.js +0 -5
- package/dist/services/skills/status.js +0 -37
- package/dist/utils/coding-steering.js +0 -85
- package/dist/utils/npm-pack.js +0 -55
- package/dist/utils/spark-meta.js +0 -42
package/README.md
CHANGED
|
@@ -36,10 +36,11 @@ miaoda file ls --output json
|
|
|
36
36
|
|
|
37
37
|
命令以"域"作为第一级命名空间:
|
|
38
38
|
|
|
39
|
-
| 域
|
|
40
|
-
|
|
41
|
-
| `miaoda file ...`
|
|
42
|
-
| `miaoda db ...`
|
|
39
|
+
| 域 | 用途 |
|
|
40
|
+
| -------------------------- | ---------------------------------------------------- |
|
|
41
|
+
| `miaoda file ...` | 文件操作:上传、下载、元数据、签名下载、批量删除 |
|
|
42
|
+
| `miaoda db ...` | 数据操作:SQL 执行、表结构查询、数据导入导出 |
|
|
43
|
+
| `miaoda observability ...` | 线上日志、链路、前端源码堆栈反查、监控指标、运营指标 |
|
|
43
44
|
|
|
44
45
|
完整命令通过 `miaoda --help` 或 `miaoda <domain> --help` 查看。
|
|
45
46
|
|
package/dist/api/deploy/index.js
CHANGED
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NodeStatus = exports.nodeStatusFromText = exports.nodeStatusText = exports.errorJobSchema = exports.deployGetSchema = exports.deployHistorySchema = exports.
|
|
3
|
+
exports.NodeStatus = exports.nodeStatusFromText = exports.nodeStatusText = exports.errorJobSchema = exports.deployGetSchema = exports.deployHistorySchema = exports.queryPipelineInstance = exports.getErrorLog = exports.listPipelineInstances = exports.createRelease = void 0;
|
|
4
4
|
var api_1 = require("./api");
|
|
5
5
|
Object.defineProperty(exports, "createRelease", { enumerable: true, get: function () { return api_1.createRelease; } });
|
|
6
6
|
Object.defineProperty(exports, "listPipelineInstances", { enumerable: true, get: function () { return api_1.listPipelineInstances; } });
|
|
7
7
|
Object.defineProperty(exports, "getErrorLog", { enumerable: true, get: function () { return api_1.getErrorLog; } });
|
|
8
8
|
Object.defineProperty(exports, "queryPipelineInstance", { enumerable: true, get: function () { return api_1.queryPipelineInstance; } });
|
|
9
|
-
var modern_1 = require("./modern");
|
|
10
|
-
Object.defineProperty(exports, "preRelease", { enumerable: true, get: function () { return modern_1.preRelease; } });
|
|
11
|
-
Object.defineProperty(exports, "createLocalRelease", { enumerable: true, get: function () { return modern_1.createLocalRelease; } });
|
|
12
|
-
Object.defineProperty(exports, "updateLocalRelease", { enumerable: true, get: function () { return modern_1.updateLocalRelease; } });
|
|
13
|
-
Object.defineProperty(exports, "createModernRelease", { enumerable: true, get: function () { return modern_1.createRelease; } });
|
|
14
|
-
Object.defineProperty(exports, "getModernReleaseStatus", { enumerable: true, get: function () { return modern_1.getReleaseStatus; } });
|
|
15
|
-
Object.defineProperty(exports, "getModernLastPublishedVersion", { enumerable: true, get: function () { return modern_1.getLastPublishedVersion; } });
|
|
16
|
-
var modern_types_1 = require("./modern-types");
|
|
17
|
-
Object.defineProperty(exports, "LocalReleaseStatus", { enumerable: true, get: function () { return modern_types_1.LocalReleaseStatus; } });
|
|
18
|
-
var plugin_instances_1 = require("./plugin-instances");
|
|
19
|
-
Object.defineProperty(exports, "batchSavePluginInstances", { enumerable: true, get: function () { return plugin_instances_1.batchSavePluginInstances; } });
|
|
20
9
|
var schemas_1 = require("./schemas");
|
|
21
10
|
Object.defineProperty(exports, "deployHistorySchema", { enumerable: true, get: function () { return schemas_1.deployHistorySchema; } });
|
|
22
11
|
Object.defineProperty(exports, "deployGetSchema", { enumerable: true, get: function () { return schemas_1.deployGetSchema; } });
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.searchLogs = searchLogs;
|
|
4
4
|
exports.searchTraces = searchTraces;
|
|
5
5
|
exports.getTraces = getTraces;
|
|
6
|
+
exports.resolveStackTrace = resolveStackTrace;
|
|
6
7
|
exports.queryMetricsData = queryMetricsData;
|
|
7
8
|
exports.queryAnalyticsData = queryAnalyticsData;
|
|
8
9
|
const http_1 = require("../../utils/http");
|
|
@@ -30,6 +31,15 @@ async function getTraces(req) {
|
|
|
30
31
|
defaultErrCode: DEFAULT_ERR_CODE,
|
|
31
32
|
});
|
|
32
33
|
}
|
|
34
|
+
// ── 前端源码堆栈反解 ──
|
|
35
|
+
async function resolveStackTrace(req) {
|
|
36
|
+
const url = `/v1/observability/app/${encodeURIComponent(req.appID)}/resolve_stack_trace`;
|
|
37
|
+
const { appID: _appID, ...body } = req;
|
|
38
|
+
return (0, http_1.postInnerApi)(url, body, {
|
|
39
|
+
errPrefix: 'Failed to resolve frontend source stack',
|
|
40
|
+
defaultErrCode: DEFAULT_ERR_CODE,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
33
43
|
// ── 监控指标 ──
|
|
34
44
|
async function queryMetricsData(req) {
|
|
35
45
|
const url = `/v1/observability/app/${encodeURIComponent(req.appID)}/metrics/data/query`;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StatusCode = exports.SpanKind = exports.WordOperator = exports.spanSchema = exports.logItemSchema = exports.queryAnalyticsData = exports.queryMetricsData = exports.getTraces = exports.searchTraces = exports.searchLogs = void 0;
|
|
3
|
+
exports.StatusCode = exports.SpanKind = exports.WordOperator = exports.spanSchema = exports.logItemSchema = exports.queryAnalyticsData = exports.queryMetricsData = exports.resolveStackTrace = exports.getTraces = exports.searchTraces = exports.searchLogs = void 0;
|
|
4
4
|
var api_1 = require("./api");
|
|
5
5
|
Object.defineProperty(exports, "searchLogs", { enumerable: true, get: function () { return api_1.searchLogs; } });
|
|
6
6
|
Object.defineProperty(exports, "searchTraces", { enumerable: true, get: function () { return api_1.searchTraces; } });
|
|
7
7
|
Object.defineProperty(exports, "getTraces", { enumerable: true, get: function () { return api_1.getTraces; } });
|
|
8
|
+
Object.defineProperty(exports, "resolveStackTrace", { enumerable: true, get: function () { return api_1.resolveStackTrace; } });
|
|
8
9
|
Object.defineProperty(exports, "queryMetricsData", { enumerable: true, get: function () { return api_1.queryMetricsData; } });
|
|
9
10
|
Object.defineProperty(exports, "queryAnalyticsData", { enumerable: true, get: function () { return api_1.queryAnalyticsData; } });
|
|
10
11
|
var schemas_1 = require("./schemas");
|
|
@@ -3,12 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.registerAppCommands = registerAppCommands;
|
|
4
4
|
const shared_1 = require("../../../cli/commands/shared");
|
|
5
5
|
const index_1 = require("../../../cli/handlers/app/index");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const description = opts.includeInit
|
|
9
|
-
? '应用元数据管理:查看 / 修改 / 初始化'
|
|
10
|
-
: '应用元数据管理:查看 / 修改';
|
|
11
|
-
const appCmd = program.command('app').description(description);
|
|
6
|
+
function registerAppCommands(program) {
|
|
7
|
+
const appCmd = program.command('app').description('应用元数据管理:查看 / 修改');
|
|
12
8
|
appCmd.action(() => {
|
|
13
9
|
appCmd.outputHelp();
|
|
14
10
|
});
|
|
@@ -19,9 +15,6 @@ function registerAppCommands(program, opts = {}) {
|
|
|
19
15
|
`);
|
|
20
16
|
registerAppGet(appCmd);
|
|
21
17
|
registerAppUpdate(appCmd);
|
|
22
|
-
if (opts.includeInit) {
|
|
23
|
-
registerAppInit(appCmd);
|
|
24
|
-
}
|
|
25
18
|
}
|
|
26
19
|
function registerAppGet(parent) {
|
|
27
20
|
const cmd = parent
|
|
@@ -67,77 +60,3 @@ JSON 输出
|
|
|
67
60
|
});
|
|
68
61
|
}));
|
|
69
62
|
}
|
|
70
|
-
function registerAppInit(parent) {
|
|
71
|
-
const cmd = parent
|
|
72
|
-
.command('init')
|
|
73
|
-
.description('初始化应用代码:抓 template 渲染、装 .agent/steering/ skills、写 .spark/meta.json。.spark/meta.json 已存在则直接退出')
|
|
74
|
-
.addOption((0, shared_1.appIdOption)().hideHelp())
|
|
75
|
-
.option('--template <stack>', `技术栈短名(${index_1.SUPPORTED_STACKS.join(' / ')})`)
|
|
76
|
-
.option('--conf <json>', 'init 配置 JSON。支持 {"version": "<template 版本>"} / {"steeringVersion": "<steering 版本>"},均默认 latest')
|
|
77
|
-
.option('--skip-install', '跳过依赖安装', false)
|
|
78
|
-
.addHelpText('after', `
|
|
79
|
-
幂等
|
|
80
|
-
.spark/meta.json 已存在时直接退出(initialized=false, reason=already_initialized),
|
|
81
|
-
不再触发 template 渲染、不重新拉 skills、不安装依赖。
|
|
82
|
-
meta.json 在 init 流程最后才写,写了 = 已完整成功一次;
|
|
83
|
-
上一次失败留下半渲染状态时(package.json 在但 meta.json 没在)允许重跑。
|
|
84
|
-
|
|
85
|
-
依赖安装
|
|
86
|
-
默认:npm install --no-audit --no-fund
|
|
87
|
-
--skip-install: 跳过
|
|
88
|
-
MIAODA_DEP_CACHE_DIR 环境变量:
|
|
89
|
-
若设了且 CWD 含 package.json,先算 md5(package.json),
|
|
90
|
-
命中 \${MIAODA_DEP_CACHE_DIR}/\${hash}.zip 则 unzip 复用缓存;未命中或解压后 node_modules
|
|
91
|
-
为空都会 fallback npm install。
|
|
92
|
-
JSON 模式下子进程 stdout 重定向到 stderr,避免污染最终 emit 的 JSON。
|
|
93
|
-
|
|
94
|
-
JSON 输出
|
|
95
|
-
已初始化:{"data": {"initialized": false, "reason": "already_initialized", "targetDir": "..."}}
|
|
96
|
-
新初始化:{"data": {"initialized": true, "template": "...", "templateVersion": "...", "steeringVersion": "...",
|
|
97
|
-
"installed": true, "installSource": "cache|npm|skipped", "installHash": "...", ...}}
|
|
98
|
-
|
|
99
|
-
示例
|
|
100
|
-
$ miaoda app init --template vite-react
|
|
101
|
-
$ miaoda app init --template vite-react --conf '{"version": "0.1.0-alpha.1"}'
|
|
102
|
-
$ miaoda app init --template vite-react --conf '{"steeringVersion": "0.1.0"}'
|
|
103
|
-
$ miaoda app init --template vite-react --skip-install
|
|
104
|
-
$ MIAODA_DEP_CACHE_DIR=/tmp/dep-cache miaoda app init --template vite-react
|
|
105
|
-
`);
|
|
106
|
-
cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
|
|
107
|
-
(0, shared_1.rejectCliOverride)(cmd, 'appId');
|
|
108
|
-
const conf = parseInitConf(rawOpts.conf);
|
|
109
|
-
await (0, index_1.handleAppInit)({
|
|
110
|
-
appId: (0, shared_1.resolveAppId)({ appId: rawOpts.appId }),
|
|
111
|
-
template: rawOpts.template,
|
|
112
|
-
conf,
|
|
113
|
-
skipInstall: rawOpts.skipInstall,
|
|
114
|
-
});
|
|
115
|
-
}));
|
|
116
|
-
}
|
|
117
|
-
function parseInitConf(raw) {
|
|
118
|
-
if (raw === undefined)
|
|
119
|
-
return undefined;
|
|
120
|
-
let parsed;
|
|
121
|
-
try {
|
|
122
|
-
parsed = JSON.parse(raw);
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
126
|
-
throw new error_1.AppError('ARGS_INVALID', `--conf 必须是合法 JSON:${msg}`);
|
|
127
|
-
}
|
|
128
|
-
if (!isPlainObject(parsed)) {
|
|
129
|
-
throw new error_1.AppError('ARGS_INVALID', '--conf 必须是 JSON 对象');
|
|
130
|
-
}
|
|
131
|
-
const version = parsed.version;
|
|
132
|
-
if (version !== undefined && typeof version !== 'string') {
|
|
133
|
-
throw new error_1.AppError('ARGS_INVALID', '--conf.version 必须是字符串');
|
|
134
|
-
}
|
|
135
|
-
const steeringVersion = parsed.steeringVersion;
|
|
136
|
-
if (steeringVersion !== undefined && typeof steeringVersion !== 'string') {
|
|
137
|
-
throw new error_1.AppError('ARGS_INVALID', '--conf.steeringVersion 必须是字符串');
|
|
138
|
-
}
|
|
139
|
-
return { version, steeringVersion };
|
|
140
|
-
}
|
|
141
|
-
function isPlainObject(v) {
|
|
142
|
-
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
143
|
-
}
|
|
@@ -1,43 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveScene = resolveScene;
|
|
4
3
|
exports.registerCommands = registerCommands;
|
|
5
4
|
const index_1 = require("../../cli/commands/file/index");
|
|
6
5
|
const index_2 = require("../../cli/commands/db/index");
|
|
7
6
|
const index_3 = require("../../cli/commands/observability/index");
|
|
8
7
|
const index_4 = require("../../cli/commands/app/index");
|
|
9
8
|
const index_5 = require("../../cli/commands/deploy/index");
|
|
10
|
-
const modern_1 = require("../../cli/commands/deploy/modern");
|
|
11
|
-
const index_6 = require("../../cli/commands/skills/index");
|
|
12
|
-
function resolveScene(appType, _archType) {
|
|
13
|
-
if (appType === '7')
|
|
14
|
-
return 'modern';
|
|
15
|
-
return 'default';
|
|
16
|
-
}
|
|
17
|
-
const SCENE_REGISTRARS = {
|
|
18
|
-
default: (p) => {
|
|
19
|
-
(0, index_4.registerAppCommands)(p);
|
|
20
|
-
(0, index_5.registerDeployCommands)(p);
|
|
21
|
-
(0, index_2.registerDbCommands)(p);
|
|
22
|
-
(0, index_1.registerFileCommands)(p);
|
|
23
|
-
(0, index_3.registerObservabilityCommands)(p);
|
|
24
|
-
},
|
|
25
|
-
modern: (p) => {
|
|
26
|
-
(0, index_4.registerAppCommands)(p, { includeInit: true });
|
|
27
|
-
(0, modern_1.registerDeployCommandsModern)(p);
|
|
28
|
-
(0, index_6.registerSkillsCommands)(p);
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
function readEnv(name) {
|
|
32
|
-
const v = process.env[name]?.trim();
|
|
33
|
-
return v !== undefined && v !== '' ? v : undefined;
|
|
34
|
-
}
|
|
35
9
|
function registerCommands(program) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
process.stderr.write(`[miaoda] scene=${scene} app_type=${appType ?? '-'} arch_type=${archType ?? '-'}\n`);
|
|
42
|
-
}
|
|
10
|
+
(0, index_1.registerFileCommands)(program);
|
|
11
|
+
(0, index_2.registerDbCommands)(program);
|
|
12
|
+
(0, index_3.registerObservabilityCommands)(program);
|
|
13
|
+
(0, index_4.registerAppCommands)(program);
|
|
14
|
+
(0, index_5.registerDeployCommands)(program);
|
|
43
15
|
}
|
|
@@ -14,6 +14,24 @@ const COMMON_TIME_HELP = `
|
|
|
14
14
|
1) 不带时区的形式与 pretty 输出闭环(同机器复制粘贴稳定);跨机器请带显式时区。
|
|
15
15
|
2) 必须用 T 分隔日期与时间,禁止空格——shell 会把不带引号的 'YYYY-MM-DD HH:mm:ss' 拆成两个参数。
|
|
16
16
|
`;
|
|
17
|
+
function normalizeRepeatedOption(value) {
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
const items = value.filter((item) => typeof item === 'string' && item.length > 0);
|
|
20
|
+
return items.length === 1 ? items[0] : items;
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
function normalizeRepeatedArray(value) {
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
return value.filter((item) => typeof item === 'string' && item.length > 0);
|
|
27
|
+
}
|
|
28
|
+
return typeof value === 'string' && value ? [value] : [];
|
|
29
|
+
}
|
|
30
|
+
function compactRepeatedOption(values) {
|
|
31
|
+
if (values.length === 0)
|
|
32
|
+
return undefined;
|
|
33
|
+
return values.length === 1 ? values[0] : values;
|
|
34
|
+
}
|
|
17
35
|
function registerObservabilityCommands(program) {
|
|
18
36
|
const obCmd = program
|
|
19
37
|
.command('observability')
|
|
@@ -31,6 +49,7 @@ function registerObservabilityCommands(program) {
|
|
|
31
49
|
`);
|
|
32
50
|
registerLog(obCmd);
|
|
33
51
|
registerTrace(obCmd);
|
|
52
|
+
registerSourceStack(obCmd);
|
|
34
53
|
registerMetric(obCmd);
|
|
35
54
|
registerAnalytics(obCmd);
|
|
36
55
|
}
|
|
@@ -45,8 +64,8 @@ function registerLog(parent) {
|
|
|
45
64
|
.argParser((0, shared_1.caseInsensitiveChoice)(['DEBUG', 'INFO', 'WARN', 'ERROR'])))
|
|
46
65
|
.option('--since <time>', '开始时间')
|
|
47
66
|
.option('--until <time>', '截止时间')
|
|
48
|
-
.
|
|
49
|
-
.
|
|
67
|
+
.addOption(new commander_1.Option('--log-id <id>', '按请求 logid 过滤(可重复传入)').argParser(shared_1.collectRepeatedOption))
|
|
68
|
+
.addOption(new commander_1.Option('--trace-id <id>', '按 trace ID 过滤(可重复传入)').argParser(shared_1.collectRepeatedOption))
|
|
50
69
|
.option('--grep <pattern>', '按关键字模糊搜索 body')
|
|
51
70
|
.option('--module <name>', '按模块名过滤')
|
|
52
71
|
.option('--user-id <user-id>', '按触发用户 ID 过滤')
|
|
@@ -63,7 +82,9 @@ JSON 输出
|
|
|
63
82
|
示例
|
|
64
83
|
$ miaoda observability log --since 1h --level error --json
|
|
65
84
|
$ miaoda observability log --log-id log_abc123 --json
|
|
85
|
+
$ miaoda observability log --log-id log_1 --log-id log_2 --json
|
|
66
86
|
$ miaoda observability log --trace-id 140ebb5ac9b... --json
|
|
87
|
+
$ miaoda observability log --trace-id trace_1 --trace-id trace_2 --json
|
|
67
88
|
$ miaoda observability log --api /api/orders --min-duration 200 --json
|
|
68
89
|
`);
|
|
69
90
|
cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
|
|
@@ -74,8 +95,8 @@ JSON 输出
|
|
|
74
95
|
level: rawOpts.level,
|
|
75
96
|
since: rawOpts.since,
|
|
76
97
|
until: rawOpts.until,
|
|
77
|
-
logId: rawOpts.logId,
|
|
78
|
-
traceId: rawOpts.traceId,
|
|
98
|
+
logId: normalizeRepeatedOption(rawOpts.logId),
|
|
99
|
+
traceId: normalizeRepeatedOption(rawOpts.traceId),
|
|
79
100
|
grep: rawOpts.grep,
|
|
80
101
|
module: rawOpts.module,
|
|
81
102
|
userId: rawOpts.userId,
|
|
@@ -100,7 +121,7 @@ function registerTrace(parent) {
|
|
|
100
121
|
.addOption((0, shared_1.appIdOption)().hideHelp())
|
|
101
122
|
.option('--since <time>', '开始时间')
|
|
102
123
|
.option('--until <time>', '截止时间')
|
|
103
|
-
.
|
|
124
|
+
.addOption(new commander_1.Option('--trace-id <id>', '按 trace ID 过滤(可重复传入)').argParser(shared_1.collectRepeatedOption))
|
|
104
125
|
.option('--root-span <span-name>', '按入口节点关键词过滤')
|
|
105
126
|
.option('--user-id <user-id>', '按触发用户 ID 过滤')
|
|
106
127
|
.option('--limit <n>', '返回条数上限(1~100)', parseLimit, 50)
|
|
@@ -111,6 +132,7 @@ JSON 输出
|
|
|
111
132
|
|
|
112
133
|
示例
|
|
113
134
|
$ miaoda observability trace list --since 1h --json
|
|
135
|
+
$ miaoda observability trace list --trace-id trace_1 --trace-id trace_2 --json
|
|
114
136
|
$ miaoda observability trace list --root-span api-gateway --limit 20 --json
|
|
115
137
|
`);
|
|
116
138
|
listCmd.action((0, shared_1.withHelp)(listCmd, async (rawOpts) => {
|
|
@@ -120,7 +142,7 @@ JSON 输出
|
|
|
120
142
|
appId: (0, shared_1.resolveAppId)({ appId: rawOpts.appId }),
|
|
121
143
|
since: rawOpts.since,
|
|
122
144
|
until: rawOpts.until,
|
|
123
|
-
traceId: rawOpts.traceId,
|
|
145
|
+
traceId: normalizeRepeatedOption(rawOpts.traceId),
|
|
124
146
|
rootSpan: rawOpts.rootSpan,
|
|
125
147
|
userId: rawOpts.userId,
|
|
126
148
|
limit: rawOpts.limit,
|
|
@@ -154,6 +176,40 @@ JSON 输出
|
|
|
154
176
|
});
|
|
155
177
|
}));
|
|
156
178
|
}
|
|
179
|
+
// ── source-stack ──
|
|
180
|
+
function registerSourceStack(parent) {
|
|
181
|
+
const cmd = parent
|
|
182
|
+
.command('source-stack')
|
|
183
|
+
.description('反解前端错误堆栈到源码位置')
|
|
184
|
+
.argument('[log-ids...]', '前端错误请求 logid,可传多个')
|
|
185
|
+
.addOption((0, shared_1.appIdOption)().hideHelp())
|
|
186
|
+
.addOption(new commander_1.Option('--log-id <id>', '前端错误请求 logid(可重复传入)').argParser(shared_1.collectRepeatedOption))
|
|
187
|
+
.addOption(new commander_1.Option('--trace-id <id>', '包含前端错误的 trace ID(可重复传入)').argParser(shared_1.collectRepeatedOption))
|
|
188
|
+
.option('--since <time>', '开始时间')
|
|
189
|
+
.option('--until <time>', '截止时间')
|
|
190
|
+
.option('--limit <n>', '每类查询返回条数上限(1~100)', parseLimit, 50)
|
|
191
|
+
.addHelpText('after', `${COMMON_TIME_HELP}
|
|
192
|
+
JSON 输出
|
|
193
|
+
{"data": [{"log_id": "...", "trace_id": "...", "status": "resolved", "error_message_stack": "Error: boom\\n at src/App.tsx:42:7"}], "next_cursor": null, "has_more": false}
|
|
194
|
+
|
|
195
|
+
示例
|
|
196
|
+
$ miaoda observability source-stack --log-id log_1 --log-id log_2 --json
|
|
197
|
+
$ miaoda observability source-stack --trace-id trace_1 --trace-id trace_2 --json
|
|
198
|
+
$ miaoda observability source-stack log_abc123 --json
|
|
199
|
+
`);
|
|
200
|
+
cmd.action((0, shared_1.withHelp)(cmd, async (logIds, rawOpts) => {
|
|
201
|
+
(0, shared_1.validateTimeOptions)(rawOpts, 'since', 'until');
|
|
202
|
+
(0, shared_1.rejectCliOverride)(cmd, 'appId');
|
|
203
|
+
await (0, index_1.handleObservabilitySourceStack)({
|
|
204
|
+
appId: (0, shared_1.resolveAppId)({ appId: rawOpts.appId }),
|
|
205
|
+
logId: compactRepeatedOption([...logIds, ...normalizeRepeatedArray(rawOpts.logId)]),
|
|
206
|
+
traceId: normalizeRepeatedOption(rawOpts.traceId),
|
|
207
|
+
since: rawOpts.since,
|
|
208
|
+
until: rawOpts.until,
|
|
209
|
+
limit: rawOpts.limit,
|
|
210
|
+
});
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
157
213
|
// ── metric ──
|
|
158
214
|
function registerMetric(parent) {
|
|
159
215
|
const cmd = parent
|
|
@@ -7,6 +7,7 @@ exports.softRequiredOption = softRequiredOption;
|
|
|
7
7
|
exports.resolveAppId = resolveAppId;
|
|
8
8
|
exports.withHelp = withHelp;
|
|
9
9
|
exports.caseInsensitiveChoice = caseInsensitiveChoice;
|
|
10
|
+
exports.collectRepeatedOption = collectRepeatedOption;
|
|
10
11
|
exports.validateTimeOptions = validateTimeOptions;
|
|
11
12
|
exports.rejectCliOverride = rejectCliOverride;
|
|
12
13
|
const commander_1 = require("commander");
|
|
@@ -86,6 +87,10 @@ function caseInsensitiveChoice(canonical) {
|
|
|
86
87
|
return hit;
|
|
87
88
|
};
|
|
88
89
|
}
|
|
90
|
+
/** Commander repeatable option parser:重复传入时收集为数组。 */
|
|
91
|
+
function collectRepeatedOption(value, previous = []) {
|
|
92
|
+
return [...previous, value];
|
|
93
|
+
}
|
|
89
94
|
/**
|
|
90
95
|
* --since / --until 等时间参数的 action 阶段校验。
|
|
91
96
|
*
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.handleAppUpdate = exports.handleAppGet = void 0;
|
|
4
4
|
var get_1 = require("./get");
|
|
5
5
|
Object.defineProperty(exports, "handleAppGet", { enumerable: true, get: function () { return get_1.handleAppGet; } });
|
|
6
6
|
var update_1 = require("./update");
|
|
7
7
|
Object.defineProperty(exports, "handleAppUpdate", { enumerable: true, get: function () { return update_1.handleAppUpdate; } });
|
|
8
|
-
var init_1 = require("./init");
|
|
9
|
-
Object.defineProperty(exports, "handleAppInit", { enumerable: true, get: function () { return init_1.handleAppInit; } });
|
|
10
|
-
// commands 层渲染 help 时需要这份枚举;从 handler barrel 转发,避免 commands → services 越界
|
|
11
|
-
var index_1 = require("../../../services/app/init/index");
|
|
12
|
-
Object.defineProperty(exports, "SUPPORTED_STACKS", { enumerable: true, get: function () { return index_1.SUPPORTED_STACKS; } });
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ceilMsToBucket = exports.floorMsToBucket = exports.msToSec = exports.msToNs = exports.parseToSec = exports.parseToNs = exports.parseToMs = exports.parseTimeToMs = void 0;
|
|
4
4
|
exports.eqFilter = eqFilter;
|
|
5
|
+
exports.inFilter = inFilter;
|
|
5
6
|
exports.rangeFilter = rangeFilter;
|
|
6
7
|
exports.fuzzyFilter = fuzzyFilter;
|
|
7
8
|
exports.buildFieldFilters = buildFieldFilters;
|
|
@@ -27,6 +28,9 @@ function eqFilter(value, type = 'str') {
|
|
|
27
28
|
const v = type !== 'str' ? Number(value) : value;
|
|
28
29
|
return { [type]: { eq: v } };
|
|
29
30
|
}
|
|
31
|
+
function inFilter(strs) {
|
|
32
|
+
return { str: { in: strs } };
|
|
33
|
+
}
|
|
30
34
|
/** i64 数值范围过滤 → { i64: { gte, lte } };输入接受 string(CLI flag)或 number */
|
|
31
35
|
function rangeFilter(opts) {
|
|
32
36
|
const i64 = {};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.handleObservabilityAnalytics = exports.handleObservabilityMetric = exports.handleObservabilityTraceGet = exports.handleObservabilityTraceList = exports.handleObservabilityLog = void 0;
|
|
3
|
+
exports.handleObservabilityAnalytics = exports.handleObservabilityMetric = exports.handleObservabilitySourceStack = exports.handleObservabilityTraceGet = exports.handleObservabilityTraceList = exports.handleObservabilityLog = void 0;
|
|
4
4
|
var log_1 = require("./log");
|
|
5
5
|
Object.defineProperty(exports, "handleObservabilityLog", { enumerable: true, get: function () { return log_1.handleObservabilityLog; } });
|
|
6
6
|
var trace_1 = require("./trace");
|
|
7
7
|
Object.defineProperty(exports, "handleObservabilityTraceList", { enumerable: true, get: function () { return trace_1.handleObservabilityTraceList; } });
|
|
8
8
|
Object.defineProperty(exports, "handleObservabilityTraceGet", { enumerable: true, get: function () { return trace_1.handleObservabilityTraceGet; } });
|
|
9
|
+
var source_stack_1 = require("./source-stack");
|
|
10
|
+
Object.defineProperty(exports, "handleObservabilitySourceStack", { enumerable: true, get: function () { return source_stack_1.handleObservabilitySourceStack; } });
|
|
9
11
|
var metric_1 = require("./metric");
|
|
10
12
|
Object.defineProperty(exports, "handleObservabilityMetric", { enumerable: true, get: function () { return metric_1.handleObservabilityMetric; } });
|
|
11
13
|
var analytics_1 = require("./analytics");
|
|
@@ -38,6 +38,12 @@ const api = __importStar(require("../../../api/index"));
|
|
|
38
38
|
const output_1 = require("../../../utils/output");
|
|
39
39
|
const index_1 = require("../../../api/observability/index");
|
|
40
40
|
const helpers_1 = require("./helpers");
|
|
41
|
+
function stringIdFilter(value) {
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
return value.length > 0 ? (0, helpers_1.inFilter)(value) : undefined;
|
|
44
|
+
}
|
|
45
|
+
return value ? (0, helpers_1.eqFilter)(value) : undefined;
|
|
46
|
+
}
|
|
41
47
|
/** miaoda observability log */
|
|
42
48
|
async function handleObservabilityLog(opts) {
|
|
43
49
|
const appID = opts.appId;
|
|
@@ -50,8 +56,8 @@ async function handleObservabilityLog(opts) {
|
|
|
50
56
|
// - duration_ms 暂未在 BAM 描述里明确列出,留 TODO 等 e2e 验证
|
|
51
57
|
const fieldFilters = (0, helpers_1.buildFieldFilters)([
|
|
52
58
|
{ key: 'severity_text', value: opts.level ? (0, helpers_1.eqFilter)(opts.level) : undefined },
|
|
53
|
-
{ key: 'attributes.ob_data_id', value:
|
|
54
|
-
{ key: 'trace_id', value:
|
|
59
|
+
{ key: 'attributes.ob_data_id', value: stringIdFilter(opts.logId) },
|
|
60
|
+
{ key: 'trace_id', value: stringIdFilter(opts.traceId) },
|
|
55
61
|
{ key: 'module', value: opts.module ? (0, helpers_1.eqFilter)(opts.module) : undefined },
|
|
56
62
|
{ key: 'user_id', value: opts.userId ? (0, helpers_1.eqFilter)(opts.userId, 'i64') : undefined },
|
|
57
63
|
{ key: 'page', value: opts.page ? (0, helpers_1.eqFilter)(opts.page) : undefined },
|