opsx
5e59347c40
feat(settings,analysis): 日志保留时间可配(发送历史保留 7 天)+ 分析页手动刷新;修复我引入的 RWMutex 死锁
...
=== 0. 【严重】修复上一版引入的死锁(平台写路径全卡死)===
上一版把保留期读取写成 `GetRetentionSettings()`(内部 db.RLock()),
却在 `db.Lock()` 已持有的情况下调用(recordDelivery / RecordAudit 的裁剪路径)。
Go 的 sync.RWMutex **不可重入** → 第一次写投递历史/审计日志就永久死锁。
现象:登录 28 秒返回空(登录也要写审计)、所有写接口挂住。
go build / go vet / 之前的单测(不触发写路径)全都查不出来。
修法:
- 拆出 retentionFromDBLocked(db) / alertDeliveryRetentionLocked(db) /
auditLogRetentionLocked(db),调用方已持锁时用无锁版本
- upsertSettingLocked 里**不能**用 db.NextID()(内部 d.mu.Lock(),同样死锁),
改为锁内自算 max(id)+1
- 新增 retention_test.go:持写锁调用裁剪函数,2 秒超时未返回即判死锁
实测修复后:登录 103ms(原 28000ms)、panic/deadlock 命中 0。
=== 1. 平台数据保留期可配(系统设置 → 通用配置 → 日志保留时间)===
新增 GET/PUT /api/v1/settings/retention:
alertDeliveryDays 告警发送历史保留天数,默认 7(原写死"最近 50 条")
auditLogDays 审计日志保留天数,默认 90(原写死常量)
保存后立即按新策略裁剪一次,不必等下次触发。
校验:发送历史 1~365 天、审计 1~3650 天,超出返回明确中文原因(不是 500)。
注意与「Loki 日志保留期」区分:那个是部署级配置(组件部署 → 保留策略)。
=== 2. 发送历史:50 条硬上限 → 保留 7 天 ===
后端 Deliveries 接口原来写死 `len(out) < 50`,现在按保留期取(响应上限 500 可调),
标题改为「发送历史(保留 N 天)」,N 从设置里读。
=== 3. 菜单「日志服务」→「组件部署」===
=== 4. 分析页:去掉「全部命名空间」+ 改手动刷新 ===
- 移除「全部命名空间」选项:{namespace=~".+"} 要扫全集群(约 370GB/天),
一次分析几十秒,得不偿失;历史值 __all__ 也会被忽略并回退到策略/第一个 ns
- 筛选改为「选择值 / 已生效值」分离:切换命名空间或时间范围**不再自动查询**,
只把刷新按钮点亮并提示「筛选条件已改,点刷新生效」;
点一次才应用并取数。
原因:一次分析要跑多条 count_over_time,切一下下拉就重查一轮,
快速连点会把 Loki 打满(并发护栏 429),还拖慢别人。
=== 实测(9739c7c092e7)===
登录 103ms / token 273 字符
GET retention → {alertDeliveryDays:7, auditLogDays:90}
PUT 0 天 → 400「告警发送历史保留天数需在 1~365 之间」
平台日志 panic/deadlock 命中 0
go test ./... 全绿(含 2 个新死锁回归用例)
2026-10-29 04:16:52 +00:00
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
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
opsx
d0b9b6b71d
fix(ui): 前端用户可见文案 opsx-loki → lokistack
...
修正用户能看到/会复制走的旧名(你反馈的 K8s 示例 token 命令在内):
1. 界面标题(4 处)
App.tsx 浏览器标题栏
Layout.tsx 侧边栏 logo / 页面标题 fallback / 移动端导航
login/index.tsx 登录页大标题
settings/index.tsx 「关于 lokistack」
2. 集群接入示例(用户直接复制到集群执行,5 处)
ClusterFormDialog.tsx:
Role / ServiceAccount 名: opsx-loki → lokistack
token Secret 名: opsx-loki-token → lokistack-token
取 token 命令: get secret opsx-loki-token → lokistack-token
3. 文档
docs/deployment/README.md, host-nginx.md 旧名全量修正
README.md 迁移章节之外的示例命令修正;
迁移章节(从 opsx-loki 升级)保留旧名作历史对照
【刻意不改】
a) localStorage key(9 个)
opsxloki.auth.{token,refresh-token,user}
opsxloki.theme.mode / layout.collapsed / chunk-reloaded
opsxloki.logs.{query-history,range-history}
原因:改了所有在线用户立即掉登录,主题/折叠/查询历史全丢。
要改必须配套迁移(参考 main.tsx 中 lokideploy.* → opsxloki.* 的写法)。
b) 数据文件名 opsxloki.json(后端硬编码,改了读不到 DB)
c) Go module 路径 opsxloki/...(159 处 import)
属编译期内部标识,最终用户不可见;改名需全仓重构 + go.mod 变更。
2026-10-26 17:30:30 +00:00
logan
9f7c522157
feat: K8s 部署清单、Token 接入加固与日志/设置页优化
...
- kubernetes/: 30Gi PVC、单副本 Recreate、Secret/Service/NodePort/Ingress 清单与部署文档
- 数据安全: kubeconfig/token 统一加密存储,启动迁移历史明文,DB 0600
- Token 接入: 命名空间级最小权限提示、长期 Token、自签证书 TLS 兼容
- 部署: 命名空间级 Token 下跳过 Namespace patch/枚举,节点信息容错
- 日志页: namespace → app → pod 选择顺序与作用域收窄
- 设置页: 拆分为通用/告警/LDAP/镜像源四个 tab
- 弹框: 统一 max-h 滚动与长命令换行,修复内容溢出
2026-10-25 23:44:07 +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