opsx
6d6e17745c
fix(logs): 恢复 POST /logs/histogram(直方图 404)+ 系统设置改为侧栏五分页
...
=== 1. 修复 /analysis 与 /logs 直方图 404(我上一轮 patch 的误伤)===
现象:分析页直接报 "API endpoint not found";日志查询页直方图不显示。
根因:37e2f0f 里一次模糊匹配的 patch 把
logs.POST("/histogram", logsCtrl.Histogram)
改成了
logs.GET("/histogram", logsCtrl.Histogram)
前端 logsApi.histogram 一直用 POST(body 带 sourceId/query/start/end),
于是 POST /logs/histogram 全部 404。访问日志实证:
POST /api/v1/logs/histogram → 404 ×7
这类"方法写错"编译期查不出来,go build / tsc 都是绿的。
修法:同时注册 POST(前端用)与 GET(curl 调试用)。
新增 backend/routers/router_test.go 守门:
TestCriticalRoutes 断言 19 条关键路由的 method+path 组合都存在
TestHistogramAcceptsPost 单独断言 histogram 必须同时有 POST 与 GET
以后再把 POST 写成 GET,测试会直接红。
=== 2. 系统设置放回侧栏,改成 5 个顶层 tab ===
按使用反馈调整:
系统设置(侧栏一个入口)
├ 通用配置 /settings ← tab 起点
├ 用户管理 /users
├ 审计日志 /audit
├ LDAP 接入 /settings/ldap ← 新拆分
└ 默认镜像源 /settings/registry ← 新拆分
为什么拆:原来 /settings 页面内部已有 4 个 tab(通用/告警通知/LDAP/镜像源),
如果侧栏再加一层 tab 就是"两层 tab",点两下才知道自己在哪。现在扁平化成单层。
配套改动:
- 新增 pages/settings/ldap.tsx、registry.tsx(各自只渲染一块内容)
- settings 主页去掉内层 Tabs,只留通用配置(外观/语言/改密码/关于)
- 上一版把设置放到了右上角齿轮,现在移除齿轮入口
- 菜单文案:settings 页标题 系统设置 → 通用配置;新增 LDAP 接入 / 默认镜像源
- 删除设置页副标题「通用配置、告警通知、LDAP 接入与默认镜像源」(用户要求去掉)
- 删除 settings 里已不存在的 tabs.notify 文案
(注意 settings.notify.* 这些 key 仍被告警页的 NotifySection 用着,保留)
=== 3. 告警通知已不在系统设置里 ===
它在上一轮就搬到了「日志告警 → 通知通道」tab,
本次顺带把系统设置里遗留的 tab 文案一并清掉,避免出现"看似有两处配置入口"。
=== 实测 ===
POST /api/v1/logs/histogram → 200(修复前 404)
go test ./... 全绿(含新增的 routers 包)
tsc -b --force 通过
2026-10-28 23:12:42 +00:00
opsx
95dcd9408c
fix(logs,analysis,alerts): 数据源不可达、分析页超时、告警规则混入基础设施项
...
=== 1. 主机模式数据源地址 0.0.0.0 → 主机真实 IP(查询页"永远加载中"的根因)===
现象:切换数据源后命名空间/App 下拉不动,一直显示"加载中…",控制台报
Get "http://0.0.0.0:3100/loki/api/v1/labels ": dial tcp 0.0.0.0:3100: connect: connection refused
根因:主机模式部署的 endpoint 记的是**容器监听地址** 0.0.0.0:3100,
而平台进程不在被采集主机上,0.0.0.0 只在本机有意义。
EnsureLogSourceForDeployment 把它原样写成了数据源 URL。
修法:
- 新增 reachableEndpoint():把 0.0.0.0 / [::] 换成关联主机的真实 IP
- schemaVersion v3→v4 迁移 fixUnreachableLogSourceURLs(),修正已有脏数据
- 实测:http://0.0.0.0:3100 → http://172.19.16.8:3100,该源 label 查询由 502 变 200
=== 2. 前端:区分"加载中"与"加载失败" ===
原来用 `loading={!options.length}` 表示加载中 —— 数据源不可达时列表永远为空,
于是界面永远转圈,把真实错误完全藏起来了(这次的 0.0.0.0 就是这样被掩盖的)。
改为独立的 namespaceLoading / namespaceError 两个状态:
- 切换数据源先清空旧 options(否则显示上一个源的命名空间,看着像"没反应")
- 失败显示"加载失败"并在旁边给「重试」按钮,不用刷新整页
=== 3. 日志分析页:主图改走索引接口(原来 5 条 count_over_time 全超时)===
实测 astralx(约 370GB/天)15 分钟窗口:
count_over_time → exec 29s + 排队 95s,超过 30s 护栏 → 502
index/volume_range → 0s
改为两阶段渲染:
- 总量趋势改用 /logs/histogram(内部 index/volume_range),**0s 出图**
- 错误/警告/app 维度仍需读日志内容,串行执行,先渲染主图再更新
- heavyQueryTimeout 30s → 90s(实测 error 维度查询 14s 可完成)
=== 4. 告警规则按日志平台定位收敛 ===
- seed 里删掉「Kubernetes 节点 NotReady」「容器 OOMKilled」:
这类属于 kube-state-metrics / Prometheus 的职责,用日志字符串匹配不可靠
- 迁移里清掉线上已存在的同类规则(3 条)
- 修 AlertRule / NotifyChannel 重复 ID(同 logSources 一样漏在 sequences 重建外)
=== 5. 告警页 UI ===
- 规则列表由"每条一张卡"改为紧凑表格(一屏看全,阈值可对齐比较)
- 通知通道(飞书/Lark/Webhook)从「系统设置」搬到告警页折叠区:
规则和"发到哪"是一件事的两半,分两页配容易漏配导致告警发不出去
=== 6. 权限收敛 ===
- /alerts 加 adminOnly:普通用户按查询授权只看「日志查询」,不再看到告警菜单
- 系统设置从侧栏移到右上角齿轮(低频平台配置,不占侧栏一位)
=== 7. 迁移设计教训(写进代码注释)===
v2 时把"告警去重 + 清基础设施规则"塞进 case 1,但线上库已到 v2,
那段代码永远不执行。**结构变更只要逻辑变了、目标库已达该版本,就必须再抬一版**,
不能改历史迁移分支。
=== 实测(v4-1028-2210 / 979bdb4a48e8)===
v4 迁移:数据源 URL 修正 http://0.0.0.0:3100 → http://172.19.16.8:3100
source 1 label:200,0s(astralx / log)
source 2 label:200,0s(不再 connection refused)
分析页 histogram astralx 15m:0s
分析页 metrics error astralx 15m:14s
告警规则:10 条(已无基础设施类)、ID 唯一
另清理 172.19.16.8 上 13 个残留容器,回收 6.1GB
2026-10-28 22:11:48 +00:00
opsx
1a4c75e28c
feat(menu): 日志查询/日志分析拆为独立菜单 + 部署菜单改名「组件部署」
...
按使用反馈调整信息架构:
=== 1. 日志查询、日志分析保持独立菜单(不折叠)===
上一版把两者并进「日志」分组,实际使用中不方便:
- 日志查询是最高频入口,不该多点一次 tab 才到
- 日志分析是管理员专用的聚合视图,与查询的心智模型不同
改为两个独立菜单项,/logs 的菜单名保持「日志查询」不变(用户明确要求),
/analysis 保留 adminOnly(仅管理员可见)。
=== 2. /deployments 菜单改名:部署 Loki → 组件部署 ===
命名评估(三个候选):
组件部署 ✅ 选中:部署对象是基础设施组件(Loki 实例),
与本环境大量 cex-* 业务服务明确区分。
运维在侧栏看到「服务部署」第一反应会是"发布业务服务",容易误点。
服务部署 ✗ 与业务服务语义冲突
部署 Loki ✗ 以后支持多组件(Fluent Bit / Grafana)就名不副实
文案改动:菜单 menu.deployments、页面标题、组内 tab 全部统一为「组件部署」,
en 同步为 Component Deploy / Component Deploy 页面标题。
=== 3. 顺带修:启动日志每次都打印「首次部署」===
旧实现无条件打印
log.Printf("首次部署请查看启动日志或 %s/initial-admin-password.txt ...")
于是每次重启日志里都有「首次部署」,排查时极易被误导成
"平台重新初始化了、数据是不是丢了"(本次就因此自查了一轮)。
改为仅当密码文件存在时才提示(admin 改密后该文件会被删除)。
=== 当前菜单结构(8 项)===
仪表盘 / 部署向导 / 资源接入(集群·主机·存储) / 日志服务(组件部署·日志采集)
/ 日志查询 / 日志分析(admin) / 日志告警 / 系统管理(用户·审计·设置)
=== 实测 ===
bundle 文案:组件部署1 日志查询2 日志分析2 资源接入1 日志服务1 系统管理1
启动日志「首次部署」出现次数:0
CLI self-check:overall=ok(数据库 54.7 KB,CLI 模式读取)
CLI backup:记录数 88(修复前为 0)、密钥指纹 d714ebda23908331
镜像:lghost/lokistack:latest + v0.1 = aa6313fee5bb
2026-10-28 21:44:15 +00:00
opsx
b49677f6a6
feat: 运维标杆化打磨 P0/P1/P2 —— 审计日志、真实指标、备份恢复、菜单收敛
...
审计发现 5 处硬伤(/metrics 空壳、零备份、prod 双副本数据分裂、零审计、资源偏紧),
本轮全部落地。
=== P0-1 真实 /metrics(原来是空壳)===
原实现只返回一行注释 `# LokiStack Metrics`,注释却写着"可被 Prometheus 抓取",
平台挂了/DB 写不进去/告警引擎卡死都只能靠用户反馈。
现接入 prometheus/client_golang,四层指标:
HTTP : lokistack_http_requests_total / _duration_seconds / _in_flight_requests
存储 : lokistack_db_size_bytes / _db_save_duration_seconds / _db_save_total / _db_records
业务 : lokistack_deployments{status,mode} / lokistack_collectors{status,type,run_mode}
后台任务: lokistack_alert_evaluations_total / _duration_seconds / lokistack_loki_queries_total
+ go_* / process_*(GoCollector、ProcessCollector)
关键点:path 标签用 c.FullPath() 路由模板,不用原始 URL —— 否则 117 个 Deployment
会把 Prometheus 基数炸掉。指标定义下沉 pkg/metrics 叶子包,避开
services ↔ repository 循环依赖。
=== P0-2 备份与恢复(原来 0 处代码)===
平台全部状态在 /app/data/opsxloki.json(51KB)+ kubeconfigs/ + known_hosts/,
DB 丢了 = 失去"这些资源是谁建的"的映射,从此无法管理/卸载/升级在跑的 Loki。
CLI : lokistack backup --output <path> / restore <pkg> / self-check / version
API : GET /system/backup(下载)/ POST /system/restore(校验暂存)/
POST /system/restore/apply(确认应用)/ GET /system/backups
K8s : kubernetes/pdb-backup.yaml —— 每日 03:30 CronJob,保留最近 7 份
安全设计:
- manifest.json 记录 ENCRYPTION_KEY 的 sha256 前 16 位**指纹**,用于恢复时
校验"这把钥匙能不能解开这份备份",不泄露密钥本身
- 恢复分两步(校验暂存 → 确认应用),应用前自动把当前 DB 备份为
opsxloki.json.before-restore.<时间戳>
- 包内不含明文密钥(kubeconfig 本就是加密态)
=== P0-3 prod compose 双副本 → 单副本 ===
lokistack-1 / lokistack-2 各挂独立数据卷 + nginx 轮询 = 数据分裂:
页面刷新两次可能看到不同结果,写操作只落一个副本。不是高可用。
已改单实例(nginx 仅做反代),文件顶部与 nginx.conf 都写明原因。
=== P0-4 操作审计日志(借鉴 /usr/local/src/aiops 的字段口径)===
aiops 是每个 controller 各写 recordXxxAudit();本平台有 60+ 写接口,
逐个埋点必然漏,漏掉的那个恰好最危险(删集群、改存储凭证)。
改为 **gin 中间件统一记录** + handler 通过 SetAudit 补充业务语义:
models/audit.go : 字段对齐 aiops,另加 Method/Path/Before/After
services/audit.go : 写入 + 90 天/2 万条自动裁剪 + 脱敏 + diff 生成
middleware/audit.go : 自动识别 module/action/resource,跳过只读接口
controllers/audit.go: 列表/详情/统计(仅 admin)
敏感字段(password/secretKey/privateKey/token)写入前统一替换为 ***。
=== P1 稳定性 ===
- 平台资源 1C/1Gi → 4C/4Gi 限(500m/512Mi 请求):JSON DB 全量读写 +
每分钟告警评估 + 批量发布并发,1Gi 会 OOM
- terminationGracePeriodSeconds: 30 —— 收到 SIGTERM 要等 DB 完整落盘,
否则 kubelet SIGKILL 会把 JSON 写一半(全库丢失)
- liveness timeoutSeconds 10s(默认 1s 写盘时会被误杀)
- PDB minAvailable: 0 —— 让 kubectl drain 正确等待重建,不卡维护
- DB schemaVersion + migrateSchema() 版本递进迁移(原先加字段全靠零值兜底)
- scripts/release.sh —— 不可变 tag <版本>-<日期>-<commit> + IfNotPresent,
根治 latest 并发构建互相覆盖导致的静默回滚(本项目已实际踩过)
- PVC 保持 30Gi(按长期增长预留,云盘单价低,不做在线扩容)
=== P2 易用性 ===
- 一键自检 GET /system/self-check + 仪表盘自检卡:真实探活 Loki /ready、
集群凭据解密、磁盘空间、主机状态、近 24h 失败操作
- 审计日志页 /audit:统计卡 + 用户名/模块/结果筛选 + 变更前后 diff 弹窗
- 菜单收敛 13 → 7(页内 tab 切换,URL 全部不变):
资源接入 = 集群 + 主机 + 存储
日志服务 = Loki 实例 + 采集器
日志 = 查询 + 分析
系统管理 = 用户 + 审计 + 设置
新增 GroupTabs 组件 + meta.group/groupKey,侧栏按分组去重并正确高亮
测试:go vet 通过、go test 全绿、tsc 通过
2026-10-28 21:27:01 +00:00
Codex
11d0fff764
fix(frontend): 补齐 analysis 构建依赖与共享组件搬迁
...
补 commit hooks/图表组件、路由与 i18n domains、logs metrics API;
StatCard/TimeRangePicker/ingress-access-log 抽到共享路径,干净 checkout 可编过。
2026-10-28 22:00:30 +08:00
opsx
f3733f0bfc
feat: 品牌统一 LokiStack + 全站中英 i18n + 用户批量删除 + 主题定时切换与浅色侧栏
...
- 品牌: Go 模块/数据文件/二进制/构建部署资产全部 opsx→lokistack;前端 localStorage 命名空间迁移(读旧写新,含按用户 id 前缀迁移);修复 nginx upstream 与 Makefile 引用已改名服务的断裂
- i18n: react-i18next 落地,common + 11 个页面域命名空间全站中英(菜单/顶栏/登录/列表页/表单/确认弹窗/状态徽章);设置页语言即时切换;修复词典自注册导致的循环导入白屏
- 用户管理: 批量删除(POST /users/batch-delete,不删自己/最后管理员,部分失败不阻断)+ 行复选/全选/批量工具条
- 主题: 浅色侧栏(中性灰激活态)、四态模式(浅色/深色/跟随系统/定时切换,按时区判定)、顶栏太阳月亮二态、设置页紧凑分段选择器
- UI: 登录记住用户名、CardActionButton 统一五页卡片操作钮、shadcn Badge 替换手写徽章、语义色修正
- 清理: 移除主机 Web 终端(前后端)、k8s-helm/Helm 遗留代码与字段、README 重写精简
- 修复: 侧栏与日志告警 order 重复、路由标题 i18n key 未翻译、词典双逗号等
2026-10-27 17:11:38 +08:00
logan
2d73661dd1
feat: complete Loki query, insights, settings and deployment workflows
...
Add the Loki query UI, access policies, ingress insights, alert and registry settings, and their backend APIs. Include the related Kubernetes deployment and collector updates required by the integrated application.
Validated with go test ./..., npm run build, and npm run lint.
2026-10-25 21:28:32 +08:00
logan
f9c6c1d826
feat: opsx-loki 全面升级 — 前端重构/用户与LDAP/部署向导/日志查询
...
基于 WEB-UI-Development-Guide 标准的整体升级,并更名 LokiDeploy → opsx-loki。
前端(Gin+React+shadcn/ui):
- 按 02/07 章重构:页面域化拆分(无超 400 行文件)、PageContainer/ListQuery、
反馈分级(成功静默/失败 toast/危险确认)、401 单飞刷新+队列重放
- 暗色模式(next-themes)+ 语义 Token(--primary 品牌色/success/warning/info)
- 部署向导(状态推导四步:环境→存储→Loki→采集,内嵌表单闭环)
- 日志查询页:LogQL 标签构建器/拖拽直方图/日志上下文/Live Tail/查询历史
- 按用户+标签策略的查询授权(服务端强制合并策略)
后端(Go+Gin+JSON DB):
- 简单用户管理(仅 admin,无 RBAC)+ TokenVersion 会话吊销 + 登录 IP 限流
- LDAP 接入:配置(AES 加密存储/hasPassword 脱敏)/测试连接/批量导入/登录
- 存储配置测试连接(SigV4 零依赖)+ 桶不存在自动创建
- Loki 三模式部署修复:SSH 密钥认证、3.x 配置模板、ruler 对象存储嵌套块、
凭证解密、孤儿 deploying 状态恢复、Grafana 部署(可选默认关)+面板导入
- DaemonSet 采集纯 YAML(去 helm 依赖)+ DNS 自愈回退 ClusterIP + 集群名标签
- 日志查询代理:cluster-svc 经 kube-apiserver proxy/url 直连 + cursor 翻页
- 统一 log 命名空间;部署就绪探活;Grafana 访问地址自动记录
修复:run.sh 增量编译检测、Sanitized 脱敏补全、LokiDeployment Update 白名单、
健康检查 CreatedAt 零值等 10+ 存量 bug。
数据兼容:DB 沿用旧 lokideploy.json(新名优先);localStorage 一次性迁移;
HKDF 加密前缀保留(已加密凭证不受影响)。
2026-10-24 13:20:12 +08:00