Files
aiops/CLAUDE.md
T

12 KiB
Raw Blame History

CLAUDE.md — AIOps

本文档为 Claude Code / Hermes 等 AI 编程助手提供在代码库中工作的指导说明。

作者:Logan.Li 语言:中文(代码注释和文档主要使用中文,注释署名 // Logan.Li)

项目概述

AIOps 是一个企业级智能运维平台,聚焦三大核心能力:

  1. 资产管理 — 服务器管理、云资源(云账号/域名/账单)、K8s 集群
  2. 监控告警 — Agent 采集指标、告警引擎(资源阈值/离线检测)、告警中心、日志能力、链路追踪、监控大屏
  3. 自动化运维 / AIOps — CronJob/Script/Ansible 自动化、资源申请审批、AI 智能运维(告警分析/故障诊断/脚本生成)

核心特性

  • Agent 双通道 — 指标采集通道(10s 上报 /proc)+ 远程任务通道(5s 轮询执行命令)
  • LDAP 集成 — 配置管理、用户导入、OU 管理、LDAP 用户 CRUD
  • 资源申请审批 — 云服务器申请、应用部署申请(Git 地址/端口/Nacos 等配置),动态表单
  • 5 套主题 — CSS 变量驱动,暗色/亮色/紫色/绿色/玫红一键切换
  • WebShell — WebSocket 终端,在线 SSH 操作服务器

技术栈

层 技术 端口
后端 Go 1.21 + Gin + GORM + SQLite (CGO) + JWT + Zap 8080
前端 React 19 + TypeScript + Vite + Tailwind + shadcn/ui + Zustand + TanStack Query 5173
Agent Go 1.24 (CGO_ENABLED=0 静态二进制, amd64+arm64) —

常用命令

快速启动

./run.sh start          # 启动前后端
./run.sh stop           # 停止服务
./run.sh restart        # 重启服务
./run.sh status         # 查看服务状态
./run.sh logs           # 查看实时日志

后端 (backend/)

cd backend

# 编译(每次修改后端必须执行)
unset http_proxy https_proxy && export GOPROXY=https://goproxy.cn,direct && GOTOOLCHAIN=local CGO_ENABLED=1 go build -o aiops-server ./cmd/

# 直接运行
go run ./cmd/

# 代码检查
go vet ./...

前端 (frontend/)

cd frontend
npm run dev             # 开发服务器 (端口 5173)
npm run build           # 生产构建
npx tsc --noEmit        # 类型检查(提交前必须零错误)

Agent (agent/)

cd agent

# 本地构建(macOS 测试用)
CGO_ENABLED=0 go build -o aiops-agent .

# 交叉编译
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o aiops-agent-linux-amd64 .
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o aiops-agent-linux-arm64 .

# 运行 Agent
./aiops-agent --server http://localhost:8080 --token <JWT_TOKEN>

架构说明

项目结构

aiops/
├── backend/
│   ├── cmd/
│   │   ├── main.go              # 应用入口
│   │   └── seed.go              # 种子数据(用户/角色/审批模板/LDAP配置)
│   ├── internal/
│   │   ├── config/config.go     # Viper 配置
│   │   ├── models/              # GORM 模型(每模块独立文件)
│   │   └── api/
│   │       ├── handlers/        # HTTP handler(按模块拆分,每文件 <400 行)
│   │       ├── middleware/auth.go  # JWT + Admin 中间件
│   │       └── routes/routes.go    # 路由注册
│   ├── pkg/database/database.go  # DB 连接 + AutoMigrate
│   └── scripts/mock.go          # Mock 种子(已废弃)
│
├── frontend/
│   ├── src/
│   │   ├── components/
│   │   │   ├── dashboard/       # 仪表盘(统计/图表/最近活动)
│   │   │   ├── server/          # 服务器管理
│   │   │   ├── cloud/           # 云资源管理
│   │   │   ├── k8s/             # K8s 集群管理
│   │   │   ├── deploy/          # 应用发布(CI/CD 流水线)
│   │   │   ├── monitor/         # 监控告警(指标/告警中心/日志/大屏/Agent告警)
│   │   │   ├── automation/      # 自动化运维(CronJob/Script/Ansible)
│   │   │   ├── approval/        # 资源申请审批
│   │   │   ├── aiops/           # AI 智能运维
│   │   │   ├── system/          # 系统管理(用户/LDAP/审计)
│   │   │   ├── navigation/      # 站内导航
│   │   │   └── layout/          # 布局(Sidebar/Header)
│   │   ├── services/
│   │   │   ├── api.ts           # API 定义(按模块分组)
│   │   │   └── http.ts          # Axios 封装(拦截器自动注入 Token)
│   │   ├── store/               # Zustand 状态管理
│   │   ├── hooks/               # React hooks(useConfirm 等)
│   │   └── types/index.ts       # 全局类型
│   └── App.tsx                  # 路由 + 顶层 Provider
│
├── agent/                        # 监控 Agent(独立 Go module)
│   ├── main.go                   # CLI 入口
│   ├── collector/                # /proc 采集器(CPU/内存/磁盘/端口)
│   ├── task/                     # 远程任务执行器(command/script)
│   ├── reporter/http.go          # HTTP 上报
│   └── model/model.go            # 数据结构
│
└── run.sh                        # 一键启动脚本

后端分层

handlers/ (HTTP 处理) → models/ (GORM 数据操作)
     ↓
middleware/auth.go (JWT 验证)

新增模块 4 步:

  1. models/xxx.go — 定义 GORM 模型
  2. handlers/xxx.go — 实现 handler(所有返回必须用 models.Response{Code:200} 包裹)
  3. routes/routes.go — 注册路由
  4. pkg/database/database.go — 添加 AutoMigrate

API 响应格式

// 统一响应(所有 handler 必须遵循)
type Response struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}

