Files
bj_power/bj_power_mes/internal/handler/attachment_monitor.go
T

106 lines
3.5 KiB
Go
Raw Normal View History

package handler
import (
"context"
"fmt"
"net/http"
"os"
"time"
"bj_power_mes/common/httpx"
"bj_power_mes/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
// diskStatusView 磁盘空间状态视图(附件中心顶部提示 + 定时告警共用)。
type diskStatusView struct {
RootDir string `json:"rootDir"`
UsedPercent int `json:"usedPercent"`
FreeBytes uint64 `json:"freeBytes"`
TotalBytes uint64 `json:"totalBytes"`
WarnPercent int `json:"warnPercent"`
CritPercent int `json:"critPercent"`
Level string `json:"level"` // ok / warn / critical / unknown
Message string `json:"message"`
CheckedAt int64 `json:"checkedAt"`
}
// diskStatus 读取附件根目录所在磁盘剩余空间并给出告警级别。
// 剩余 < DiskCriticalPercent → critical(提示执行备份归档清理);< DiskWarnPercent → warn。
func diskStatus(svcCtx *svc.ServiceContext) diskStatusView {
cfg := svcCtx.Config.Upload
root := cfg.Dir
if root == "" {
root = "uploads"
}
v := diskStatusView{
RootDir: root, WarnPercent: cfg.DiskWarnPercent, CritPercent: cfg.DiskCriticalPercent,
Level: "ok", Message: "磁盘空间正常", CheckedAt: time.Now().Unix(),
}
used, free, total, err := diskUsage(root)
if err != nil {
_ = os.MkdirAll(root, 0o755)
used, free, total, err = diskUsage(root)
}
if err != nil {
v.Level = "unknown"
v.Message = "磁盘空间检测失败:" + err.Error()
return v
}
v.UsedPercent, v.FreeBytes, v.TotalBytes = used, free, total
freePercent := 100 - used
switch {
case freePercent < cfg.DiskCriticalPercent:
v.Level = "critical"
v.Message = fmt.Sprintf("磁盘剩余空间仅 %d%%,低于 %d%%,请立即执行备份归档清理(附件中心可一键归档)", freePercent, cfg.DiskCriticalPercent)
case freePercent < cfg.DiskWarnPercent:
v.Level = "warn"
v.Message = fmt.Sprintf("磁盘剩余空间 %d%%,低于 %d%% 告警线,请及时清理", freePercent, cfg.DiskWarnPercent)
}
return v
}
// DiskStatusHandler GET /attachment/disk-status
func DiskStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
httpx.Ok(w, diskStatus(svcCtx))
}
}
// StartDiskMonitor 启动磁盘空间监控:每天 DiskCheckHour(默认 7 点) 检测一次,
// 剩余 <20% 告警、<10% 提示清理(写服务日志 + 操作日志,附件中心顶部同步展示)。
func StartDiskMonitor(svcCtx *svc.ServiceContext) {
go func() {
hour := svcCtx.Config.Upload.DiskCheckHour
if hour < 0 || hour > 23 {
hour = 7
}
for {
now := time.Now()
next := time.Date(now.Year(), now.Month(), now.Day(), hour, 0, 0, 0, time.Local)
if !next.After(now) {
next = next.Add(24 * time.Hour)
}
time.Sleep(time.Until(next))
checkDiskOnce(svcCtx)
}
}()
}
func checkDiskOnce(svcCtx *svc.ServiceContext) {
st := diskStatus(svcCtx)
switch st.Level {
case "critical":
logx.Errorf("[磁盘监控] %s(已用 %d%%,剩余 %d%%", st.Message, st.UsedPercent, 100-st.UsedPercent)
svcCtx.EventLog.Write(context.Background(), "system.disk", "", "system", "attachment", "disk", st.Message,
map[string]any{"usedPercent": st.UsedPercent, "freeBytes": st.FreeBytes})
case "warn":
logx.Alert("[磁盘监控] " + st.Message)
svcCtx.EventLog.Write(context.Background(), "system.disk", "", "system", "attachment", "disk", st.Message,
map[string]any{"usedPercent": st.UsedPercent, "freeBytes": st.FreeBytes})
default:
logx.Infof("[磁盘监控] 正常:剩余 %d%%%s", 100-st.UsedPercent, st.RootDir)
}
}