You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
10 KiB
150 lines
10 KiB
import { defineComponent, ref, computed, useSSRContext } from 'vue';
|
|
import { ssrRenderAttrs, ssrRenderList, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrInterpolate, ssrRenderStyle, ssrRenderClass } from 'vue/server-renderer';
|
|
import { u as useApi } from './useApi-B6h53Mkt.mjs';
|
|
import { u as useToast } from './useToast-C76a6bSX.mjs';
|
|
import { _ as _export_sfc } from './server.mjs';
|
|
import './auth-QFkCoU1C.mjs';
|
|
import 'pinia';
|
|
import './useLoading-D6mc40Wj.mjs';
|
|
import './state-DQnwRar-.mjs';
|
|
import '../nitro/nitro.mjs';
|
|
import 'node:http';
|
|
import 'node:https';
|
|
import 'node:events';
|
|
import 'node:buffer';
|
|
import 'node:fs';
|
|
import 'node:path';
|
|
import 'node:crypto';
|
|
import 'node:url';
|
|
import '../routes/renderer.mjs';
|
|
import 'vue-bundle-renderer/runtime';
|
|
import 'unhead/server';
|
|
import 'devalue';
|
|
import 'unhead/utils';
|
|
import 'perfect-debounce';
|
|
|
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
__name: "statlog",
|
|
__ssrInlineRender: true,
|
|
setup(__props) {
|
|
useApi();
|
|
useToast();
|
|
const REGION_NAMES = { cn: "中国", us: "美国", ea: "东亚", sea: "东南亚", sa: "南亚", me: "中东", eu: "欧洲", ru: "俄罗斯", af: "非洲", sam: "南美", nam: "北美", oc: "大洋洲", br: "巴西", in: "印度" };
|
|
function regionName(c) {
|
|
return c ? REGION_NAMES[c] || c : "-";
|
|
}
|
|
const all = ref([]);
|
|
const loading = ref(false);
|
|
const loadError = ref("");
|
|
const statTotal = ref("-");
|
|
const statLast = ref("-");
|
|
const statTip = ref("");
|
|
const fDay = ref(0);
|
|
const fLevel = ref("");
|
|
const fKw = ref("");
|
|
const fAuto = ref(false);
|
|
function shYmd(offsetDays = 0) {
|
|
const d = new Date(Date.now() + offsetDays * 864e5);
|
|
const s = new Intl.DateTimeFormat("en-CA", { timeZone: "Asia/Shanghai", year: "numeric", month: "2-digit", day: "2-digit" }).format(d);
|
|
return parseInt(s.replace(/-/g, ""), 10);
|
|
}
|
|
function fmtDay(yyyymmdd) {
|
|
const s = "" + yyyymmdd;
|
|
return s.length === 8 ? s.slice(0, 4) + "-" + s.slice(4, 6) + "-" + s.slice(6, 8) : s;
|
|
}
|
|
function fmtTime(ts) {
|
|
if (!ts) return "--";
|
|
const d = new Date(ts * 1e3);
|
|
const p = (n) => n < 10 ? "0" + n : "" + n;
|
|
return p(d.getHours()) + ":" + p(d.getMinutes()) + ":" + p(d.getSeconds());
|
|
}
|
|
function fmtProduct(pid) {
|
|
return pid ? "0x" + (pid >>> 0).toString(16).toUpperCase() : "全部";
|
|
}
|
|
const dayOptions = computed(() => [
|
|
{ value: shYmd(0), label: "今天 " + fmtDay(shYmd(0)) },
|
|
{ value: shYmd(-1), label: "昨天 " + fmtDay(shYmd(-1)) }
|
|
]);
|
|
function levelInfo(level) {
|
|
if (level === "error") return { cls: "lv-error", txt: "解析失败" };
|
|
if (level === "warn") return { cls: "lv-warn", txt: "未落库" };
|
|
return { cls: "lv-info", txt: "已落库" };
|
|
}
|
|
function isLate(e) {
|
|
return !!(e.snap_ts && e.ts && e.ts - e.snap_ts > 120);
|
|
}
|
|
const filteredRows = computed(() => {
|
|
const level = fLevel.value;
|
|
const kw = fKw.value.trim().toLowerCase();
|
|
return all.value.filter((e) => {
|
|
if (level && e.level !== level) return false;
|
|
if (kw) {
|
|
const hay = ((e.app || "") + " " + (e.region || "") + " " + regionName(e.region) + " " + (e.product_id || "") + " " + fmtProduct(e.product_id) + " " + (e.stat_day || "")).toLowerCase();
|
|
if (hay.indexOf(kw) < 0) return false;
|
|
}
|
|
return true;
|
|
});
|
|
});
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
_push(`<div${ssrRenderAttrs(_attrs)} data-v-742ee359><div class="flex items-center justify-between mb-4 flex-wrap gap-3" data-v-742ee359><div data-v-742ee359><h2 class="text-lg font-bold text-slate-700" data-v-742ee359>统计日志</h2><p class="text-xs text-slate-400 mt-0.5" data-v-742ee359>console 从 NATS 收到的「当日统计快照」接收流水(最新在前,按接收时间分天存 Redis)。各业务部署每个同步周期/启动时/0点 推送一次当日绝对快照,console 收到后覆盖落库。用于核对每个部署是否在正常汇报;带 <span class="unreg" data-v-742ee359>未注册</span> 的应用快照已收到但<b data-v-742ee359>不会落库</b>(应用名需与 console 注册表完全一致)。</p></div><div class="flex items-center gap-2 flex-wrap" data-v-742ee359><select class="select select-bordered select-sm" data-v-742ee359><!--[-->`);
|
|
ssrRenderList(dayOptions.value, (opt) => {
|
|
_push(`<option${ssrRenderAttr("value", opt.value)} data-v-742ee359${ssrIncludeBooleanAttr(Array.isArray(fDay.value) ? ssrLooseContain(fDay.value, opt.value) : ssrLooseEqual(fDay.value, opt.value)) ? " selected" : ""}>${ssrInterpolate(opt.label)}</option>`);
|
|
});
|
|
_push(`<!--]--></select><select class="select select-bordered select-sm" data-v-742ee359><option value="" data-v-742ee359${ssrIncludeBooleanAttr(Array.isArray(fLevel.value) ? ssrLooseContain(fLevel.value, "") : ssrLooseEqual(fLevel.value, "")) ? " selected" : ""}>全部级别</option><option value="info" data-v-742ee359${ssrIncludeBooleanAttr(Array.isArray(fLevel.value) ? ssrLooseContain(fLevel.value, "info") : ssrLooseEqual(fLevel.value, "info")) ? " selected" : ""}>已落库</option><option value="warn" data-v-742ee359${ssrIncludeBooleanAttr(Array.isArray(fLevel.value) ? ssrLooseContain(fLevel.value, "warn") : ssrLooseEqual(fLevel.value, "warn")) ? " selected" : ""}>未落库</option><option value="error" data-v-742ee359${ssrIncludeBooleanAttr(Array.isArray(fLevel.value) ? ssrLooseContain(fLevel.value, "error") : ssrLooseEqual(fLevel.value, "error")) ? " selected" : ""}>解析失败</option></select><input${ssrRenderAttr("value", fKw.value)} class="input input-bordered input-sm w-44" placeholder="筛选 应用/区域/产品" data-v-742ee359><label class="flex items-center gap-1 text-xs text-slate-500 cursor-pointer" data-v-742ee359><input${ssrIncludeBooleanAttr(Array.isArray(fAuto.value) ? ssrLooseContain(fAuto.value, null) : fAuto.value) ? " checked" : ""} type="checkbox" class="checkbox checkbox-xs" data-v-742ee359> 自动刷新 </label><button class="btn btn-primary btn-sm text-white" data-v-742ee359>刷新</button><button class="btn btn-outline btn-error btn-sm" title="清空本日核对流水(不影响已落库的统计数据),清空后可重新观察埋点是否正常进来" data-v-742ee359>清空本日</button></div></div><div class="flex items-center gap-4 mb-3 text-xs text-slate-500" data-v-742ee359><span data-v-742ee359>该日保留 <b class="text-slate-700" data-v-742ee359>${ssrInterpolate(statTotal.value)}</b> 条</span><span data-v-742ee359>当前显示 <b class="text-slate-700" data-v-742ee359>${ssrInterpolate(filteredRows.value.length)}</b> 条</span><span data-v-742ee359>最近接收 <b class="text-slate-700" data-v-742ee359>${ssrInterpolate(statLast.value)}</b></span><span class="muted" data-v-742ee359>${ssrInterpolate(statTip.value)}</span></div><div class="panel overflow-hidden" data-v-742ee359><div id="logHead" data-v-742ee359><div data-v-742ee359>接收时间</div><div data-v-742ee359>级别</div><div data-v-742ee359>应用 · 区域 · 产品</div><div data-v-742ee359>统计日</div><div data-v-742ee359>指标摘要 / 说明</div><div data-v-742ee359>快照时间</div></div><div id="logBody" style="${ssrRenderStyle({ "max-height": "calc(100vh - 230px)", "overflow-y": "auto" })}" data-v-742ee359>`);
|
|
if (loading.value) {
|
|
_push(`<div class="text-center text-slate-400 py-10" data-v-742ee359>加载中...</div>`);
|
|
} else if (loadError.value) {
|
|
_push(`<div class="text-center text-red-400 py-10" data-v-742ee359>加载失败:${ssrInterpolate(loadError.value)}</div>`);
|
|
} else if (!filteredRows.value.length) {
|
|
_push(`<div class="text-center text-slate-400 py-10" data-v-742ee359>${ssrInterpolate(all.value.length ? "无匹配记录" : "该日暂无接收记录")}</div>`);
|
|
} else {
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(filteredRows.value, (e, i) => {
|
|
_push(`<div class="logrow" data-v-742ee359><div class="t" data-v-742ee359>${ssrInterpolate(fmtTime(e.ts))}</div><div data-v-742ee359><span class="${ssrRenderClass([levelInfo(e.level).cls, "lv"])}" data-v-742ee359>${ssrInterpolate(levelInfo(e.level).txt)}</span></div><div data-v-742ee359>`);
|
|
if (e.app) {
|
|
_push(`<!--[--><span class="app-name" data-v-742ee359>${ssrInterpolate(e.app)}</span>`);
|
|
if (!e.registered) {
|
|
_push(`<span class="unreg" title="该应用名未在 console 注册,快照已收到但不会写入统计库" data-v-742ee359>未注册</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--]-->`);
|
|
} else {
|
|
_push(`<span class="muted" data-v-742ee359>(无应用名)</span>`);
|
|
}
|
|
_push(`<span class="muted" data-v-742ee359> · ${ssrInterpolate(regionName(e.region))}</span><span class="muted" data-v-742ee359> · ${ssrInterpolate(fmtProduct(e.product_id))}</span></div><div class="muted" data-v-742ee359>${ssrInterpolate(e.stat_day ? fmtDay(e.stat_day) : "-")}</div><div data-v-742ee359>`);
|
|
if (e.msg) {
|
|
_push(`<!--[--><span class="${ssrRenderClass(e.level === "error" ? "text-red-600" : "text-amber-600")}" data-v-742ee359>${ssrInterpolate(e.msg)}</span>`);
|
|
if (e.summary) {
|
|
_push(`<span class="muted" data-v-742ee359> · ${ssrInterpolate(e.summary)}</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--]-->`);
|
|
} else {
|
|
_push(`<!--[-->${ssrInterpolate(e.summary || "无增量")}<!--]-->`);
|
|
}
|
|
_push(`</div><div class="t" data-v-742ee359>${ssrInterpolate(fmtTime(e.snap_ts))}`);
|
|
if (isLate(e)) {
|
|
_push(`<span class="late" data-v-742ee359>迟到${ssrInterpolate(e.ts - e.snap_ts)}s</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div></div>`);
|
|
});
|
|
_push(`<!--]-->`);
|
|
}
|
|
_push(`</div></div></div>`);
|
|
};
|
|
}
|
|
});
|
|
const _sfc_setup = _sfc_main.setup;
|
|
_sfc_main.setup = (props, ctx) => {
|
|
const ssrContext = useSSRContext();
|
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/statlog.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
const statlog = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-742ee359"]]);
|
|
|
|
export { statlog as default };
|
|
//# sourceMappingURL=statlog-DjkPa7zJ.mjs.map
|
|
|