@cvtoolman/huawei-lts-cli 2.0.0 → 2.1.1

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/dist/cli/index.js CHANGED
@@ -65,25 +65,25 @@ program
65
65
  .name('lts-cli')
66
66
  .description('Huawei Cloud LTS (Log Tank Service) CLI — query logs from the terminal')
67
67
  .version(readVersion())
68
- .addHelpText('after', `
69
- Examples:
70
- $ lts-cli init Setup credentials interactively
71
- $ lts-cli init --from-url <url> Import region/groupId/streamId from a console URL
72
- $ lts-cli config --list Show current configuration
73
- $ lts-cli groups List log groups
74
- $ lts-cli streams List log streams in a group
75
- $ lts-cli fields Show the index config of a log stream
76
- $ lts-cli query --last 2h -q 'level:error' --all
77
- $ lts-cli trace <requestId> Fetch the full request chain
78
-
79
- Environment variables:
80
- LTS_AK Access Key
81
- LTS_SK Secret Key
82
- LTS_PROJECT_ID Project ID
83
- LTS_REGION Region
84
- LTS_ENDPOINT Service endpoint
85
- LTS_GROUP_ID Default log group ID
86
- LTS_STREAM_ID Default log stream ID
68
+ .addHelpText('after', `
69
+ Examples:
70
+ $ lts-cli init Setup credentials interactively
71
+ $ lts-cli init --from-url <url> Import region/groupId/streamId from a console URL
72
+ $ lts-cli config --list Show current configuration
73
+ $ lts-cli groups List log groups
74
+ $ lts-cli streams List log streams in a group
75
+ $ lts-cli fields Show the index config of a log stream
76
+ $ lts-cli query --last 2h -q 'level:error' --all
77
+ $ lts-cli trace <requestId> Fetch the full request chain
78
+
79
+ Environment variables:
80
+ LTS_AK Access Key
81
+ LTS_SK Secret Key
82
+ LTS_PROJECT_ID Project ID
83
+ LTS_REGION Region
84
+ LTS_ENDPOINT Service endpoint
85
+ LTS_GROUP_ID Default log group ID
86
+ LTS_STREAM_ID Default log stream ID
87
87
  `);
88
88
  program.addCommand((0, init_1.createInitCommand)());
89
89
  program.addCommand((0, query_1.createQueryCommand)());
@@ -99,6 +99,7 @@ program.addCommand((0, config_1.createConfigCommand)());
99
99
  */
100
100
  const QUERY_OPTS = '-g --group-id -s --stream-id --start-time --end-time --st --et --last -q --query --app --content --request-id -l --limit -r --reverse -f --format --all';
101
101
  const TRACE_OPTS = '-g --group-id -s --stream-id --field --last --start-time --end-time --st --et -l --limit -f --format';
102
+ const CONTEXT_OPTS = '-g --group-id -s --stream-id --line-num --time --before --after -f --format';
102
103
  const VALUE_OPTS = '-g --group-id -s --stream-id -f --format';
103
104
  // Shell completion support
104
105
  const completionCmd = new commander_1.Command('completion')
@@ -107,179 +108,200 @@ const completionCmd = new commander_1.Command('completion')
107
108
  .action((shell) => {
108
109
  switch (shell) {
109
110
  case 'bash':
110
- console.log(`# lts-cli bash completion — add to ~/.bashrc or ~/.bash_profile
111
- _lts_cli_completion() {
112
- local words cword
113
- _get_comp_words_by_ref -n : words cword
114
- local cur="\${words[cword]}"
115
-
116
- if (( cword == 1 )); then
117
- COMPREPLY=( $(compgen -W "query trace context groups streams fields config init completion" -- "\$cur") )
118
- return
119
- fi
120
-
121
- local cmd="\${words[1]}"
122
- case "\$cmd" in
123
- query)
124
- case "\$prev" in
125
- -g|--group-id|-s|--stream-id|-q|--query|--app|--content|--request-id|-l|--limit|-f|--format)
126
- COMPREPLY=()
127
- return
128
- ;;
129
- *)
130
- COMPREPLY=( $(compgen -W "${QUERY_OPTS}" -- "\$cur") )
131
- return
132
- ;;
133
- esac
134
- ;;
135
- trace)
136
- case "\$prev" in
137
- -g|--group-id|-s|--stream-id|--field|--last|-l|--limit|-f|--format)
138
- COMPREPLY=()
139
- return
140
- ;;
141
- *)
142
- COMPREPLY=( $(compgen -W "${TRACE_OPTS}" -- "\$cur") )
143
- return
144
- ;;
145
- esac
146
- ;;
147
- fields)
148
- COMPREPLY=( $(compgen -W "${VALUE_OPTS}" -- "\$cur") )
149
- return
150
- ;;
151
- config)
152
- COMPREPLY=( $(compgen -W "--set --get --list --unset" -- "\$cur") )
153
- return
154
- ;;
155
- completion)
156
- COMPREPLY=( $(compgen -W "bash zsh powershell" -- "\$cur") )
157
- return
158
- ;;
159
- *)
160
- COMPREPLY=()
161
- return
162
- ;;
163
- esac
164
- }
111
+ console.log(`# lts-cli bash completion — add to ~/.bashrc or ~/.bash_profile
112
+ _lts_cli_completion() {
113
+ local words cword
114
+ _get_comp_words_by_ref -n : words cword
115
+ local cur="\${words[cword]}"
116
+ local prev="\${words[cword-1]}"
117
+
118
+ if (( cword == 1 )); then
119
+ COMPREPLY=( $(compgen -W "query trace context groups streams fields config init completion" -- "\$cur") )
120
+ return
121
+ fi
122
+
123
+ local cmd="\${words[1]}"
124
+ case "\$cmd" in
125
+ query)
126
+ case "\$prev" in
127
+ -g|--group-id|-s|--stream-id|-q|--query|--app|--content|--request-id|--start-time|--end-time|--st|--et|--last|-l|--limit|-f|--format)
128
+ COMPREPLY=()
129
+ return
130
+ ;;
131
+ *)
132
+ COMPREPLY=( $(compgen -W "${QUERY_OPTS}" -- "\$cur") )
133
+ return
134
+ ;;
135
+ esac
136
+ ;;
137
+ trace)
138
+ case "\$prev" in
139
+ -g|--group-id|-s|--stream-id|--field|--start-time|--end-time|--st|--et|--last|-l|--limit|-f|--format)
140
+ COMPREPLY=()
141
+ return
142
+ ;;
143
+ *)
144
+ COMPREPLY=( $(compgen -W "${TRACE_OPTS}" -- "\$cur") )
145
+ return
146
+ ;;
147
+ esac
148
+ ;;
149
+ context)
150
+ case "\$prev" in
151
+ -g|--group-id|-s|--stream-id|--line-num|--time|--before|--after|-f|--format)
152
+ COMPREPLY=()
153
+ return
154
+ ;;
155
+ *)
156
+ COMPREPLY=( $(compgen -W "${CONTEXT_OPTS}" -- "\$cur") )
157
+ return
158
+ ;;
159
+ esac
160
+ ;;
161
+ groups)
162
+ COMPREPLY=( $(compgen -W "-f --format" -- "\$cur") )
163
+ return
164
+ ;;
165
+ streams)
166
+ COMPREPLY=( $(compgen -W "${VALUE_OPTS}" -- "\$cur") )
167
+ return
168
+ ;;
169
+ fields)
170
+ COMPREPLY=( $(compgen -W "${VALUE_OPTS}" -- "\$cur") )
171
+ return
172
+ ;;
173
+ config)
174
+ COMPREPLY=( $(compgen -W "--set --get --list --unset" -- "\$cur") )
175
+ return
176
+ ;;
177
+ completion)
178
+ COMPREPLY=( $(compgen -W "bash zsh powershell" -- "\$cur") )
179
+ return
180
+ ;;
181
+ *)
182
+ COMPREPLY=()
183
+ return
184
+ ;;
185
+ esac
186
+ }
165
187
  complete -F _lts_cli_completion lts-cli`);
