feat(contracts): 日志列表 / 日志流与资源监控契约,审计新增登录失败

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-06 17:58:08 +08:00
1 parent ad3bf8926b
commit 01c68f9771
9 files changed
+245

No files matched your search

@@ -0,0 +1,72 @@
import { z } from "zod";
import { Timestamp } from "./common.ts";
// 资源监控(界面第二轮 V 线,参考 MoviePilot 仪表盘的 CPU / 内存 / 网络组件):
// api 进程每 5 秒读一次 /proc 与 cgroup v2,采样只放内存(保留 6 小时,进程重启后从头攒)。
// 容器里优先用 cgroup(本容器的 CPU 占用、内存、磁盘读写),取不到时退回 /proc 整机口径;都取不到的字段为 null。
/** 采集口径:cgroup = 本容器(cgroup v2);host = /proc 整机;none = 取不到 */
export const ResourceScope = z.enum(["cgroup", "host", "none"]);
export type ResourceScope = z.infer<typeof ResourceScope>;
const Num = z.number().nonnegative().nullable();
export const ResourceSample = z.object({
at: Timestamp,
/** CPU 占用 %(相对可用核数,0–100) */
cpuPercent: Num,
memoryUsedBytes: Num,
memoryPercent: Num,
netRxBps: Num,
netTxBps: Num,
diskReadBps: Num,
diskWriteBps: Num,
});
export type ResourceSample = z.infer<typeof ResourceSample>;
export const SystemResources = z.object({
at: Timestamp,
/** 采样间隔(秒) */
intervalSec: z.number().positive(),
/** 返回的趋势每点代表的秒数(长时间窗口按桶取平均) */
bucketSec: z.number().positive(),
cpu: z.object({
scope: ResourceScope,
percent: Num,
/** 可用核数:cgroup cpu.max 的限额,否则为在线核数 */
cores: Num,
/** 整机 CPU 占用 %(/proc/stat),与 scope 无关 */
hostPercent: Num,
/** 整机 1 / 5 / 15 分钟平均负载(3 个数) */
load: z.array(z.number()).nullable(),
}),
memory: z.object({
scope: ResourceScope,
/** 已用:cgroup 为 memory.current − inactive_file(同 docker stats);整机为 MemTotal − MemAvailable */
usedBytes: Num,
/** 上限:cgroup memory.max(不限时退回整机总量) */
limitBytes: Num,
percent: Num,
hostTotalBytes: Num,
hostAvailableBytes: Num,
swapUsedBytes: Num,
}),
network: z.object({
scope: ResourceScope,
rxBps: Num,
txBps: Num,
rxTotalBytes: Num,
txTotalBytes: Num,
}),
diskIo: z.object({ scope: ResourceScope, readBps: Num, writeBps: Num }),
/** 整机已运行秒数(/proc/uptime) */
hostUptimeSec: Num,
samples: z.array(ResourceSample),
});
export type SystemResources = z.infer<typeof SystemResources>;
export const SystemResourcesQuery = z.object({
/** 趋势窗口(分钟),5–360,缺省 60 */
minutes: z.coerce.number().int().min(5).max(360).default(60),
});
export type SystemResourcesQuery = z.infer<typeof SystemResourcesQuery>;