// 列表响应(Data 内层)
type ListResponse struct {
    List  interface{} `json:"list"`
    Total int64       `json:"total"`
}

前端 http.ts 已自动提取 .data,所以组件中拿到的是 Response.Data。列表 API 返回 {list, total},组件中需 .list 提取数组。

认证流程

Login(本地/LDAP fallback) → JWT Token → 前端 Zustand persist 存储
→ http.ts 自动注入 Bearer → JWTAuth 中间件验证 → AdminAuth 中间件(管理类路由)

Agent 双通道架构

指标通道: ticker(10s) → collect(/proc) → POST /agent/report
任务通道: ticker(5s)  → GET /agent/tasks/poll → execute → POST /agent/tasks/:id/result

告警引擎

  • 内嵌后端 cron 定时器,每分钟扫描 AgentReport
  • 资源阈值告警 — CPU/内存/磁盘超阈值(需配置规则)
  • 主机离线告警 — 内置检测(3 分钟无数据上报即告警,不需配置规则)
  • 端口告警 — 监控端口消失

开发规范

⛔ 文件大小红线

类型 上限 超出处理
Go handler 400 行 按 sub-domain 拆分到独立文件(同一 package)
Go model 300 行 按模块拆分
React 组件 (.tsx) 700 行 提取子组件到同目录
任何文件 700 行(硬上限) 必须拆分
# 检查超限文件
find backend -name "*.go" -not -path "*/vendor/*" | xargs wc -l | awk '$1 > 400 && $2 != "total"'
find frontend/src -name "*.tsx" -o -name "*.ts" | xargs wc -l | awk '$1 > 700 && $2 != "total"'