166
188
  break;
167
189
  case 'zsh':
168
- console.log(`# lts-cli zsh completion — add to ~/.zshrc
169
- #compdef lts-cli
170
- _lts_cli() {
171
- local -a commands
172
- commands=(
173
- 'query:Query LTS logs'
174
- 'trace:Trace a request by ID'
175
- 'context:View logs before/after a log entry'
176
- 'groups:List log groups'
177
- 'streams:List log streams'
178
- 'fields:Show the index config of a log stream'
179
- 'config:Manage configuration'
180
- 'init:Interactive setup wizard'
181
- 'completion:Generate shell completion script'
182
- )
183
-
184
- local context state state_descr line
185
- typeset -A opt_args
186
-
187
- _arguments -C \\
188
- '1: :->command' \\
189
- '*:: :->args'
190
-
191
- case "\$state" in
192
- command)
193
- _describe 'command' commands
194
- ;;
195
- args)
196
- case "\$line[1]" in
197
- query)
198
- _arguments \\
199
- '-g[Log group ID]:group ID:' \\
200
- '-s[Log stream ID]:stream ID:' \\
201
- '--start-time[Start time (ISO 8601)]:time:' \\
202
- '--end-time[End time (ISO 8601)]:time:' \\
203
- '--st[Alias for --start-time]:time:' \\
204
- '--et[Alias for --end-time]:time:' \\
205
- '--last[Relative range: 30m, 2h, 1d, 7d]:duration:' \\
206
- '-q[Query expression]:query:' \\
207
- '--app[Filter by appName]:appName:' \\
208
- '--content[Filter by content]:keyword:' \\
209
- '--request-id[Filter by REQUEST_ID]:id:' \\
210
- '-l[Page size]:number:' \\
211
- '-r[Reverse order]' \\
212
- '-f[Output format]:format:(json table pretty)' \\
213
- '--all[Follow the cursor to the end]'
214
- ;;
215
- trace)
216
- _arguments \\
217
- '-g[Log group ID]:group ID:' \\
218
- '-s[Log stream ID]:stream ID:' \\
219
- '--field[Field to match]:field:' \\
220
- '--last[Relative range: 30m, 2h, 1d, 7d]:duration:' \\
221
- '--start-time[Start time (ISO 8601)]:time:' \\
222
- '--end-time[End time (ISO 8601)]:time:' \\
223
- '--st[Alias for --start-time]:time:' \\
224
- '--et[Alias for --end-time]:time:' \\
225
- '-l[Max logs]:number:' \\
226
- '-f[Output format]:format:(json table pretty)'
227
- ;;
228
- fields|groups|streams)
229
- _arguments \\
230
- '-g[Log group ID]:group ID:' \\
231
- '-s[Log stream ID]:stream ID:' \\
232
- '-f[Output format]:format:(json table pretty)'
233
- ;;
234
- config)
235
- _arguments \\
236
- '--set[Set config value]:key=value:' \\
237
- '--get[Get config value]:key:' \\
238
- '--list[List all config]' \\
239
- '--unset[Remove config value]:key:'
240
- ;;
241
- completion)
242
- _values 'shell' bash zsh powershell
243
- ;;
244
- esac
245
- ;;
246
- esac
247
- }
190
+ console.log(`# lts-cli zsh completion — add to ~/.zshrc
191
+ #compdef lts-cli
192
+ _lts_cli() {
193
+ local -a commands
194
+ commands=(
195
+ 'query:Query LTS logs'
196
+ 'trace:Trace a request by ID'
197
+ 'context:View logs before/after a log entry'
198
+ 'groups:List log groups'
199
+ 'streams:List log streams'
200
+ 'fields:Show the index config of a log stream'
201
+ 'config:Manage configuration'
202
+ 'init:Interactive setup wizard'
203
+ 'completion:Generate shell completion script'
204
+ )
205
+
206
+ local context state state_descr line
207
+ typeset -A opt_args
208
+
209
+ _arguments -C \\
210
+ '1: :->command' \\
211
+ '*:: :->args'
212
+
213
+ case "\$state" in
214
+ command)
215
+ _describe 'command' commands
216
+ ;;
217
+ args)
218
+ case "\$line[1]" in
219
+ query)
220
+ _arguments \\
221
+ '-g[Log group ID]:group ID:' \\
222
+ '-s[Log stream ID]:stream ID:' \\
223
+ '--start-time[Start time (ISO 8601)]:time:' \\
224
+ '--end-time[End time (ISO 8601)]:time:' \\
225
+ '--st[Alias for --start-time]:time:' \\
226
+ '--et[Alias for --end-time]:time:' \\
227
+ '--last[Relative range: 30m, 2h, 1d, 7d]:duration:' \\
228
+ '-q[Query expression]:query:' \\
229
+ '--app[Filter by appName]:appName:' \\
230
+ '--content[Filter by content]:keyword:' \\
231
+ '--request-id[Filter by REQUEST_ID]:id:' \\
232
+ '-l[Page size]:number:' \\
233
+ '-r[Reverse order]' \\
234
+ '-f[Output format]:format:(json table pretty)' \\
235
+ '--all[Follow the cursor to the end]'
236
+ ;;
237
+ trace)
238
+ _arguments \\
239
+ '-g[Log group ID]:group ID:' \\
240
+ '-s[Log stream ID]:stream ID:' \\
241
+ '--field[Field to match]:field:' \\
242
+ '--last[Relative range: 30m, 2h, 1d, 7d]:duration:' \\
243
+ '--start-time[Start time (ISO 8601)]:time:' \\
244
+ '--end-time[End time (ISO 8601)]:time:' \\
245
+ '--st[Alias for --start-time]:time:' \\
246
+ '--et[Alias for --end-time]:time:' \\
247
+ '-l[Max logs]:number:' \\
248
+ '-f[Output format]:format:(json table pretty)'
249
+ ;;
250
+ fields|groups|streams)
251
+ _arguments \\
252
+ '-g[Log group ID]:group ID:' \\
253
+ '-s[Log stream ID]:stream ID:' \\
254
+ '-f[Output format]:format:(json table pretty)'
255
+ ;;
256
+ config)
257
+ _arguments \\
258
+ '--set[Set config value]:key=value:' \\
259
+ '--get[Get config value]:key:' \\
260
+ '--list[List all config]' \\
261
+ '--unset[Remove config value]:key:'
262
+ ;;
263
+ completion)
264
+ _values 'shell' bash zsh powershell
265
+ ;;
266
+ esac
267
+ ;;
268
+ esac
269
+ }
248
270
  compdef _lts_cli lts-cli`);
249
271
  break;
250
272
  case 'powershell':
251
- console.log(`# lts-cli PowerShell completion — add to $PROFILE
252
- Register-ArgumentCompleter -CommandName lts-cli -ScriptBlock {
253
- param(\$wordToComplete, \$commandAst, \$cursorPosition)
254
-
255
- \$commands = @('query', 'trace', 'context', 'groups', 'streams', 'fields', 'config', 'init', 'completion')
256
-
257
- \$args = \$commandAst.ToString() -split '\\s+'
258
- if (\$args.Count -le 1) {
259
- return \$commands | Where-Object { \$_ -like "\$wordToComplete*" }
260
- }
261
-
262
- switch (\$args[1]) {
263
- 'query' {
264
- \$opts = @('-g', '-s', '--start-time', '--end-time', '--st', '--et', '--last', '-q', '--app', '--content', '--request-id', '-l', '-r', '-f', '--all')
265
- return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
266
- }
267
- 'trace' {
268
- \$opts = @('-g', '-s', '--field', '--last', '--start-time', '--end-time', '--st', '--et', '-l', '-f')
269
- return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
270
- }
271
- 'fields' {
272
- \$opts = @('-g', '-s', '-f')
273
- return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
274
- }
275
- 'config' {
276
- \$opts = @('--set', '--get', '--list', '--unset')
277
- return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
278
- }
279
- 'completion' {
280
- return @('bash', 'zsh', 'powershell') | Where-Object { \$_ -like "\$wordToComplete*" }
281
- }
282
- }
273
+ console.log(`# lts-cli PowerShell completion — add to $PROFILE
274
+ Register-ArgumentCompleter -CommandName lts-cli -ScriptBlock {
275
+ param(\$wordToComplete, \$commandAst, \$cursorPosition)
276
+
277
+ \$commands = @('query', 'trace', 'context', 'groups', 'streams', 'fields', 'config', 'init', 'completion')
278
+
279
+ \$args = \$commandAst.ToString() -split '\\s+'
280
+ if (\$args.Count -le 1) {
281
+ return \$commands | Where-Object { \$_ -like "\$wordToComplete*" }
282
+ }
283
+
284
+ switch (\$args[1]) {
285
+ 'query' {
286
+ \$opts = @('-g', '-s', '--start-time', '--end-time', '--st', '--et', '--last', '-q', '--app', '--content', '--request-id', '-l', '-r', '-f', '--all')
287
+ return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
288
+ }
289
+ 'trace' {
290
+ \$opts = @('-g', '-s', '--field', '--last', '--start-time', '--end-time', '--st', '--et', '-l', '-f')
291
+ return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
292
+ }
293
+ 'fields' {
294
+ \$opts = @('-g', '-s', '-f')
295
+ return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
296
+ }
297
+ 'config' {
298
+ \$opts = @('--set', '--get', '--list', '--unset')
299
+ return \$opts | Where-Object { \$_ -like "\$wordToComplete*" }
300
+ }
301
+ 'completion' {
302
+ return @('bash', 'zsh', 'powershell') | Where-Object { \$_ -like "\$wordToComplete*" }
303
+ }
304
+ }
283
305
  }`);
284
306
  break;
285
307
  default:
@@ -1,8 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.LTSClient = void 0;
4
37
  exports.resolveTimeRange = resolveTimeRange;
5
38
  exports.parseQueryExpression = parseQueryExpression;
39
+ exports.anchorTimeFromLineNum = anchorTimeFromLineNum;
40
+ const path = __importStar(require("path"));
6
41
  const LtsClient_1 = require("@huaweicloud/huaweicloud-sdk-lts/v2/LtsClient");
7
42
  const ClientBuilder_1 = require("@huaweicloud/huaweicloud-sdk-core/ClientBuilder");
8
43
  const BasicCredentials_1 = require("@huaweicloud/huaweicloud-sdk-core/auth/BasicCredentials");
@@ -15,6 +50,32 @@ const ListLogGroupsRequest_1 = require("@huaweicloud/huaweicloud-sdk-lts/v2/mode
15
50
  const ListLogStreamsRequest_1 = require("@huaweicloud/huaweicloud-sdk-lts/v2/model/ListLogStreamsRequest");
16
51
  const ListLogStreamIndexRequest_1 = require("@huaweicloud/huaweicloud-sdk-lts/v2/model/ListLogStreamIndexRequest");
17
52
  const pagination_1 = require("./pagination");
53
+ /**
54
+ * 华为云 SDK 把 log4js 的 console appender 指向 stdout,任何 API 错误都会把整个
55
+ * axios 错误对象(含 Authorization 头)倒进 stdout——`-f json` 的输出因此变成
56
+ * 不可解析的混合体。这里把 SDK 日志改道 stderr 并默认关闭:CLI 自己会打印
57
+ * 一行可读的错误,6KB 的 axios dump 只会淹没它。要排查 SDK 层问题时设
58
+ * LTS_CLI_DEBUG=1。
59
+ *
60
+ * 解析到的必须是 SDK 自己那个 log4js 实例,否则 configure 改的是另一份模块状态。
61
+ * 拿不到就保持原状:日志难看,但不影响结果本身。
62
+ */
63
+ function configureSdkLogger() {
64
+ try {
65
+ const corePkg = require.resolve('@huaweicloud/huaweicloud-sdk-core/package.json');
66
+ const log4js = require(require.resolve('log4js', { paths: [path.dirname(corePkg)] }));
67
+ log4js.configure({
68
+ appenders: { sdkStderr: { type: 'stderr' } },
69
+ categories: {
70
+ default: { appenders: ['sdkStderr'], level: process.env.LTS_CLI_DEBUG ? 'all' : 'off' },
71
+ },
72
+ });
73
+ }
74
+ catch {
75
+ /* 无法改道时不做任何事 */
76
+ }
77
+ }
78
+ configureSdkLogger();
18
79
  function sleep(ms) {
19
80
  return new Promise((resolve) => setTimeout(resolve, ms));
20
81
  }
@@ -71,6 +132,14 @@ function parseQueryExpression(expr) {
71
132
  }
72
133
  return { keywords: trimmed, isAnalysisQuery: false };
73
134
  }
135
+ /**
136
+ * line_num 是 19 位纳秒时间戳,前 13 位就是毫秒(实测与日志时间严格对齐)。
137
+ * `context` 接口要求传毫秒时间戳,而 LTS 的日志记录本身不带时间字段,只能从
138
+ * line_num 推。格式不符时返回 undefined,让调用方要求显式 --time。
139
+ */
140
+ function anchorTimeFromLineNum(lineNum) {
141
+ return /^\d{19}$/.test(lineNum) ? lineNum.slice(0, 13) : undefined;
142
+ }
74
143
  /** 服务端默认在命中词上包裹 <HighLightTag>,输出前剥离 */
75
144
  function stripHighlightTags(value) {
76
145
  return value.replace(/<\/?HighLightTag>/g, '');
@@ -118,7 +187,7 @@ class LTSClient {
118
187
  // 游标翻页:首屏不带游标,后续页把上一页末条的 line_num 当作续读起点
119
188
  if (params.lineNum) {
120
189
  queryParams.withLineNum(params.lineNum);
121
- queryParams.withSearchType(params.searchType ?? (0, pagination_1.cursorDirection)(params.reverse));
190
+ queryParams.withSearchType(params.searchType ?? pagination_1.CONTINUE_SEARCH_TYPE);
122
191
  }
123
192
  const request = new ListLogsRequest_1.ListLogsRequest(params.groupId, params.streamId, 'application/json')
124
193
  .withBody(queryParams);