@yuku123/z-observer-component 0.0.0-stage → 0.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/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import { A as s, H as r, L as t, M as g, T as p, a as c, b as i, l as m, m as o, c as A, r as P, t as l } from "./pages-manifest-Cubmz47-.js";
2
+ export {
3
+ s as AlertPage,
4
+ r as HomePage,
5
+ t as LogSearchPage,
6
+ g as MetricPage,
7
+ p as TracePage,
8
+ c as alertApi,
9
+ i as appMeta,
10
+ m as logApi,
11
+ o as menuItems,
12
+ A as metricApi,
13
+ P as routes,
14
+ l as traceApi
15
+ };
@@ -0,0 +1,904 @@
1
+ import Te, { useState as o, useEffect as Q } from "react";
2
+ import { SearchOutlined as _e, ReloadOutlined as Se, DashboardOutlined as ke, LineChartOutlined as Oe, FileSearchOutlined as Ce, FieldTimeOutlined as Ie, AlertOutlined as Ae } from "@ant-design/icons";
3
+ import { Card as k, Button as V, Select as fe, Input as U, Table as le, Tag as $, Typography as Y, Space as N, Alert as X, Tree as Pe, Row as je, Col as L, Statistic as M, DatePicker as ze } from "antd";
4
+ import H from "dayjs";
5
+ import { TableToolbar as Ne, SearchInput as ye, ErrorState as K, EmptyState as q } from "@yuku123/z-frontend-common/ui";
6
+ import Le from "axios";
7
+ import { Link as se } from "react-router-dom";
8
+ var G = { exports: {} }, B = {};
9
+ /**
10
+ * @license React
11
+ * react-jsx-runtime.production.js
12
+ *
13
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */
18
+ var he;
19
+ function Me() {
20
+ if (he) return B;
21
+ he = 1;
22
+ var r = Symbol.for("react.transitional.element"), x = Symbol.for("react.fragment");
23
+ function u(m, i, d) {
24
+ var p = null;
25
+ if (d !== void 0 && (p = "" + d), i.key !== void 0 && (p = "" + i.key), "key" in i) {
26
+ d = {};
27
+ for (var R in i)
28
+ R !== "key" && (d[R] = i[R]);
29
+ } else d = i;
30
+ return i = d.ref, {
31
+ $$typeof: r,
32
+ type: m,
33
+ key: p,
34
+ ref: i !== void 0 ? i : null,
35
+ props: d
36
+ };
37
+ }
38
+ return B.Fragment = x, B.jsx = u, B.jsxs = u, B;
39
+ }
40
+ var W = {};
41
+ /**
42
+ * @license React
43
+ * react-jsx-runtime.development.js
44
+ *
45
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
46
+ *
47
+ * This source code is licensed under the MIT license found in the
48
+ * LICENSE file in the root directory of this source tree.
49
+ */
50
+ var pe;
51
+ function $e() {
52
+ return pe || (pe = 1, process.env.NODE_ENV !== "production" && (function() {
53
+ function r(t) {
54
+ if (t == null) return null;
55
+ if (typeof t == "function")
56
+ return t.$$typeof === Ee ? null : t.displayName || t.name || null;
57
+ if (typeof t == "string") return t;
58
+ switch (t) {
59
+ case f:
60
+ return "Fragment";
61
+ case c:
62
+ return "Profiler";
63
+ case a:
64
+ return "StrictMode";
65
+ case I:
66
+ return "Suspense";
67
+ case D:
68
+ return "SuspenseList";
69
+ case ve:
70
+ return "Activity";
71
+ case be:
72
+ return "ViewTransition";
73
+ }
74
+ if (typeof t == "object")
75
+ switch (typeof t.tag == "number" && console.error(
76
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
77
+ ), t.$$typeof) {
78
+ case j:
79
+ return "Portal";
80
+ case s:
81
+ return t.displayName || "Context";
82
+ case y:
83
+ return (t._context.displayName || "Context") + ".Consumer";
84
+ case T:
85
+ var n = t.render;
86
+ return t = t.displayName, t || (t = n.displayName || n.name || "", t = t !== "" ? "ForwardRef(" + t + ")" : "ForwardRef"), t;
87
+ case A:
88
+ return n = t.displayName || null, n !== null ? n : r(t.type) || "Memo";
89
+ case Z:
90
+ n = t._payload, t = t._init;
91
+ try {
92
+ return r(t(n));
93
+ } catch {
94
+ }
95
+ }
96
+ return null;
97
+ }
98
+ function x(t) {
99
+ return "" + t;
100
+ }
101
+ function u(t) {
102
+ try {
103
+ x(t);
104
+ var n = !1;
105
+ } catch {
106
+ n = !0;
107
+ }
108
+ if (n) {
109
+ n = console;
110
+ var h = n.error, b = typeof Symbol == "function" && Symbol.toStringTag && t[Symbol.toStringTag] || t.constructor.name || "Object";
111
+ return h.call(
112
+ n,
113
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
114
+ b
115
+ ), x(t);
116
+ }
117
+ }
118
+ function m(t) {
119
+ if (t === f) return "<>";
120
+ if (typeof t == "object" && t !== null && t.$$typeof === Z)
121
+ return "<...>";
122
+ try {
123
+ var n = r(t);
124
+ return n ? "<" + n + ">" : "<...>";
125
+ } catch {
126
+ return "<...>";
127
+ }
128
+ }
129
+ function i() {
130
+ var t = ee.A;
131
+ return t === null ? null : t.getOwner();
132
+ }
133
+ function d() {
134
+ return Error("react-stack-top-frame");
135
+ }
136
+ function p(t) {
137
+ if (oe.call(t, "key")) {
138
+ var n = Object.getOwnPropertyDescriptor(t, "key").get;
139
+ if (n && n.isReactWarning) return !1;
140
+ }
141
+ return t.key !== void 0;
142
+ }
143
+ function R(t, n) {
144
+ function h() {
145
+ ie || (ie = !0, console.error(
146
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
147
+ n
148
+ ));
149
+ }
150
+ h.isReactWarning = !0, Object.defineProperty(t, "key", {
151
+ get: h,
152
+ configurable: !0
153
+ });
154
+ }
155
+ function _() {
156
+ var t = r(this.type);
157
+ return ce[t] || (ce[t] = !0, console.error(
158
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
159
+ )), t = this.props.ref, t !== void 0 ? t : null;
160
+ }
161
+ function S(t, n, h, b, z, P) {
162
+ var E = h.ref;
163
+ return t = {
164
+ $$typeof: O,
165
+ type: t,
166
+ key: n,
167
+ props: h,
168
+ _owner: b
169
+ }, (E !== void 0 ? E : null) !== null ? Object.defineProperty(t, "ref", {
170
+ enumerable: !1,
171
+ get: _
172
+ }) : Object.defineProperty(t, "ref", { enumerable: !1, value: null }), t._store = {}, Object.defineProperty(t._store, "validated", {
173
+ configurable: !1,
174
+ enumerable: !1,
175
+ writable: !0,
176
+ value: 0
177
+ }), Object.defineProperty(t, "_debugInfo", {
178
+ configurable: !1,
179
+ enumerable: !1,
180
+ writable: !0,
181
+ value: null
182
+ }), Object.defineProperty(t, "_debugStack", {
183
+ configurable: !1,
184
+ enumerable: !1,
185
+ writable: !0,
186
+ value: z
187
+ }), Object.defineProperty(t, "_debugTask", {
188
+ configurable: !1,
189
+ enumerable: !1,
190
+ writable: !0,
191
+ value: P
192
+ }), Object.freeze && (Object.freeze(t.props), Object.freeze(t)), t;
193
+ }
194
+ function g(t, n, h, b, z, P) {
195
+ var E = n.children;
196
+ if (E !== void 0)
197
+ if (b)
198
+ if (Re(E)) {
199
+ for (b = 0; b < E.length; b++)
200
+ l(E[b]);
201
+ Object.freeze && Object.freeze(E);
202
+ } else
203
+ console.error(
204
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
205
+ );
206
+ else l(E);
207
+ if (oe.call(n, "key")) {
208
+ E = r(t);
209
+ var F = Object.keys(n).filter(function(we) {
210
+ return we !== "key";
211
+ });
212
+ b = 0 < F.length ? "{key: someKey, " + F.join(": ..., ") + ": ...}" : "{key: someKey}", me[E + b] || (F = 0 < F.length ? "{" + F.join(": ..., ") + ": ...}" : "{}", console.error(
213
+ `A props object containing a "key" prop is being spread into JSX:
214
+ let props = %s;
215
+ <%s {...props} />
216
+ React keys must be passed directly to JSX without using spread:
217
+ let props = %s;
218
+ <%s key={someKey} {...props} />`,
219
+ b,
220
+ E,
221
+ F,
222
+ E
223
+ ), me[E + b] = !0);
224
+ }
225
+ if (E = null, h !== void 0 && (u(h), E = "" + h), p(n) && (u(n.key), E = "" + n.key), "key" in n) {
226
+ h = {};
227
+ for (var re in n)
228
+ re !== "key" && (h[re] = n[re]);
229
+ } else h = n;
230
+ return E && R(
231
+ h,
232
+ typeof t == "function" ? t.displayName || t.name || "Unknown" : t
233
+ ), S(
234
+ t,
235
+ E,
236
+ h,
237
+ i(),
238
+ z,
239
+ P
240
+ );
241
+ }
242
+ function l(t) {
243
+ v(t) ? t._store && (t._store.validated = 1) : typeof t == "object" && t !== null && t.$$typeof === Z && (t._payload.status === "fulfilled" ? v(t._payload.value) && t._payload.value._store && (t._payload.value._store.validated = 1) : t._store && (t._store.validated = 1));
244
+ }
245
+ function v(t) {
246
+ return typeof t == "object" && t !== null && t.$$typeof === O;
247
+ }
248
+ var w = Te, O = Symbol.for("react.transitional.element"), j = Symbol.for("react.portal"), f = Symbol.for("react.fragment"), a = Symbol.for("react.strict_mode"), c = Symbol.for("react.profiler"), y = Symbol.for("react.consumer"), s = Symbol.for("react.context"), T = Symbol.for("react.forward_ref"), I = Symbol.for("react.suspense"), D = Symbol.for("react.suspense_list"), A = Symbol.for("react.memo"), Z = Symbol.for("react.lazy"), ve = Symbol.for("react.activity"), be = Symbol.for("react.view_transition"), Ee = Symbol.for("react.client.reference"), ee = w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, oe = Object.prototype.hasOwnProperty, Re = Array.isArray, te = console.createTask ? console.createTask : function() {
249
+ return null;
250
+ };
251
+ w = {
252
+ react_stack_bottom_frame: function(t) {
253
+ return t();
254
+ }
255
+ };
256
+ var ie, ce = {}, ue = w.react_stack_bottom_frame.bind(
257
+ w,
258
+ d
259
+ )(), de = te(m(d)), me = {};
260
+ W.Fragment = f, W.jsx = function(t, n, h) {
261
+ var b = 1e4 > ee.recentlyCreatedOwnerStacks++;
262
+ if (b) {
263
+ var z = Error.stackTraceLimit;
264
+ Error.stackTraceLimit = 10;
265
+ var P = Error("react-stack-top-frame");
266
+ Error.stackTraceLimit = z;
267
+ } else P = ue;
268
+ return g(
269
+ t,
270
+ n,
271
+ h,
272
+ !1,
273
+ P,
274
+ b ? te(m(t)) : de
275
+ );
276
+ }, W.jsxs = function(t, n, h) {
277
+ var b = 1e4 > ee.recentlyCreatedOwnerStacks++;
278
+ if (b) {
279
+ var z = Error.stackTraceLimit;
280
+ Error.stackTraceLimit = 10;
281
+ var P = Error("react-stack-top-frame");
282
+ Error.stackTraceLimit = z;
283
+ } else P = ue;
284
+ return g(
285
+ t,
286
+ n,
287
+ h,
288
+ !0,
289
+ P,
290
+ b ? te(m(t)) : de
291
+ );
292
+ };
293
+ })()), W;
294
+ }
295
+ var xe;
296
+ function De() {
297
+ return xe || (xe = 1, process.env.NODE_ENV === "production" ? G.exports = Me() : G.exports = $e()), G.exports;
298
+ }
299
+ var e = De();
300
+ const C = Le.create({ timeout: 15e3 });
301
+ C.interceptors.response.use(
302
+ (r) => r.data,
303
+ (r) => {
304
+ var u, m;
305
+ const x = ((m = (u = r == null ? void 0 : r.response) == null ? void 0 : u.data) == null ? void 0 : m.error) || r.message || "请求失败";
306
+ return Promise.reject(new Error(x));
307
+ }
308
+ );
309
+ const ne = {
310
+ /** 关键词用空格分隔是「且」关系;中文按 unigram+bigram 建索引,无需分词 */
311
+ search: (r) => C.get("/api/logs", { params: r }),
312
+ status: () => C.get("/api/logs/status")
313
+ }, ae = {
314
+ recent: (r = 20) => C.get("/api/traces", { params: { limit: r } }),
315
+ /** 后端对不存在的 traceId 返 404,不是空树 —— 「没采到」和「采到但是空」要分得开 */
316
+ tree: (r) => C.get(`/api/traces/${encodeURIComponent(r)}`)
317
+ }, J = {
318
+ list: () => C.get("/api/alerts"),
319
+ addSilence: (r) => C.post("/api/silences", r),
320
+ addInhibit: (r) => C.post("/api/inhibits", r)
321
+ }, Fe = {
322
+ instant: (r, x) => C.get("/api/metrics/query", { params: { promql: r, time: x } }),
323
+ range: (r, x, u, m) => C.get("/api/metrics/query-range", { params: { promql: r, from: x, to: u, step: m } })
324
+ }, Ye = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"], qe = {
325
+ ERROR: "red",
326
+ WARN: "orange",
327
+ INFO: "blue",
328
+ DEBUG: "default",
329
+ TRACE: "default"
330
+ };
331
+ function Be() {
332
+ const [r, x] = o(""), [u, m] = o(void 0), [i, d] = o(""), [p, R] = o(15), [_, S] = o([]), [g, l] = o(null), [v, w] = o(!1), [O, j] = o(null);
333
+ async function f(a) {
334
+ w(!0), j(null);
335
+ try {
336
+ const c = Date.now(), y = c - p * 60 * 1e3, s = { limit: 200 }, T = typeof a == "string" ? a : r;
337
+ T && (s.q = T), u && (s.level = u), i && (s.traceId = i), p > 0 && (s.from = y, s.to = c);
338
+ const [I, D] = await Promise.all([ne.search(s), ne.status()]);
339
+ S(Array.isArray(I) ? I : []), l(D);
340
+ } catch (c) {
341
+ j(c.message), S([]);
342
+ } finally {
343
+ w(!1);
344
+ }
345
+ }
346
+ return Q(() => {
347
+ f();
348
+ }, []), /* @__PURE__ */ e.jsxs(
349
+ k,
350
+ {
351
+ title: "日志检索",
352
+ extra: /* @__PURE__ */ e.jsx(N, { children: /* @__PURE__ */ e.jsx(V, { icon: /* @__PURE__ */ e.jsx(Se, {}), onClick: () => f(), loading: v, children: "刷新" }) }),
353
+ children: [
354
+ /* @__PURE__ */ e.jsx(
355
+ Ne,
356
+ {
357
+ left: /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
358
+ /* @__PURE__ */ e.jsx(
359
+ ye,
360
+ {
361
+ style: { width: 280 },
362
+ placeholder: "关键词,空格分隔为且关系",
363
+ value: r,
364
+ onChange: x,
365
+ onSearch: (a) => f(a)
366
+ }
367
+ ),
368
+ /* @__PURE__ */ e.jsx(
369
+ fe,
370
+ {
371
+ style: { width: 120 },
372
+ placeholder: "级别",
373
+ allowClear: !0,
374
+ value: u,
375
+ onChange: m,
376
+ options: Ye.map((a) => ({ label: a, value: a }))
377
+ }
378
+ ),
379
+ /* @__PURE__ */ e.jsx(
380
+ U,
381
+ {
382
+ style: { width: 240 },
383
+ placeholder: "traceId(按链路聚类)",
384
+ value: i,
385
+ onChange: (a) => d(a.target.value),
386
+ onPressEnter: () => f(),
387
+ allowClear: !0
388
+ }
389
+ ),
390
+ /* @__PURE__ */ e.jsx(
391
+ fe,
392
+ {
393
+ style: { width: 140 },
394
+ value: p,
395
+ onChange: R,
396
+ options: [5, 15, 60, 360, 1440].map((a) => ({
397
+ label: `最近 ${a} 分钟`,
398
+ value: a
399
+ }))
400
+ }
401
+ )
402
+ ] }),
403
+ right: /* @__PURE__ */ e.jsx(V, { type: "primary", icon: /* @__PURE__ */ e.jsx(_e, {}), onClick: () => f(), loading: v, children: "查询" })
404
+ }
405
+ ),
406
+ O && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ e.jsx(K, { error: O, title: "查询失败", onRetry: () => f() }) }),
407
+ /* @__PURE__ */ e.jsx(
408
+ le,
409
+ {
410
+ rowKey: (a, c) => `${a.timestampMillis}-${c}`,
411
+ size: "small",
412
+ loading: v,
413
+ dataSource: _,
414
+ pagination: { pageSize: 50, showSizeChanger: !0 },
415
+ locale: {
416
+ emptyText: /* @__PURE__ */ e.jsx(
417
+ q,
418
+ {
419
+ title: "没有匹配的日志",
420
+ description: "放宽关键词或扩大时间窗再查一次",
421
+ size: "sm"
422
+ }
423
+ )
424
+ },
425
+ columns: [
426
+ {
427
+ title: "时间",
428
+ dataIndex: "timestampMillis",
429
+ width: 170,
430
+ render: (a) => a ? H(a).format("YYYY-MM-DD HH:mm:ss.SSS") : "-"
431
+ },
432
+ {
433
+ title: "级别",
434
+ dataIndex: "level",
435
+ width: 90,
436
+ render: (a) => /* @__PURE__ */ e.jsx($, { color: qe[a], children: a })
437
+ },
438
+ { title: "线程", dataIndex: "thread", width: 120 },
439
+ { title: "logger", dataIndex: "logger", width: 220, ellipsis: !0 },
440
+ { title: "消息", dataIndex: "message", ellipsis: !0 },
441
+ {
442
+ title: "traceId",
443
+ dataIndex: "traceId",
444
+ width: 200,
445
+ ellipsis: !0,
446
+ render: (a) => a ? /* @__PURE__ */ e.jsx(Y.Text, { copyable: { text: a }, children: a }) : "-"
447
+ }
448
+ ]
449
+ }
450
+ ),
451
+ g && /* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", style: { display: "block", marginTop: 12 }, children: [
452
+ "在库 ",
453
+ g.liveLogs,
454
+ " 条,累计淘汰 ",
455
+ g.evictedLogs,
456
+ " 条"
457
+ ] })
458
+ ]
459
+ }
460
+ );
461
+ }
462
+ function We() {
463
+ const [r, x] = o([]), [u, m] = o(null), [i, d] = o(null), [p, R] = o(0), [_, S] = o(""), [g, l] = o(null), [v, w] = o(!1);
464
+ async function O() {
465
+ try {
466
+ const c = await ae.recent(50);
467
+ x(c.traceIds || []);
468
+ } catch (c) {
469
+ l(c.message);
470
+ }
471
+ }
472
+ async function j(c) {
473
+ w(!0), l(null);
474
+ try {
475
+ const y = await ae.tree(c);
476
+ d(y), R(y.orphanCount || 0), m(c);
477
+ } catch (y) {
478
+ d(null), l(y.message);
479
+ } finally {
480
+ w(!1);
481
+ }
482
+ }
483
+ Q(() => {
484
+ O();
485
+ }, []);
486
+ function f(c) {
487
+ return (c || []).map((y) => ({
488
+ key: y.spanId,
489
+ title: /* @__PURE__ */ e.jsxs(N, { size: 6, wrap: !0, children: [
490
+ /* @__PURE__ */ e.jsx($, { color: y.statusCode === "ERROR" ? "red" : "blue", children: y.name }),
491
+ /* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", children: [
492
+ y.durationMillis,
493
+ " ms"
494
+ ] }),
495
+ y.attributes && Object.keys(y.attributes).length > 0 && /* @__PURE__ */ e.jsx(Y.Text, { type: "secondary", style: { fontSize: 12 }, children: Object.entries(y.attributes).map(([s, T]) => `${s}=${T}`).join(" ") })
496
+ ] }),
497
+ children: f(y.children)
498
+ }));
499
+ }
500
+ const a = _ ? r.filter((c) => c.includes(_)) : r;
501
+ return /* @__PURE__ */ e.jsxs(N, { align: "start", size: 16, style: { width: "100%" }, children: [
502
+ /* @__PURE__ */ e.jsxs(k, { title: "最近链路", style: { width: 320 }, children: [
503
+ /* @__PURE__ */ e.jsx(
504
+ ye,
505
+ {
506
+ placeholder: "按 traceId 过滤",
507
+ value: _,
508
+ onChange: S,
509
+ style: { marginBottom: 12 }
510
+ }
511
+ ),
512
+ a.length === 0 ? /* @__PURE__ */ e.jsx(q, { title: "还没有链路数据", description: "后端还没有采集到 trace,采集恢复后这里会自动出现链路", size: "sm" }) : /* @__PURE__ */ e.jsx("div", { style: { maxHeight: 560, overflow: "auto" }, children: a.map((c) => /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 6 }, children: /* @__PURE__ */ e.jsx(
513
+ "a",
514
+ {
515
+ onClick: () => j(c),
516
+ style: {
517
+ fontWeight: u === c ? "bold" : "normal",
518
+ wordBreak: "break-all"
519
+ },
520
+ children: c
521
+ }
522
+ ) }, c)) })
523
+ ] }),
524
+ /* @__PURE__ */ e.jsxs(k, { title: "链路详情", style: { flex: 1 }, loading: v, children: [
525
+ g && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ e.jsx(K, { error: g, title: "取链路失败", onRetry: () => u && j(u) }) }),
526
+ !i && !g && /* @__PURE__ */ e.jsx(q, { title: "未选择链路", description: "从左边选一条链路", size: "sm" }),
527
+ i && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
528
+ p > 0 && /* @__PURE__ */ e.jsx(
529
+ X,
530
+ {
531
+ type: "warning",
532
+ showIcon: !0,
533
+ style: { marginBottom: 12 },
534
+ message: `有 ${p} 个 span 的父 span 不在本条链路里(跨进程调用),已保留但单独标记`
535
+ }
536
+ ),
537
+ /* @__PURE__ */ e.jsx(
538
+ Pe,
539
+ {
540
+ showLine: !0,
541
+ defaultExpandAll: !0,
542
+ treeData: f(i.roots)
543
+ }
544
+ ),
545
+ /* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", style: { display: "block", marginTop: 12 }, children: [
546
+ "traceId ",
547
+ i.traceId,
548
+ " · span ",
549
+ i.spanCount,
550
+ " 个"
551
+ ] })
552
+ ] })
553
+ ] })
554
+ ] });
555
+ }
556
+ const Ue = { critical: "red", warning: "orange", info: "blue" }, Ve = { FIRING: "red", PENDING: "orange", OK: "green", RESOLVED: "green" };
557
+ function ge(r) {
558
+ return r ? r.valueOf() : void 0;
559
+ }
560
+ function Ge() {
561
+ var y;
562
+ const [r, x] = o(null), [u, m] = o(null), [i, d] = o(!1), [p, R] = o(""), [_, S] = o(null), [g, l] = o(""), [v, w] = o(""), [O, j] = o(null);
563
+ async function f() {
564
+ d(!0), m(null);
565
+ try {
566
+ x(await J.list());
567
+ } catch (s) {
568
+ m(s.message);
569
+ } finally {
570
+ d(!1);
571
+ }
572
+ }
573
+ Q(() => {
574
+ f();
575
+ }, []);
576
+ async function a() {
577
+ if (j(null), !g) {
578
+ j("静默必须填原因 —— 事后要能回答「为什么这段时间没人收到告警」");
579
+ return;
580
+ }
581
+ const s = _ || [H(), H().add(1, "hour")];
582
+ try {
583
+ await J.addSilence({
584
+ id: `s-${Date.now()}`,
585
+ matchers: p.split(/[\s,]+/).filter(Boolean),
586
+ startMillis: ge(s[0]),
587
+ endMillis: ge(s[1]),
588
+ reason: g,
589
+ createdBy: "console"
590
+ }), j("静默已生效"), R(""), l(""), S(null), f();
591
+ } catch (T) {
592
+ j(`加静默失败:${T.message}`);
593
+ }
594
+ }
595
+ async function c() {
596
+ j(null);
597
+ const s = v.split(/[\s,]+/).filter(Boolean);
598
+ if (s.length < 2) {
599
+ j("抑制规则填两个条件:source=... target=...(如 cluster_down target=api_high_error)");
600
+ return;
601
+ }
602
+ const T = s.find((A) => A.startsWith("source=")), I = s.find((A) => A.startsWith("target=")), D = s.find((A) => A.startsWith("equal="));
603
+ if (!T || !I) {
604
+ j("抑制规则必须有 source= 与 target=");
605
+ return;
606
+ }
607
+ try {
608
+ await J.addInhibit({
609
+ id: `i-${Date.now()}`,
610
+ sourceRuleId: T.slice(7),
611
+ targetRuleId: I.slice(7),
612
+ equalLabel: D ? D.slice(6) : ""
613
+ }), j("抑制规则已生效"), f();
614
+ } catch (A) {
615
+ j(`加抑制失败:${A.message}`);
616
+ }
617
+ }
618
+ return /* @__PURE__ */ e.jsxs(N, { direction: "vertical", size: 16, style: { width: "100%" }, children: [
619
+ /* @__PURE__ */ e.jsxs(je, { gutter: 16, children: [
620
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(M, { title: "活动告警", value: ((y = r == null ? void 0 : r.active) == null ? void 0 : y.length) ?? 0 }) }) }),
621
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(M, { title: "已发通知", value: (r == null ? void 0 : r.notificationsSent) ?? 0 }) }) }),
622
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(
623
+ M,
624
+ {
625
+ title: "通知失败",
626
+ value: (r == null ? void 0 : r.notificationsFailed) ?? 0,
627
+ valueStyle: ((r == null ? void 0 : r.notificationsFailed) ?? 0) > 0 ? { color: "#cf1322" } : void 0
628
+ }
629
+ ) }) }),
630
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(
631
+ M,
632
+ {
633
+ title: "评估失败",
634
+ value: (r == null ? void 0 : r.evaluateErrorCount) ?? 0,
635
+ valueStyle: ((r == null ? void 0 : r.evaluateErrorCount) ?? 0) > 0 ? { color: "#cf1322" } : void 0
636
+ }
637
+ ) }) })
638
+ ] }),
639
+ u && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ e.jsx(K, { error: u, title: "读告警失败", onRetry: f }) }),
640
+ /* @__PURE__ */ e.jsx(k, { title: "活动告警", children: /* @__PURE__ */ e.jsx(
641
+ le,
642
+ {
643
+ rowKey: (s, T) => `${s.ruleId}-${T}`,
644
+ size: "small",
645
+ loading: i,
646
+ dataSource: (r == null ? void 0 : r.active) ?? [],
647
+ pagination: !1,
648
+ locale: { emptyText: /* @__PURE__ */ e.jsx(q, { title: "当前没有活动告警", description: "规则触发后活动告警会出现在这里", size: "sm" }) },
649
+ columns: [
650
+ { title: "规则", dataIndex: "ruleName" },
651
+ {
652
+ title: "级别",
653
+ dataIndex: "severity",
654
+ render: (s) => /* @__PURE__ */ e.jsx($, { color: Ue[s], children: s })
655
+ },
656
+ {
657
+ title: "状态",
658
+ dataIndex: "state",
659
+ render: (s) => /* @__PURE__ */ e.jsx($, { color: Ve[s], children: s })
660
+ },
661
+ {
662
+ title: "标签",
663
+ dataIndex: "labels",
664
+ render: (s) => Object.entries(s || {}).map(([T, I]) => /* @__PURE__ */ e.jsxs($, { children: [
665
+ T,
666
+ "=",
667
+ I
668
+ ] }, T))
669
+ },
670
+ { title: "取值", dataIndex: "value", render: (s) => s ?? "-" },
671
+ {
672
+ title: "开始于",
673
+ dataIndex: "activeSinceMillis",
674
+ render: (s) => s ? H(s).format("MM-DD HH:mm:ss") : "-"
675
+ }
676
+ ]
677
+ }
678
+ ) }),
679
+ /* @__PURE__ */ e.jsx(k, { title: "去噪操作", children: /* @__PURE__ */ e.jsxs(N, { direction: "vertical", style: { width: "100%" }, children: [
680
+ /* @__PURE__ */ e.jsx(He, {}),
681
+ /* @__PURE__ */ e.jsxs(N, { wrap: !0, children: [
682
+ /* @__PURE__ */ e.jsx(
683
+ U,
684
+ {
685
+ style: { width: 420 },
686
+ placeholder: "条件,空格分隔:app=z-gw 或 cluster=c1(留空=全员静默)",
687
+ value: p,
688
+ onChange: (s) => R(s.target.value)
689
+ }
690
+ ),
691
+ /* @__PURE__ */ e.jsx(
692
+ ze.RangePicker,
693
+ {
694
+ showTime: !0,
695
+ value: _,
696
+ onChange: S
697
+ }
698
+ ),
699
+ /* @__PURE__ */ e.jsx(
700
+ U,
701
+ {
702
+ style: { width: 260 },
703
+ placeholder: "原因(必填)",
704
+ value: g,
705
+ onChange: (s) => l(s.target.value)
706
+ }
707
+ ),
708
+ /* @__PURE__ */ e.jsx(V, { type: "primary", onClick: a, children: "加静默" })
709
+ ] }),
710
+ /* @__PURE__ */ e.jsxs(N.Compact, { style: { width: "100%" }, children: [
711
+ /* @__PURE__ */ e.jsx(
712
+ U,
713
+ {
714
+ style: { width: 460 },
715
+ placeholder: "抑制规则:source=cluster_down target=api_high_error equal=cluster",
716
+ value: v,
717
+ onChange: (s) => w(s.target.value)
718
+ }
719
+ ),
720
+ /* @__PURE__ */ e.jsx(V, { onClick: c, children: "加抑制" })
721
+ ] }),
722
+ O && /* @__PURE__ */ e.jsx(X, { type: "info", message: O, showIcon: !0 })
723
+ ] }) })
724
+ ] });
725
+ }
726
+ function He() {
727
+ return /* @__PURE__ */ e.jsx(
728
+ X,
729
+ {
730
+ type: "info",
731
+ showIcon: !0,
732
+ message: "静默只压通知不改状态机;抑制需要成对写,source 与 target 不能是同一条规则"
733
+ }
734
+ );
735
+ }
736
+ function Je() {
737
+ const [r, x] = o("up"), [u, m] = o([]), [i, d] = o(null), [p, R] = o(!1), [_, S] = o(!1);
738
+ async function g() {
739
+ R(!0), d(null);
740
+ try {
741
+ const l = await Fe.instant(r);
742
+ m(Array.isArray(l) ? l : []), S(!0);
743
+ } catch (l) {
744
+ d(l.message), m([]), S(!0);
745
+ } finally {
746
+ R(!1);
747
+ }
748
+ }
749
+ return /* @__PURE__ */ e.jsxs(k, { title: "指标即时查询", children: [
750
+ /* @__PURE__ */ e.jsxs(N.Compact, { style: { width: "100%", marginBottom: 16 }, children: [
751
+ /* @__PURE__ */ e.jsx(
752
+ U,
753
+ {
754
+ style: { width: 520 },
755
+ value: r,
756
+ onChange: (l) => x(l.target.value),
757
+ onPressEnter: g,
758
+ placeholder: 'PromQL,例如 up{job="z-gw"}'
759
+ }
760
+ ),
761
+ /* @__PURE__ */ e.jsx(V, { type: "primary", onClick: g, loading: p, children: "查询" })
762
+ ] }),
763
+ i && /* @__PURE__ */ e.jsx(
764
+ X,
765
+ {
766
+ type: "warning",
767
+ showIcon: !0,
768
+ style: { marginBottom: 12 },
769
+ message: "指标源不可达或表达式有误",
770
+ description: i
771
+ }
772
+ ),
773
+ /* @__PURE__ */ e.jsx(
774
+ le,
775
+ {
776
+ rowKey: (l, v) => l.seriesKey || String(v),
777
+ size: "small",
778
+ loading: p,
779
+ dataSource: u,
780
+ pagination: { pageSize: 50 },
781
+ locale: {
782
+ emptyText: _ ? /* @__PURE__ */ e.jsx(q, { title: "没有匹配的时序", description: "目标可能已下线,换个 PromQL 再查一次", size: "sm" }) : /* @__PURE__ */ e.jsx(q, { title: "尚未查询", description: "输入 PromQL 后查询", size: "sm" })
783
+ },
784
+ columns: [
785
+ {
786
+ title: "标签",
787
+ dataIndex: "labels",
788
+ render: (l) => Object.entries(l || {}).map(([v, w]) => /* @__PURE__ */ e.jsxs($, { children: [
789
+ v,
790
+ "=",
791
+ w
792
+ ] }, v))
793
+ },
794
+ {
795
+ title: "取值",
796
+ dataIndex: "value",
797
+ width: 160,
798
+ render: (l) => Number.isNaN(l) ? /* @__PURE__ */ e.jsx($, { children: "NaN" }) : String(l)
799
+ },
800
+ {
801
+ title: "采样时间",
802
+ dataIndex: "timestampMillis",
803
+ width: 200,
804
+ render: (l) => new Date(l).toLocaleString()
805
+ }
806
+ ]
807
+ }
808
+ ),
809
+ /* @__PURE__ */ e.jsx(Y.Paragraph, { type: "secondary", style: { marginTop: 12 }, children: "M1 期间指标读的是 z-env 已有的 Prometheus 本体,z-observer 自己不落时序存储; 与第三方 Prometheus / Grafana 并存是有意为之的过渡形态。" })
810
+ ] });
811
+ }
812
+ function Qe() {
813
+ var d, p, R, _, S, g, l, v, w, O, j;
814
+ const [r, x] = o(null), [u, m] = o(null), i = async () => {
815
+ try {
816
+ const [f, a, c] = await Promise.all([ne.status(), ae.recent(1), J.list()]);
817
+ x({ logs: f, traces: a, alerts: c }), m(null);
818
+ } catch (f) {
819
+ m(f.message);
820
+ }
821
+ };
822
+ return Q(() => {
823
+ i();
824
+ }, []), /* @__PURE__ */ e.jsxs(k, { title: "z-observer 概览", children: [
825
+ u && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ e.jsx(K, { error: u, title: "读状态失败", onRetry: i }) }),
826
+ /* @__PURE__ */ e.jsxs(je, { gutter: 16, children: [
827
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsxs(k, { size: "small", children: [
828
+ /* @__PURE__ */ e.jsx(
829
+ M,
830
+ {
831
+ title: /* @__PURE__ */ e.jsx(se, { to: "/z-observer/logs", children: "在库日志" }),
832
+ value: ((d = r == null ? void 0 : r.logs) == null ? void 0 : d.liveLogs) ?? "-"
833
+ }
834
+ ),
835
+ /* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
836
+ "累计淘汰 ",
837
+ ((p = r == null ? void 0 : r.logs) == null ? void 0 : p.evictedLogs) ?? "-"
838
+ ] })
839
+ ] }) }),
840
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsxs(k, { size: "small", children: [
841
+ /* @__PURE__ */ e.jsx(
842
+ M,
843
+ {
844
+ title: /* @__PURE__ */ e.jsx(se, { to: "/z-observer/traces", children: "在库链路" }),
845
+ value: ((R = r == null ? void 0 : r.traces) == null ? void 0 : R.traceCount) ?? "-"
846
+ }
847
+ ),
848
+ /* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
849
+ "累计淘汰 ",
850
+ ((_ = r == null ? void 0 : r.traces) == null ? void 0 : _.evictedTraces) ?? "-"
851
+ ] })
852
+ ] }) }),
853
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsx(k, { size: "small", children: /* @__PURE__ */ e.jsx(
854
+ M,
855
+ {
856
+ title: /* @__PURE__ */ e.jsx(se, { to: "/z-observer/alerts", children: "活动告警" }),
857
+ value: ((g = (S = r == null ? void 0 : r.alerts) == null ? void 0 : S.active) == null ? void 0 : g.length) ?? "-",
858
+ valueStyle: (((v = (l = r == null ? void 0 : r.alerts) == null ? void 0 : l.active) == null ? void 0 : v.length) ?? 0) > 0 ? { color: "#cf1322" } : void 0
859
+ }
860
+ ) }) }),
861
+ /* @__PURE__ */ e.jsx(L, { span: 6, children: /* @__PURE__ */ e.jsxs(k, { size: "small", children: [
862
+ /* @__PURE__ */ e.jsx(
863
+ M,
864
+ {
865
+ title: "通知失败",
866
+ value: ((w = r == null ? void 0 : r.alerts) == null ? void 0 : w.notificationsFailed) ?? "-",
867
+ valueStyle: (((O = r == null ? void 0 : r.alerts) == null ? void 0 : O.notificationsFailed) ?? 0) > 0 ? { color: "#cf1322" } : void 0
868
+ }
869
+ ),
870
+ /* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
871
+ "被静默压住 ",
872
+ ((j = r == null ? void 0 : r.alerts) == null ? void 0 : j.notificationsSilenced) ?? "-"
873
+ ] })
874
+ ] }) })
875
+ ] })
876
+ ] });
877
+ }
878
+ const nt = { title: "z-observer 可观测性", short: "z-observer" }, at = [
879
+ { key: "/z-observer/home", label: "概览", icon: /* @__PURE__ */ e.jsx(ke, {}) },
880
+ { key: "/z-observer/metrics", label: "指标", icon: /* @__PURE__ */ e.jsx(Oe, {}) },
881
+ { key: "/z-observer/logs", label: "日志", icon: /* @__PURE__ */ e.jsx(Ce, {}) },
882
+ { key: "/z-observer/traces", label: "链路", icon: /* @__PURE__ */ e.jsx(Ie, {}) },
883
+ { key: "/z-observer/alerts", label: "告警", icon: /* @__PURE__ */ e.jsx(Ae, {}) }
884
+ ], lt = [
885
+ { path: "/z-observer/home", Component: Qe },
886
+ { path: "/z-observer/metrics", Component: Je },
887
+ { path: "/z-observer/logs", Component: Be },
888
+ { path: "/z-observer/traces", Component: We },
889
+ { path: "/z-observer/alerts", Component: Ge }
890
+ ];
891
+ export {
892
+ Ge as A,
893
+ Qe as H,
894
+ Be as L,
895
+ Je as M,
896
+ We as T,
897
+ J as a,
898
+ nt as b,
899
+ Fe as c,
900
+ ne as l,
901
+ at as m,
902
+ lt as r,
903
+ ae as t
904
+ };
package/dist/pages.js ADDED
@@ -0,0 +1,15 @@
1
+ import { A as s, H as r, L as t, M as g, T as p, a as c, b as i, l as m, m as o, c as A, r as P, t as l } from "./pages-manifest-Cubmz47-.js";
2
+ export {
3
+ s as AlertPage,
4
+ r as HomePage,
5
+ t as LogSearchPage,
6
+ g as MetricPage,
7
+ p as TracePage,
8
+ c as alertApi,
9
+ i as appMeta,
10
+ m as logApi,
11
+ o as menuItems,
12
+ A as metricApi,
13
+ P as routes,
14
+ l as traceApi
15
+ };
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@yuku123/z-observer-component",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "z-observer 可观测性看板页面:日志检索 / 链路树 / 告警(lead 008 §8:域前端唯一真源在本仓 _frontend/)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./pages": "./dist/pages.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "vite build"
17
+ },
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org/",
20
+ "access": "public"
21
+ },
22
+ "dependencies": {
23
+ "@yuku123/z-frontend-common": "^1.1.3",
24
+ "axios": "^1.16.1",
25
+ "dayjs": "^1.11.10"
26
+ },
27
+ "peerDependencies": {
28
+ "@ant-design/icons": "^6.0.0",
29
+ "antd": "^6.0.0",
30
+ "react": "^19.0.0",
31
+ "react-dom": "^19.0.0",
32
+ "react-router-dom": "^7.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@ant-design/icons": "^6.1.0",
36
+ "@vitejs/plugin-react": "^4.2.1",
37
+ "antd": "^6.3.3",
38
+ "react": "^19.2.0",
39
+ "react-dom": "^19.2.0",
40
+ "vite": "^6.2.6"
41
+ }
42
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.