⛔ Go 代码规范

  1. 所有 handler 返回必须用 models.Response{Code:200, Data:...} 包裹 — 前端 http.ts 从 json.data 取值,裸 gin.H{} 会导致前端拿到 undefined 静默失败
  2. 编译命令(每次必须):
    cd backend && unset http_proxy https_proxy && export GOPROXY=https://goproxy.cn,direct && GOTOOLCHAIN=local CGO_ENABLED=1 go build -o aiops-server ./cmd/
    
  3. 新增 handler 不绑 model — 用独立 request struct 接收 ShouldBindJSON,再映射到 GORM model
  4. GORM 指针字段必须解引用 — model 中 *int/*string 字段传给 fmt.Sprintf 时先 *field
  5. SQLite 必须 CGO_ENABLED=1(macOS 默认开)

⛔ React 前端规范

  1. API 列表响应解包 — 后端返回 {code, data: {list: T[], total: N}},http.ts 提取 .data 后仍是 {list, total} 对象,组件中必须 .list 提取数组
  2. 禁止 window.confirm()/alert() — 用 ConfirmProvider(useConfirm() hook)替代,用 toast.error()/toast.success() 替代 alert
  3. Radix Dialog 必须有 <DialogDescription> — 至少加 <DialogDescription className="sr-only">
  4. Token 不在 localStorage — 用 useUserStore.getState().token(Zustand persist)
  5. 新增组件 2 步: API 层(services/api.ts 添加) → 组件+路由(App.tsx 加 Route,Sidebar.tsx 加菜单)

⛔ UI 设计原则

  • 能去掉的都去掉 — 不要多余边框、高亮框、装饰性分隔线
  • 按钮文案 2-4 字 — "批量导入" 而非 "批量导入用户"
  • 不留占位按钮 — 功能没做好就不放按钮,不要 toast.info('开发中')
  • 页面打开即用 — 不需要额外"新建"按钮跳转
  • 主题感知 — 用 CSS 变量 bg-[var(--dg-bg-secondary)],不用硬编码颜色
  • 表单操作按钮在字段下方 — 用 mt-4 pt-4 border-t 分隔,不放 Card 标题右侧
  • 主动排查同类问题 — 用户报一个 UI 问题,全局搜索同类一次性修复

⛔ 通用开发流程

分析需求 → 写代码 → go build + tsc --noEmit → ./run.sh restart → 浏览器验证 → git commit + push
  • 修改前端后必须在浏览器实际测试,不能只说"刷新试试"
  • 提交前编译验证:后端 go build ./...,前端 npx tsc --noEmit && npm run build
  • Git 提交: git add -A && git commit -m "feat: 描述" && git push origin master
  • 大变更前先 git commit — 方便回滚
  • 开发日志: 每次开发后更新 docs/dev-log.md

默认账号

用户名 密码 角色
admin 123456 超级管理员
ops01 123456 运维
dev01 123456 开发
logan zxc987 LDAP 用户

⚠️ 生产环境请修改默认密码

主题系统

5 套预设主题(CSS 变量驱动):

Key 名称 场景
ocean-deep 深海蓝(默认) 暗色主界面
light-professional 专业亮色 亮色模式
midnight-purple 午夜紫 个性化
forest-green 森林绿 个性化
dark-rose 暗夜玫红 个性化

所有组件必须用 var(--dg-xxx) 变量,禁止硬编码颜色值。

访问地址

  • 前端:http://localhost:5173
  • 后端:http://localhost:8080
  • 健康检查:http://localhost:8080/health
  • Agent 下载:http://localhost:8080/agent/arch

常见陷阱速查

# 陷阱 解决
Go1 go build 超时 unset proxy + GOPROXY=goproxy.cn + GOTOOLCHAIN=local
Go2 handler 不包裹 Response 必须 models.Response{Code:200, Data:...}
Go3 GORM 指针字段 *field 解引用后再用
Go4 GORM First() 连续查带上次 ID 用 Take()
Go5 go map literal 不能有 duplicate key 检查重复键
FE1 白屏无堆栈 90% 是列表 {list,total} 未解包
FE2 confirm() 冻结自动化 用 useConfirm()
FE3 Token 获取 useUserStore.getState().token,不是 localStorage
FE4 Radix Dialog 警告 必须有 <DialogDescription>
FE5 browser_click 不触发 toggle 改用 browser_console 注入 .click()
FE6 API 字段名不匹配 前端 base_dn vs 后端 ou_dn 类型问题

注释规范

新增或修改代码必须写中文注释,注释结尾署名 // Logan.Li。

// ListServers 获取服务器列表 // Logan.Li
func (h *ServerHandler) ListServers(c *gin.Context) {
    // 业务逻辑
}

远程仓库

https://gitee.com/attacker/aiops.git
Git 用户: attacker / attacker@gitee.com