@yuku123/z-observer-component 0.1.1 → 0.1.2
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 +10 -9
- package/dist/pages-manifest-BK-_AJJb.js +921 -0
- package/dist/pages.js +10 -9
- package/package.json +1 -1
- package/dist/pages-manifest-Cubmz47-.js +0 -904
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
import we, { useState as i, useEffect as Q } from "react";
|
|
2
|
+
import { SearchOutlined as Se, ReloadOutlined as Pe, DashboardOutlined as _e, LineChartOutlined as Ce, FileSearchOutlined as Oe, FieldTimeOutlined as ke, AlertOutlined as Ae, ReadOutlined as ze } from "@ant-design/icons";
|
|
3
|
+
import { Card as _, Button as U, Select as pe, Input as G, Table as oe, Tag as M, Typography as Y, Space as L, Alert as X, Tree as Ie, Row as je, Col as N, Statistic as D, DatePicker as Le } from "antd";
|
|
4
|
+
import V from "dayjs";
|
|
5
|
+
import { TableToolbar as Ne, SearchInput as ve, ErrorState as K, EmptyState as q, ComponentDoc as De } from "@yuku123/z-frontend-common/ui";
|
|
6
|
+
import Me from "axios";
|
|
7
|
+
import { Link as ne } from "react-router-dom";
|
|
8
|
+
var H = { 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 $e() {
|
|
20
|
+
if (he) return B;
|
|
21
|
+
he = 1;
|
|
22
|
+
var r = Symbol.for("react.transitional.element"), g = Symbol.for("react.fragment");
|
|
23
|
+
function u(m, l, d) {
|
|
24
|
+
var f = null;
|
|
25
|
+
if (d !== void 0 && (f = "" + d), l.key !== void 0 && (f = "" + l.key), "key" in l) {
|
|
26
|
+
d = {};
|
|
27
|
+
for (var T in l)
|
|
28
|
+
T !== "key" && (d[T] = l[T]);
|
|
29
|
+
} else d = l;
|
|
30
|
+
return l = d.ref, {
|
|
31
|
+
$$typeof: r,
|
|
32
|
+
type: m,
|
|
33
|
+
key: f,
|
|
34
|
+
ref: l !== void 0 ? l : null,
|
|
35
|
+
props: d
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return B.Fragment = g, 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 fe;
|
|
51
|
+
function Fe() {
|
|
52
|
+
return fe || (fe = 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 p:
|
|
60
|
+
return "Fragment";
|
|
61
|
+
case c:
|
|
62
|
+
return "Profiler";
|
|
63
|
+
case a:
|
|
64
|
+
return "StrictMode";
|
|
65
|
+
case k:
|
|
66
|
+
return "Suspense";
|
|
67
|
+
case $:
|
|
68
|
+
return "SuspenseList";
|
|
69
|
+
case ye:
|
|
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 n:
|
|
81
|
+
return t.displayName || "Context";
|
|
82
|
+
case v:
|
|
83
|
+
return (t._context.displayName || "Context") + ".Consumer";
|
|
84
|
+
case w:
|
|
85
|
+
var s = t.render;
|
|
86
|
+
return t = t.displayName, t || (t = s.displayName || s.name || "", t = t !== "" ? "ForwardRef(" + t + ")" : "ForwardRef"), t;
|
|
87
|
+
case A:
|
|
88
|
+
return s = t.displayName || null, s !== null ? s : r(t.type) || "Memo";
|
|
89
|
+
case Z:
|
|
90
|
+
s = t._payload, t = t._init;
|
|
91
|
+
try {
|
|
92
|
+
return r(t(s));
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
function g(t) {
|
|
99
|
+
return "" + t;
|
|
100
|
+
}
|
|
101
|
+
function u(t) {
|
|
102
|
+
try {
|
|
103
|
+
g(t);
|
|
104
|
+
var s = !1;
|
|
105
|
+
} catch {
|
|
106
|
+
s = !0;
|
|
107
|
+
}
|
|
108
|
+
if (s) {
|
|
109
|
+
s = console;
|
|
110
|
+
var h = s.error, b = typeof Symbol == "function" && Symbol.toStringTag && t[Symbol.toStringTag] || t.constructor.name || "Object";
|
|
111
|
+
return h.call(
|
|
112
|
+
s,
|
|
113
|
+
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
114
|
+
b
|
|
115
|
+
), g(t);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function m(t) {
|
|
119
|
+
if (t === p) return "<>";
|
|
120
|
+
if (typeof t == "object" && t !== null && t.$$typeof === Z)
|
|
121
|
+
return "<...>";
|
|
122
|
+
try {
|
|
123
|
+
var s = r(t);
|
|
124
|
+
return s ? "<" + s + ">" : "<...>";
|
|
125
|
+
} catch {
|
|
126
|
+
return "<...>";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function l() {
|
|
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 f(t) {
|
|
137
|
+
if (ie.call(t, "key")) {
|
|
138
|
+
var s = Object.getOwnPropertyDescriptor(t, "key").get;
|
|
139
|
+
if (s && s.isReactWarning) return !1;
|
|
140
|
+
}
|
|
141
|
+
return t.key !== void 0;
|
|
142
|
+
}
|
|
143
|
+
function T(t, s) {
|
|
144
|
+
function h() {
|
|
145
|
+
le || (le = !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
|
+
s
|
|
148
|
+
));
|
|
149
|
+
}
|
|
150
|
+
h.isReactWarning = !0, Object.defineProperty(t, "key", {
|
|
151
|
+
get: h,
|
|
152
|
+
configurable: !0
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function S() {
|
|
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 P(t, s, h, b, I, z) {
|
|
162
|
+
var E = h.ref;
|
|
163
|
+
return t = {
|
|
164
|
+
$$typeof: C,
|
|
165
|
+
type: t,
|
|
166
|
+
key: s,
|
|
167
|
+
props: h,
|
|
168
|
+
_owner: b
|
|
169
|
+
}, (E !== void 0 ? E : null) !== null ? Object.defineProperty(t, "ref", {
|
|
170
|
+
enumerable: !1,
|
|
171
|
+
get: S
|
|
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: I
|
|
187
|
+
}), Object.defineProperty(t, "_debugTask", {
|
|
188
|
+
configurable: !1,
|
|
189
|
+
enumerable: !1,
|
|
190
|
+
writable: !0,
|
|
191
|
+
value: z
|
|
192
|
+
}), Object.freeze && (Object.freeze(t.props), Object.freeze(t)), t;
|
|
193
|
+
}
|
|
194
|
+
function x(t, s, h, b, I, z) {
|
|
195
|
+
var E = s.children;
|
|
196
|
+
if (E !== void 0)
|
|
197
|
+
if (b)
|
|
198
|
+
if (Te(E)) {
|
|
199
|
+
for (b = 0; b < E.length; b++)
|
|
200
|
+
o(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 o(E);
|
|
207
|
+
if (ie.call(s, "key")) {
|
|
208
|
+
E = r(t);
|
|
209
|
+
var F = Object.keys(s).filter(function(Re) {
|
|
210
|
+
return Re !== "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), f(s) && (u(s.key), E = "" + s.key), "key" in s) {
|
|
226
|
+
h = {};
|
|
227
|
+
for (var re in s)
|
|
228
|
+
re !== "key" && (h[re] = s[re]);
|
|
229
|
+
} else h = s;
|
|
230
|
+
return E && T(
|
|
231
|
+
h,
|
|
232
|
+
typeof t == "function" ? t.displayName || t.name || "Unknown" : t
|
|
233
|
+
), P(
|
|
234
|
+
t,
|
|
235
|
+
E,
|
|
236
|
+
h,
|
|
237
|
+
l(),
|
|
238
|
+
I,
|
|
239
|
+
z
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
function o(t) {
|
|
243
|
+
y(t) ? t._store && (t._store.validated = 1) : typeof t == "object" && t !== null && t.$$typeof === Z && (t._payload.status === "fulfilled" ? y(t._payload.value) && t._payload.value._store && (t._payload.value._store.validated = 1) : t._store && (t._store.validated = 1));
|
|
244
|
+
}
|
|
245
|
+
function y(t) {
|
|
246
|
+
return typeof t == "object" && t !== null && t.$$typeof === C;
|
|
247
|
+
}
|
|
248
|
+
var R = we, C = Symbol.for("react.transitional.element"), j = Symbol.for("react.portal"), p = Symbol.for("react.fragment"), a = Symbol.for("react.strict_mode"), c = Symbol.for("react.profiler"), v = Symbol.for("react.consumer"), n = Symbol.for("react.context"), w = Symbol.for("react.forward_ref"), k = Symbol.for("react.suspense"), $ = Symbol.for("react.suspense_list"), A = Symbol.for("react.memo"), Z = Symbol.for("react.lazy"), ye = Symbol.for("react.activity"), be = Symbol.for("react.view_transition"), Ee = Symbol.for("react.client.reference"), ee = R.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, ie = Object.prototype.hasOwnProperty, Te = Array.isArray, te = console.createTask ? console.createTask : function() {
|
|
249
|
+
return null;
|
|
250
|
+
};
|
|
251
|
+
R = {
|
|
252
|
+
react_stack_bottom_frame: function(t) {
|
|
253
|
+
return t();
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
var le, ce = {}, ue = R.react_stack_bottom_frame.bind(
|
|
257
|
+
R,
|
|
258
|
+
d
|
|
259
|
+
)(), de = te(m(d)), me = {};
|
|
260
|
+
W.Fragment = p, W.jsx = function(t, s, h) {
|
|
261
|
+
var b = 1e4 > ee.recentlyCreatedOwnerStacks++;
|
|
262
|
+
if (b) {
|
|
263
|
+
var I = Error.stackTraceLimit;
|
|
264
|
+
Error.stackTraceLimit = 10;
|
|
265
|
+
var z = Error("react-stack-top-frame");
|
|
266
|
+
Error.stackTraceLimit = I;
|
|
267
|
+
} else z = ue;
|
|
268
|
+
return x(
|
|
269
|
+
t,
|
|
270
|
+
s,
|
|
271
|
+
h,
|
|
272
|
+
!1,
|
|
273
|
+
z,
|
|
274
|
+
b ? te(m(t)) : de
|
|
275
|
+
);
|
|
276
|
+
}, W.jsxs = function(t, s, h) {
|
|
277
|
+
var b = 1e4 > ee.recentlyCreatedOwnerStacks++;
|
|
278
|
+
if (b) {
|
|
279
|
+
var I = Error.stackTraceLimit;
|
|
280
|
+
Error.stackTraceLimit = 10;
|
|
281
|
+
var z = Error("react-stack-top-frame");
|
|
282
|
+
Error.stackTraceLimit = I;
|
|
283
|
+
} else z = ue;
|
|
284
|
+
return x(
|
|
285
|
+
t,
|
|
286
|
+
s,
|
|
287
|
+
h,
|
|
288
|
+
!0,
|
|
289
|
+
z,
|
|
290
|
+
b ? te(m(t)) : de
|
|
291
|
+
);
|
|
292
|
+
};
|
|
293
|
+
})()), W;
|
|
294
|
+
}
|
|
295
|
+
var ge;
|
|
296
|
+
function Ye() {
|
|
297
|
+
return ge || (ge = 1, process.env.NODE_ENV === "production" ? H.exports = $e() : H.exports = Fe()), H.exports;
|
|
298
|
+
}
|
|
299
|
+
var e = Ye();
|
|
300
|
+
const O = Me.create({ timeout: 15e3 });
|
|
301
|
+
O.interceptors.response.use(
|
|
302
|
+
(r) => r.data,
|
|
303
|
+
(r) => {
|
|
304
|
+
var u, m;
|
|
305
|
+
const g = ((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(g));
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
const se = {
|
|
310
|
+
/** 关键词用空格分隔是「且」关系;中文按 unigram+bigram 建索引,无需分词 */
|
|
311
|
+
search: (r) => O.get("/api/logs", { params: r }),
|
|
312
|
+
status: () => O.get("/api/logs/status")
|
|
313
|
+
}, ae = {
|
|
314
|
+
recent: (r = 20) => O.get("/api/traces", { params: { limit: r } }),
|
|
315
|
+
/** 后端对不存在的 traceId 返 404,不是空树 —— 「没采到」和「采到但是空」要分得开 */
|
|
316
|
+
tree: (r) => O.get(`/api/traces/${encodeURIComponent(r)}`)
|
|
317
|
+
}, J = {
|
|
318
|
+
list: () => O.get("/api/alerts"),
|
|
319
|
+
addSilence: (r) => O.post("/api/silences", r),
|
|
320
|
+
addInhibit: (r) => O.post("/api/inhibits", r)
|
|
321
|
+
}, qe = {
|
|
322
|
+
instant: (r, g) => O.get("/api/metrics/query", { params: { promql: r, time: g } }),
|
|
323
|
+
range: (r, g, u, m) => O.get("/api/metrics/query-range", { params: { promql: r, from: g, to: u, step: m } })
|
|
324
|
+
}, Be = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"], We = {
|
|
325
|
+
ERROR: "red",
|
|
326
|
+
WARN: "orange",
|
|
327
|
+
INFO: "blue",
|
|
328
|
+
DEBUG: "default",
|
|
329
|
+
TRACE: "default"
|
|
330
|
+
};
|
|
331
|
+
function Ge() {
|
|
332
|
+
const [r, g] = i(""), [u, m] = i(void 0), [l, d] = i(""), [f, T] = i(15), [S, P] = i([]), [x, o] = i(null), [y, R] = i(!1), [C, j] = i(null);
|
|
333
|
+
async function p(a) {
|
|
334
|
+
R(!0), j(null);
|
|
335
|
+
try {
|
|
336
|
+
const c = Date.now(), v = c - f * 60 * 1e3, n = { limit: 200 }, w = typeof a == "string" ? a : r;
|
|
337
|
+
w && (n.q = w), u && (n.level = u), l && (n.traceId = l), f > 0 && (n.from = v, n.to = c);
|
|
338
|
+
const [k, $] = await Promise.all([se.search(n), se.status()]);
|
|
339
|
+
P(Array.isArray(k) ? k : []), o($);
|
|
340
|
+
} catch (c) {
|
|
341
|
+
j(c.message), P([]);
|
|
342
|
+
} finally {
|
|
343
|
+
R(!1);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return Q(() => {
|
|
347
|
+
p();
|
|
348
|
+
}, []), /* @__PURE__ */ e.jsxs(
|
|
349
|
+
_,
|
|
350
|
+
{
|
|
351
|
+
title: "日志检索",
|
|
352
|
+
extra: /* @__PURE__ */ e.jsx(L, { children: /* @__PURE__ */ e.jsx(U, { icon: /* @__PURE__ */ e.jsx(Pe, {}), onClick: () => p(), loading: y, children: "刷新" }) }),
|
|
353
|
+
children: [
|
|
354
|
+
/* @__PURE__ */ e.jsx(
|
|
355
|
+
Ne,
|
|
356
|
+
{
|
|
357
|
+
left: /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
|
|
358
|
+
/* @__PURE__ */ e.jsx(
|
|
359
|
+
ve,
|
|
360
|
+
{
|
|
361
|
+
style: { width: 280 },
|
|
362
|
+
placeholder: "关键词,空格分隔为且关系",
|
|
363
|
+
value: r,
|
|
364
|
+
onChange: g,
|
|
365
|
+
onSearch: (a) => p(a)
|
|
366
|
+
}
|
|
367
|
+
),
|
|
368
|
+
/* @__PURE__ */ e.jsx(
|
|
369
|
+
pe,
|
|
370
|
+
{
|
|
371
|
+
style: { width: 120 },
|
|
372
|
+
placeholder: "级别",
|
|
373
|
+
allowClear: !0,
|
|
374
|
+
value: u,
|
|
375
|
+
onChange: m,
|
|
376
|
+
options: Be.map((a) => ({ label: a, value: a }))
|
|
377
|
+
}
|
|
378
|
+
),
|
|
379
|
+
/* @__PURE__ */ e.jsx(
|
|
380
|
+
G,
|
|
381
|
+
{
|
|
382
|
+
style: { width: 240 },
|
|
383
|
+
placeholder: "traceId(按链路聚类)",
|
|
384
|
+
value: l,
|
|
385
|
+
onChange: (a) => d(a.target.value),
|
|
386
|
+
onPressEnter: () => p(),
|
|
387
|
+
allowClear: !0
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
/* @__PURE__ */ e.jsx(
|
|
391
|
+
pe,
|
|
392
|
+
{
|
|
393
|
+
style: { width: 140 },
|
|
394
|
+
value: f,
|
|
395
|
+
onChange: T,
|
|
396
|
+
options: [5, 15, 60, 360, 1440].map((a) => ({
|
|
397
|
+
label: `最近 ${a} 分钟`,
|
|
398
|
+
value: a
|
|
399
|
+
}))
|
|
400
|
+
}
|
|
401
|
+
)
|
|
402
|
+
] }),
|
|
403
|
+
right: /* @__PURE__ */ e.jsx(U, { type: "primary", icon: /* @__PURE__ */ e.jsx(Se, {}), onClick: () => p(), loading: y, children: "查询" })
|
|
404
|
+
}
|
|
405
|
+
),
|
|
406
|
+
C && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ e.jsx(K, { error: C, title: "查询失败", onRetry: () => p() }) }),
|
|
407
|
+
/* @__PURE__ */ e.jsx(
|
|
408
|
+
oe,
|
|
409
|
+
{
|
|
410
|
+
rowKey: (a, c) => `${a.timestampMillis}-${c}`,
|
|
411
|
+
size: "small",
|
|
412
|
+
loading: y,
|
|
413
|
+
dataSource: S,
|
|
414
|
+
pagination: {
|
|
415
|
+
pageSize: 50,
|
|
416
|
+
showSizeChanger: !0,
|
|
417
|
+
pageSizeOptions: ["10", "20", "50", "100"],
|
|
418
|
+
showTotal: (a) => `共 ${a} 条`
|
|
419
|
+
},
|
|
420
|
+
locale: {
|
|
421
|
+
emptyText: /* @__PURE__ */ e.jsx(
|
|
422
|
+
q,
|
|
423
|
+
{
|
|
424
|
+
title: "没有匹配的日志",
|
|
425
|
+
description: "放宽关键词或扩大时间窗再查一次",
|
|
426
|
+
size: "sm"
|
|
427
|
+
}
|
|
428
|
+
)
|
|
429
|
+
},
|
|
430
|
+
columns: [
|
|
431
|
+
{
|
|
432
|
+
title: "时间",
|
|
433
|
+
dataIndex: "timestampMillis",
|
|
434
|
+
width: 170,
|
|
435
|
+
render: (a) => a ? V(a).format("YYYY-MM-DD HH:mm:ss.SSS") : "-"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
title: "级别",
|
|
439
|
+
dataIndex: "level",
|
|
440
|
+
width: 90,
|
|
441
|
+
render: (a) => /* @__PURE__ */ e.jsx(M, { color: We[a], children: a })
|
|
442
|
+
},
|
|
443
|
+
{ title: "线程", dataIndex: "thread", width: 120 },
|
|
444
|
+
{ title: "logger", dataIndex: "logger", width: 220, ellipsis: !0 },
|
|
445
|
+
{ title: "消息", dataIndex: "message", ellipsis: !0 },
|
|
446
|
+
{
|
|
447
|
+
title: "traceId",
|
|
448
|
+
dataIndex: "traceId",
|
|
449
|
+
width: 200,
|
|
450
|
+
ellipsis: !0,
|
|
451
|
+
render: (a) => a ? /* @__PURE__ */ e.jsx(Y.Text, { copyable: { text: a }, children: a }) : "-"
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
),
|
|
456
|
+
x && /* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", style: { display: "block", marginTop: 12 }, children: [
|
|
457
|
+
"在库 ",
|
|
458
|
+
x.liveLogs,
|
|
459
|
+
" 条,累计淘汰 ",
|
|
460
|
+
x.evictedLogs,
|
|
461
|
+
" 条"
|
|
462
|
+
] })
|
|
463
|
+
]
|
|
464
|
+
}
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
function Ue() {
|
|
468
|
+
const [r, g] = i([]), [u, m] = i(null), [l, d] = i(null), [f, T] = i(0), [S, P] = i(""), [x, o] = i(null), [y, R] = i(!1);
|
|
469
|
+
async function C() {
|
|
470
|
+
try {
|
|
471
|
+
const c = await ae.recent(50);
|
|
472
|
+
g(c.traceIds || []);
|
|
473
|
+
} catch (c) {
|
|
474
|
+
o(c.message);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async function j(c) {
|
|
478
|
+
R(!0), o(null);
|
|
479
|
+
try {
|
|
480
|
+
const v = await ae.tree(c);
|
|
481
|
+
d(v), T(v.orphanCount || 0), m(c);
|
|
482
|
+
} catch (v) {
|
|
483
|
+
d(null), o(v.message);
|
|
484
|
+
} finally {
|
|
485
|
+
R(!1);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
Q(() => {
|
|
489
|
+
C();
|
|
490
|
+
}, []);
|
|
491
|
+
function p(c) {
|
|
492
|
+
return (c || []).map((v) => ({
|
|
493
|
+
key: v.spanId,
|
|
494
|
+
title: /* @__PURE__ */ e.jsxs(L, { size: 6, wrap: !0, children: [
|
|
495
|
+
/* @__PURE__ */ e.jsx(M, { color: v.statusCode === "ERROR" ? "red" : "blue", children: v.name }),
|
|
496
|
+
/* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", children: [
|
|
497
|
+
v.durationMillis,
|
|
498
|
+
" ms"
|
|
499
|
+
] }),
|
|
500
|
+
v.attributes && Object.keys(v.attributes).length > 0 && /* @__PURE__ */ e.jsx(Y.Text, { type: "secondary", style: { fontSize: 12 }, children: Object.entries(v.attributes).map(([n, w]) => `${n}=${w}`).join(" ") })
|
|
501
|
+
] }),
|
|
502
|
+
children: p(v.children)
|
|
503
|
+
}));
|
|
504
|
+
}
|
|
505
|
+
const a = S ? r.filter((c) => c.includes(S)) : r;
|
|
506
|
+
return /* @__PURE__ */ e.jsxs(L, { align: "start", size: 16, style: { width: "100%" }, children: [
|
|
507
|
+
/* @__PURE__ */ e.jsxs(_, { title: "最近链路", style: { width: 320 }, children: [
|
|
508
|
+
/* @__PURE__ */ e.jsx(
|
|
509
|
+
ve,
|
|
510
|
+
{
|
|
511
|
+
placeholder: "按 traceId 过滤",
|
|
512
|
+
value: S,
|
|
513
|
+
onChange: P,
|
|
514
|
+
style: { marginBottom: 12 }
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
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(
|
|
518
|
+
"a",
|
|
519
|
+
{
|
|
520
|
+
onClick: () => j(c),
|
|
521
|
+
style: {
|
|
522
|
+
fontWeight: u === c ? "bold" : "normal",
|
|
523
|
+
wordBreak: "break-all"
|
|
524
|
+
},
|
|
525
|
+
children: c
|
|
526
|
+
}
|
|
527
|
+
) }, c)) })
|
|
528
|
+
] }),
|
|
529
|
+
/* @__PURE__ */ e.jsxs(_, { title: "链路详情", style: { flex: 1 }, loading: y, children: [
|
|
530
|
+
x && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ e.jsx(K, { error: x, title: "取链路失败", onRetry: () => u && j(u) }) }),
|
|
531
|
+
!l && !x && /* @__PURE__ */ e.jsx(q, { title: "未选择链路", description: "从左边选一条链路", size: "sm" }),
|
|
532
|
+
l && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
|
|
533
|
+
f > 0 && /* @__PURE__ */ e.jsx(
|
|
534
|
+
X,
|
|
535
|
+
{
|
|
536
|
+
type: "warning",
|
|
537
|
+
showIcon: !0,
|
|
538
|
+
style: { marginBottom: 12 },
|
|
539
|
+
message: `有 ${f} 个 span 的父 span 不在本条链路里(跨进程调用),已保留但单独标记`
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
/* @__PURE__ */ e.jsx(
|
|
543
|
+
Ie,
|
|
544
|
+
{
|
|
545
|
+
showLine: !0,
|
|
546
|
+
defaultExpandAll: !0,
|
|
547
|
+
treeData: p(l.roots)
|
|
548
|
+
}
|
|
549
|
+
),
|
|
550
|
+
/* @__PURE__ */ e.jsxs(Y.Text, { type: "secondary", style: { display: "block", marginTop: 12 }, children: [
|
|
551
|
+
"traceId ",
|
|
552
|
+
l.traceId,
|
|
553
|
+
" · span ",
|
|
554
|
+
l.spanCount,
|
|
555
|
+
" 个"
|
|
556
|
+
] })
|
|
557
|
+
] })
|
|
558
|
+
] })
|
|
559
|
+
] });
|
|
560
|
+
}
|
|
561
|
+
const He = { critical: "red", warning: "orange", info: "blue" }, Ve = { FIRING: "red", PENDING: "orange", OK: "green", RESOLVED: "green" };
|
|
562
|
+
function xe(r) {
|
|
563
|
+
return r ? r.valueOf() : void 0;
|
|
564
|
+
}
|
|
565
|
+
function Je() {
|
|
566
|
+
var v;
|
|
567
|
+
const [r, g] = i(null), [u, m] = i(null), [l, d] = i(!1), [f, T] = i(""), [S, P] = i(null), [x, o] = i(""), [y, R] = i(""), [C, j] = i(null);
|
|
568
|
+
async function p() {
|
|
569
|
+
d(!0), m(null);
|
|
570
|
+
try {
|
|
571
|
+
g(await J.list());
|
|
572
|
+
} catch (n) {
|
|
573
|
+
m(n.message);
|
|
574
|
+
} finally {
|
|
575
|
+
d(!1);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
Q(() => {
|
|
579
|
+
p();
|
|
580
|
+
}, []);
|
|
581
|
+
async function a() {
|
|
582
|
+
if (j(null), !x) {
|
|
583
|
+
j("静默必须填原因 —— 事后要能回答「为什么这段时间没人收到告警」");
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
const n = S || [V(), V().add(1, "hour")];
|
|
587
|
+
try {
|
|
588
|
+
await J.addSilence({
|
|
589
|
+
id: `s-${Date.now()}`,
|
|
590
|
+
matchers: f.split(/[\s,]+/).filter(Boolean),
|
|
591
|
+
startMillis: xe(n[0]),
|
|
592
|
+
endMillis: xe(n[1]),
|
|
593
|
+
reason: x,
|
|
594
|
+
createdBy: "console"
|
|
595
|
+
}), j("静默已生效"), T(""), o(""), P(null), p();
|
|
596
|
+
} catch (w) {
|
|
597
|
+
j(`加静默失败:${w.message}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
async function c() {
|
|
601
|
+
j(null);
|
|
602
|
+
const n = y.split(/[\s,]+/).filter(Boolean);
|
|
603
|
+
if (n.length < 2) {
|
|
604
|
+
j("抑制规则填两个条件:source=... target=...(如 cluster_down target=api_high_error)");
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const w = n.find((A) => A.startsWith("source=")), k = n.find((A) => A.startsWith("target=")), $ = n.find((A) => A.startsWith("equal="));
|
|
608
|
+
if (!w || !k) {
|
|
609
|
+
j("抑制规则必须有 source= 与 target=");
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
try {
|
|
613
|
+
await J.addInhibit({
|
|
614
|
+
id: `i-${Date.now()}`,
|
|
615
|
+
sourceRuleId: w.slice(7),
|
|
616
|
+
targetRuleId: k.slice(7),
|
|
617
|
+
equalLabel: $ ? $.slice(6) : ""
|
|
618
|
+
}), j("抑制规则已生效"), p();
|
|
619
|
+
} catch (A) {
|
|
620
|
+
j(`加抑制失败:${A.message}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return /* @__PURE__ */ e.jsxs(L, { direction: "vertical", size: 16, style: { width: "100%" }, children: [
|
|
624
|
+
/* @__PURE__ */ e.jsxs(je, { gutter: 16, children: [
|
|
625
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsx(_, { children: /* @__PURE__ */ e.jsx(D, { title: "活动告警", value: ((v = r == null ? void 0 : r.active) == null ? void 0 : v.length) ?? 0 }) }) }),
|
|
626
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsx(_, { children: /* @__PURE__ */ e.jsx(D, { title: "已发通知", value: (r == null ? void 0 : r.notificationsSent) ?? 0 }) }) }),
|
|
627
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsx(_, { children: /* @__PURE__ */ e.jsx(
|
|
628
|
+
D,
|
|
629
|
+
{
|
|
630
|
+
title: "通知失败",
|
|
631
|
+
value: (r == null ? void 0 : r.notificationsFailed) ?? 0,
|
|
632
|
+
valueStyle: ((r == null ? void 0 : r.notificationsFailed) ?? 0) > 0 ? { color: "#cf1322" } : void 0
|
|
633
|
+
}
|
|
634
|
+
) }) }),
|
|
635
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsx(_, { children: /* @__PURE__ */ e.jsx(
|
|
636
|
+
D,
|
|
637
|
+
{
|
|
638
|
+
title: "评估失败",
|
|
639
|
+
value: (r == null ? void 0 : r.evaluateErrorCount) ?? 0,
|
|
640
|
+
valueStyle: ((r == null ? void 0 : r.evaluateErrorCount) ?? 0) > 0 ? { color: "#cf1322" } : void 0
|
|
641
|
+
}
|
|
642
|
+
) }) })
|
|
643
|
+
] }),
|
|
644
|
+
u && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ e.jsx(K, { error: u, title: "读告警失败", onRetry: p }) }),
|
|
645
|
+
/* @__PURE__ */ e.jsx(_, { title: "活动告警", children: /* @__PURE__ */ e.jsx(
|
|
646
|
+
oe,
|
|
647
|
+
{
|
|
648
|
+
rowKey: (n, w) => `${n.ruleId}-${w}`,
|
|
649
|
+
size: "small",
|
|
650
|
+
loading: l,
|
|
651
|
+
dataSource: (r == null ? void 0 : r.active) ?? [],
|
|
652
|
+
pagination: !1,
|
|
653
|
+
locale: { emptyText: /* @__PURE__ */ e.jsx(q, { title: "当前没有活动告警", description: "规则触发后活动告警会出现在这里", size: "sm" }) },
|
|
654
|
+
columns: [
|
|
655
|
+
{ title: "规则", dataIndex: "ruleName" },
|
|
656
|
+
{
|
|
657
|
+
title: "级别",
|
|
658
|
+
dataIndex: "severity",
|
|
659
|
+
render: (n) => /* @__PURE__ */ e.jsx(M, { color: He[n], children: n })
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
title: "状态",
|
|
663
|
+
dataIndex: "state",
|
|
664
|
+
render: (n) => /* @__PURE__ */ e.jsx(M, { color: Ve[n], children: n })
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
title: "标签",
|
|
668
|
+
dataIndex: "labels",
|
|
669
|
+
render: (n) => Object.entries(n || {}).map(([w, k]) => /* @__PURE__ */ e.jsxs(M, { children: [
|
|
670
|
+
w,
|
|
671
|
+
"=",
|
|
672
|
+
k
|
|
673
|
+
] }, w))
|
|
674
|
+
},
|
|
675
|
+
{ title: "取值", dataIndex: "value", render: (n) => n ?? "-" },
|
|
676
|
+
{
|
|
677
|
+
title: "开始于",
|
|
678
|
+
dataIndex: "activeSinceMillis",
|
|
679
|
+
render: (n) => n ? V(n).format("MM-DD HH:mm:ss") : "-"
|
|
680
|
+
}
|
|
681
|
+
]
|
|
682
|
+
}
|
|
683
|
+
) }),
|
|
684
|
+
/* @__PURE__ */ e.jsx(_, { title: "去噪操作", children: /* @__PURE__ */ e.jsxs(L, { direction: "vertical", style: { width: "100%" }, children: [
|
|
685
|
+
/* @__PURE__ */ e.jsx(Qe, {}),
|
|
686
|
+
/* @__PURE__ */ e.jsxs(L, { wrap: !0, children: [
|
|
687
|
+
/* @__PURE__ */ e.jsx(
|
|
688
|
+
G,
|
|
689
|
+
{
|
|
690
|
+
style: { width: 420 },
|
|
691
|
+
placeholder: "条件,空格分隔:app=z-gw 或 cluster=c1(留空=全员静默)",
|
|
692
|
+
value: f,
|
|
693
|
+
onChange: (n) => T(n.target.value)
|
|
694
|
+
}
|
|
695
|
+
),
|
|
696
|
+
/* @__PURE__ */ e.jsx(
|
|
697
|
+
Le.RangePicker,
|
|
698
|
+
{
|
|
699
|
+
showTime: !0,
|
|
700
|
+
value: S,
|
|
701
|
+
onChange: P
|
|
702
|
+
}
|
|
703
|
+
),
|
|
704
|
+
/* @__PURE__ */ e.jsx(
|
|
705
|
+
G,
|
|
706
|
+
{
|
|
707
|
+
style: { width: 260 },
|
|
708
|
+
placeholder: "原因(必填)",
|
|
709
|
+
value: x,
|
|
710
|
+
onChange: (n) => o(n.target.value)
|
|
711
|
+
}
|
|
712
|
+
),
|
|
713
|
+
/* @__PURE__ */ e.jsx(U, { type: "primary", onClick: a, children: "加静默" })
|
|
714
|
+
] }),
|
|
715
|
+
/* @__PURE__ */ e.jsxs(L.Compact, { style: { width: "100%" }, children: [
|
|
716
|
+
/* @__PURE__ */ e.jsx(
|
|
717
|
+
G,
|
|
718
|
+
{
|
|
719
|
+
style: { width: 460 },
|
|
720
|
+
placeholder: "抑制规则:source=cluster_down target=api_high_error equal=cluster",
|
|
721
|
+
value: y,
|
|
722
|
+
onChange: (n) => R(n.target.value)
|
|
723
|
+
}
|
|
724
|
+
),
|
|
725
|
+
/* @__PURE__ */ e.jsx(U, { onClick: c, children: "加抑制" })
|
|
726
|
+
] }),
|
|
727
|
+
C && /* @__PURE__ */ e.jsx(X, { type: "info", message: C, showIcon: !0 })
|
|
728
|
+
] }) })
|
|
729
|
+
] });
|
|
730
|
+
}
|
|
731
|
+
function Qe() {
|
|
732
|
+
return /* @__PURE__ */ e.jsx(
|
|
733
|
+
X,
|
|
734
|
+
{
|
|
735
|
+
type: "info",
|
|
736
|
+
showIcon: !0,
|
|
737
|
+
message: "静默只压通知不改状态机;抑制需要成对写,source 与 target 不能是同一条规则"
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
function Xe() {
|
|
742
|
+
const [r, g] = i("up"), [u, m] = i([]), [l, d] = i(null), [f, T] = i(!1), [S, P] = i(!1);
|
|
743
|
+
async function x() {
|
|
744
|
+
T(!0), d(null);
|
|
745
|
+
try {
|
|
746
|
+
const o = await qe.instant(r);
|
|
747
|
+
m(Array.isArray(o) ? o : []), P(!0);
|
|
748
|
+
} catch (o) {
|
|
749
|
+
d(o.message), m([]), P(!0);
|
|
750
|
+
} finally {
|
|
751
|
+
T(!1);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return /* @__PURE__ */ e.jsxs(_, { title: "指标即时查询", children: [
|
|
755
|
+
/* @__PURE__ */ e.jsxs(L.Compact, { style: { width: "100%", marginBottom: 16 }, children: [
|
|
756
|
+
/* @__PURE__ */ e.jsx(
|
|
757
|
+
G,
|
|
758
|
+
{
|
|
759
|
+
style: { width: 520 },
|
|
760
|
+
value: r,
|
|
761
|
+
onChange: (o) => g(o.target.value),
|
|
762
|
+
onPressEnter: x,
|
|
763
|
+
placeholder: 'PromQL,例如 up{job="z-gw"}'
|
|
764
|
+
}
|
|
765
|
+
),
|
|
766
|
+
/* @__PURE__ */ e.jsx(U, { type: "primary", onClick: x, loading: f, children: "查询" })
|
|
767
|
+
] }),
|
|
768
|
+
l && /* @__PURE__ */ e.jsx(
|
|
769
|
+
X,
|
|
770
|
+
{
|
|
771
|
+
type: "warning",
|
|
772
|
+
showIcon: !0,
|
|
773
|
+
style: { marginBottom: 12 },
|
|
774
|
+
message: "指标源不可达或表达式有误",
|
|
775
|
+
description: l
|
|
776
|
+
}
|
|
777
|
+
),
|
|
778
|
+
/* @__PURE__ */ e.jsx(
|
|
779
|
+
oe,
|
|
780
|
+
{
|
|
781
|
+
rowKey: (o, y) => o.seriesKey || String(y),
|
|
782
|
+
size: "small",
|
|
783
|
+
loading: f,
|
|
784
|
+
dataSource: u,
|
|
785
|
+
pagination: {
|
|
786
|
+
pageSize: 50,
|
|
787
|
+
showSizeChanger: !0,
|
|
788
|
+
pageSizeOptions: ["10", "20", "50", "100"],
|
|
789
|
+
showTotal: (o) => `共 ${o} 条`
|
|
790
|
+
},
|
|
791
|
+
locale: {
|
|
792
|
+
emptyText: S ? /* @__PURE__ */ e.jsx(q, { title: "没有匹配的时序", description: "目标可能已下线,换个 PromQL 再查一次", size: "sm" }) : /* @__PURE__ */ e.jsx(q, { title: "尚未查询", description: "输入 PromQL 后查询", size: "sm" })
|
|
793
|
+
},
|
|
794
|
+
columns: [
|
|
795
|
+
{
|
|
796
|
+
title: "标签",
|
|
797
|
+
dataIndex: "labels",
|
|
798
|
+
render: (o) => Object.entries(o || {}).map(([y, R]) => /* @__PURE__ */ e.jsxs(M, { children: [
|
|
799
|
+
y,
|
|
800
|
+
"=",
|
|
801
|
+
R
|
|
802
|
+
] }, y))
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
title: "取值",
|
|
806
|
+
dataIndex: "value",
|
|
807
|
+
width: 160,
|
|
808
|
+
render: (o) => Number.isNaN(o) ? /* @__PURE__ */ e.jsx(M, { children: "NaN" }) : String(o)
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
title: "采样时间",
|
|
812
|
+
dataIndex: "timestampMillis",
|
|
813
|
+
width: 200,
|
|
814
|
+
render: (o) => new Date(o).toLocaleString()
|
|
815
|
+
}
|
|
816
|
+
]
|
|
817
|
+
}
|
|
818
|
+
),
|
|
819
|
+
/* @__PURE__ */ e.jsx(Y.Paragraph, { type: "secondary", style: { marginTop: 12 }, children: "M1 期间指标读的是 z-env 已有的 Prometheus 本体,z-observer 自己不落时序存储; 与第三方 Prometheus / Grafana 并存是有意为之的过渡形态。" })
|
|
820
|
+
] });
|
|
821
|
+
}
|
|
822
|
+
function Ke() {
|
|
823
|
+
var d, f, T, S, P, x, o, y, R, C, j;
|
|
824
|
+
const [r, g] = i(null), [u, m] = i(null), l = async () => {
|
|
825
|
+
try {
|
|
826
|
+
const [p, a, c] = await Promise.all([se.status(), ae.recent(1), J.list()]);
|
|
827
|
+
g({ logs: p, traces: a, alerts: c }), m(null);
|
|
828
|
+
} catch (p) {
|
|
829
|
+
m(p.message);
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
return Q(() => {
|
|
833
|
+
l();
|
|
834
|
+
}, []), /* @__PURE__ */ e.jsxs(_, { title: "z-observer 概览", children: [
|
|
835
|
+
u && /* @__PURE__ */ e.jsx("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ e.jsx(K, { error: u, title: "读状态失败", onRetry: l }) }),
|
|
836
|
+
/* @__PURE__ */ e.jsxs(je, { gutter: 16, children: [
|
|
837
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsxs(_, { size: "small", children: [
|
|
838
|
+
/* @__PURE__ */ e.jsx(
|
|
839
|
+
D,
|
|
840
|
+
{
|
|
841
|
+
title: /* @__PURE__ */ e.jsx(ne, { to: "/z-observer/logs", children: "在库日志" }),
|
|
842
|
+
value: ((d = r == null ? void 0 : r.logs) == null ? void 0 : d.liveLogs) ?? "-"
|
|
843
|
+
}
|
|
844
|
+
),
|
|
845
|
+
/* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
|
|
846
|
+
"累计淘汰 ",
|
|
847
|
+
((f = r == null ? void 0 : r.logs) == null ? void 0 : f.evictedLogs) ?? "-"
|
|
848
|
+
] })
|
|
849
|
+
] }) }),
|
|
850
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsxs(_, { size: "small", children: [
|
|
851
|
+
/* @__PURE__ */ e.jsx(
|
|
852
|
+
D,
|
|
853
|
+
{
|
|
854
|
+
title: /* @__PURE__ */ e.jsx(ne, { to: "/z-observer/traces", children: "在库链路" }),
|
|
855
|
+
value: ((T = r == null ? void 0 : r.traces) == null ? void 0 : T.traceCount) ?? "-"
|
|
856
|
+
}
|
|
857
|
+
),
|
|
858
|
+
/* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
|
|
859
|
+
"累计淘汰 ",
|
|
860
|
+
((S = r == null ? void 0 : r.traces) == null ? void 0 : S.evictedTraces) ?? "-"
|
|
861
|
+
] })
|
|
862
|
+
] }) }),
|
|
863
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsx(_, { size: "small", children: /* @__PURE__ */ e.jsx(
|
|
864
|
+
D,
|
|
865
|
+
{
|
|
866
|
+
title: /* @__PURE__ */ e.jsx(ne, { to: "/z-observer/alerts", children: "活动告警" }),
|
|
867
|
+
value: ((x = (P = r == null ? void 0 : r.alerts) == null ? void 0 : P.active) == null ? void 0 : x.length) ?? "-",
|
|
868
|
+
valueStyle: (((y = (o = r == null ? void 0 : r.alerts) == null ? void 0 : o.active) == null ? void 0 : y.length) ?? 0) > 0 ? { color: "#cf1322" } : void 0
|
|
869
|
+
}
|
|
870
|
+
) }) }),
|
|
871
|
+
/* @__PURE__ */ e.jsx(N, { span: 6, children: /* @__PURE__ */ e.jsxs(_, { size: "small", children: [
|
|
872
|
+
/* @__PURE__ */ e.jsx(
|
|
873
|
+
D,
|
|
874
|
+
{
|
|
875
|
+
title: "通知失败",
|
|
876
|
+
value: ((R = r == null ? void 0 : r.alerts) == null ? void 0 : R.notificationsFailed) ?? "-",
|
|
877
|
+
valueStyle: (((C = r == null ? void 0 : r.alerts) == null ? void 0 : C.notificationsFailed) ?? 0) > 0 ? { color: "#cf1322" } : void 0
|
|
878
|
+
}
|
|
879
|
+
),
|
|
880
|
+
/* @__PURE__ */ e.jsxs("div", { style: { color: "#999" }, children: [
|
|
881
|
+
"被静默压住 ",
|
|
882
|
+
((j = r == null ? void 0 : r.alerts) == null ? void 0 : j.notificationsSilenced) ?? "-"
|
|
883
|
+
] })
|
|
884
|
+
] }) })
|
|
885
|
+
] })
|
|
886
|
+
] });
|
|
887
|
+
}
|
|
888
|
+
const Ze = "# z-observer-component\n\nz-observer(可观测性)跨仓唯一前端面:把「概览 / 指标查询 / 日志检索 / 链路追踪 / 告警」\n这一组可观测性页面收敛成一个可复用的 React 组件包,由 `z-observer-suit` 独立壳或平台主壳挂载。\n\n- **npm 包名**:`@yuku123/z-observer-component`\n- **宿主接入**:`@yuku123/z-observer-component/pages`(manifest + 请求层),主壳可只取 `ComponentDocPage`\n- **后端**:z-observer 收端的 `/api/**`(日志 / 链路 / 告警 / 指标)\n- **技术栈**:React 19 + antd 6 + react-router-dom 7 + dayjs + vite\n (library mode,双入口 `.` / `./pages`)\n\n---\n\n## 一、能力概览\n\n路由前缀 `/z-observer`,菜单与路由都在 `src/pages-manifest.jsx` 里声明,宿主读数组自己组装。\n前缀的作用是**把收端 REST 与 SPA 路由彻底隔开** —— 少了前缀,浏览器直接刷新\n`/z-observer/logs` 拿到的是 JSON 而不是页面。\n\n| 页面 | 路由(相对 `/z-observer/*`) | 源文件 | 能力 |\n|------|--------------------------|--------|------|\n| 概览 | `home` | `pages/HomePage.jsx` | 日志 / 链路 / 告警三路计数 + 各功能入口 |\n| 指标 | `metrics` | `pages/MetricPage.jsx` | Prometheus 即时查询(PromQL) |\n| 日志 | `logs` | `pages/LogSearchPage.jsx` | 日志检索(关键词 / 时间范围 / 级别) |\n| 链路 | `traces` | `pages/TracePage.jsx` | 最近链路列表 + 选中链路的 span 树 |\n| 告警 | `alerts` | `pages/AlertPage.jsx` | 告警列表 + 静默 / 抑制 |\n| 组件文档 | `docs` | `pages/ComponentDoc.jsx` | 本文件渲染页(左侧 240px TOC + 右侧正文) |\n\n⚠ **这个包没有登录页**:`src/pages/` 下只有上表这几个页面,manifest 也没有导出 `LoginPage`\n(其它包都有)。收端自己的鉴权方式由宿主决定。\n\n## 二、导出面\n\n```js\n// 主入口(. 桶):整个 pages.js 的转发\nimport {menuItems, routes, appMeta, HomePage, LogSearchPage, TracePage, AlertPage, MetricPage,\n logApi, traceApi, alertApi, metricApi, ComponentDocPage} from '@yuku123/z-observer-component'\n\n// 宿主组装面(./pages 桶):同一批名字\nimport {menuItems, routes, appMeta, ComponentDocPage} from '@yuku123/z-observer-component/pages'\n\n// 组件文档页(主壳接线用,名字全仓统一)\nimport {ComponentDocPage} from '@yuku123/z-observer-component'\n```\n\n主入口是 `export * from './pages.js'`,`pages.js` 同时转发 manifest 的页面导出与\n`services/api.js` 的四个 API 对象 ⇒ 文档页只要在 manifest 里导出并加进 `pages.js`,\n主入口就会自动带上它。\n\n## 三、API 端点\n\n请求实例是本包自建的 axios 实例(`src/services/api.js`),超时 15s,**不带 baseURL**\n⇒ 下面的路径就是浏览器实际请求的路径(都自带 `/api` 前缀)。\n响应拦截器直接返回 `r.data`(收端返的是**裸 JSON**,不是 z-opc 那种 `{code, data, message}` 信封),\n失败时把后端的 `{status, error}` 里的 `error` 原文抛出来。\n\n| 方法 | 路径 | 说明 |\n|---|---|---|\n| GET | `/api/logs` | 日志检索(query:关键词 / 时间范围 / 级别等) |\n| GET | `/api/logs/status` | 日志通道状态 |\n| GET | `/api/traces` | 最近链路(query:`limit`,默认 20) |\n| GET | `/api/traces/{traceId}` | 单条链路的 span 树 |\n| GET | `/api/alerts` | 告警列表 |\n| POST | `/api/silences` | 新建静默 |\n| POST | `/api/inhibits` | 新建抑制 |\n\n## 四、页面说明\n\n### 4.1 概览\n\n并行拉告警、日志、链路三路数据,给出计数与入口卡片。任一路失败用基座 `ErrorState` 显示。\n\n### 4.2 指标\n\nPrometheus **即时查询**(PromQL),后端直读 Prometheus。\n⚠ 本页**不存任何指标**(D2 过渡方案 B)—— 查询历史、看板都不在这个包里。\n\n### 4.3 日志\n\n日志检索。关键词用空格分隔是「且」关系;中文按 unigram + bigram 建索引,**无需分词**。\n\n### 4.4 链路\n\n左边最近链路列表,右边把选中的那条画成树。\n树用后端返回的父子结构**直接渲染**,不在前端重算 span 耗时 ——\n⚠ 后端对不存在的 traceId 返 **404**(不是空树),「没采到」和「采到但是空」必须分得开。\n\n### 4.5 告警\n\n告警列表 + 新建静默 / 新建抑制(时间范围用 dayjs 的 DatePicker)。\n\n### 4.6 组件文档\n\n本文件。内容以 `?raw` 在编译期内联,零额外请求;左侧 240px TOC 随滚动联动。\n\n## 五、配置\n\n| 配置项 | 默认值 | 说明 |\n|---|---|---|\n| 请求前缀 | — | axios 实例**不设 baseURL**,路径自带 `/api` |\n| 请求超时 | `15000` ms | 自建实例的 `timeout` |\n| 最近链路条数 | `20` | `traceApi.recent` 的默认 `limit` |\n\n## 六、已知限制\n\n- **请求层没走基座**:`src/services/api.js` 自己 `axios.create`,**没有用基座的\n `createRequest`** ⇒ 不注入 `Authorization` 头、不读 token 存储键、401 不会跳登录。\n 这是有意为之:收端返回裸 JSON,走基座的统一解包反而要额外解包。\n- **没有登录页**:本包不含 `LoginPage`,收端的鉴权由宿主决定。\n- **指标页只做即时查询**:没有范围查询、没有看板、没有查询历史 ——\n 后端直读 Prometheus 是 D2 过渡方案 B。\n- **链路页不做 span 耗时聚合**:直接渲染后端给的父子结构。\n- **告警的静默 / 抑制是 POST 建**,本页没有删除 / 撤销入口。\n- 静态 `message`(antd 6 下会告警,规范要求改 `App.useApp()`)。\n- z-observer 组件包**没有**被 z-opc 主壳的 `domainRoutes.ts` 注册,也没被 z-team 的\n `SystemShell` 引用,目前只有 `z-observer-suit` 独立壳在用\n ⇒ `/z-observer/docs` 在平台主壳里**没有可达路径**。\n\n## 七、变更记录\n\n| 版本 | 变更 |\n|---|---|\n| 0.1.1 | 新增组件文档页 `ComponentDocPage`(lead 008 §7):`src/DOC.md` + 基座 `ComponentDoc` 薄包装 |\n| 0.1.1 | 首版:概览 / 指标 / 日志 / 链路 / 告警页面集 + manifest + 自建 request |\n";
|
|
889
|
+
function et() {
|
|
890
|
+
return /* @__PURE__ */ e.jsx(De, { markdown: Ze, title: "组件文档 — z-observer" });
|
|
891
|
+
}
|
|
892
|
+
const lt = { title: "z-observer 可观测性", short: "z-observer" }, ct = [
|
|
893
|
+
{ key: "/z-observer/home", label: "概览", icon: /* @__PURE__ */ e.jsx(_e, {}) },
|
|
894
|
+
{ key: "/z-observer/metrics", label: "指标", icon: /* @__PURE__ */ e.jsx(Ce, {}) },
|
|
895
|
+
{ key: "/z-observer/logs", label: "日志", icon: /* @__PURE__ */ e.jsx(Oe, {}) },
|
|
896
|
+
{ key: "/z-observer/traces", label: "链路", icon: /* @__PURE__ */ e.jsx(ke, {}) },
|
|
897
|
+
{ key: "/z-observer/alerts", label: "告警", icon: /* @__PURE__ */ e.jsx(Ae, {}) },
|
|
898
|
+
{ key: "/z-observer/docs", label: "组件文档", icon: /* @__PURE__ */ e.jsx(ze, {}) }
|
|
899
|
+
], ut = [
|
|
900
|
+
{ path: "/z-observer/home", Component: Ke },
|
|
901
|
+
{ path: "/z-observer/metrics", Component: Xe },
|
|
902
|
+
{ path: "/z-observer/logs", Component: Ge },
|
|
903
|
+
{ path: "/z-observer/traces", Component: Ue },
|
|
904
|
+
{ path: "/z-observer/alerts", Component: Je },
|
|
905
|
+
{ path: "/z-observer/docs", Component: et }
|
|
906
|
+
];
|
|
907
|
+
export {
|
|
908
|
+
Je as A,
|
|
909
|
+
et as C,
|
|
910
|
+
Ke as H,
|
|
911
|
+
Ge as L,
|
|
912
|
+
Xe as M,
|
|
913
|
+
Ue as T,
|
|
914
|
+
J as a,
|
|
915
|
+
lt as b,
|
|
916
|
+
qe as c,
|
|
917
|
+
se as l,
|
|
918
|
+
ct as m,
|
|
919
|
+
ut as r,
|
|
920
|
+
ae as t
|
|
921
|
+
};
|