@yuku123/z-observer-component 0.0.0-stage → 0.1.0

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