增加磁盘和网卡硬件信息显示
This commit is contained in:
152
backend/main.go
152
backend/main.go
@@ -1,10 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -34,10 +40,119 @@ func isDefaultDBConfig(cfg *config.Config) bool {
|
||||
cfg.DB.Database == "monitor"
|
||||
}
|
||||
|
||||
// daemonize 实现守护进程功能
|
||||
func daemonize() error {
|
||||
// 检查是否已经是守护进程模式
|
||||
if os.Getenv("DAEMONIZED") == "1" {
|
||||
// 设置工作目录
|
||||
if err := os.Chdir("/"); err != nil {
|
||||
return fmt.Errorf("failed to chdir to /: %v", err)
|
||||
}
|
||||
|
||||
// 重设文件权限掩码
|
||||
syscall.Umask(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取可执行文件的绝对路径
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get executable path: %v", err)
|
||||
}
|
||||
|
||||
// 创建环境变量,标记为守护进程模式
|
||||
env := append(os.Environ(), "DAEMONIZED=1")
|
||||
|
||||
// 启动新进程
|
||||
cmd := exec.Command(execPath, os.Args[1:]...)
|
||||
cmd.Env = env
|
||||
cmd.Stdin = nil
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
cmd.Dir = "/"
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setsid: true,
|
||||
}
|
||||
|
||||
// 启动进程
|
||||
if err := cmd.Start(); err != nil {
|
||||
return fmt.Errorf("failed to start daemon: %v", err)
|
||||
}
|
||||
|
||||
// 父进程退出
|
||||
os.Exit(0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// savePID 保存进程ID到文件
|
||||
func savePID() error {
|
||||
if pidFile == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取当前进程ID
|
||||
pid := strconv.Itoa(os.Getpid())
|
||||
|
||||
// 写入PID文件
|
||||
if err := os.WriteFile(pidFile, []byte(pid), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write PID file: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// removePID 删除PID文件
|
||||
func removePID() {
|
||||
if pidFile != "" {
|
||||
os.Remove(pidFile)
|
||||
}
|
||||
}
|
||||
|
||||
// 命令行参数
|
||||
var (
|
||||
// 是否以守护进程模式运行
|
||||
daemonMode bool
|
||||
// 日志文件路径
|
||||
logFilePath string
|
||||
// 进程ID文件路径
|
||||
pidFile string
|
||||
)
|
||||
|
||||
// main 函数启动服务器
|
||||
func main() {
|
||||
// 解析命令行参数
|
||||
flag.BoolVar(&daemonMode, "daemon", false, "Run as daemon (background process)")
|
||||
flag.BoolVar(&daemonMode, "d", false, "Run as daemon (background process) - shorthand")
|
||||
flag.StringVar(&logFilePath, "log-file", "", "Path to log file")
|
||||
flag.StringVar(&logFilePath, "l", "", "Path to log file - shorthand")
|
||||
flag.StringVar(&pidFile, "pid-file", "/tmp/monitor-backend.pid", "Path to PID file")
|
||||
flag.StringVar(&pidFile, "p", "/tmp/monitor-backend.pid", "Path to PID file - shorthand")
|
||||
flag.Parse()
|
||||
|
||||
// 配置日志:同时输出到文件和标准输出
|
||||
logFileName := fmt.Sprintf("monitor-backend-%s.log", time.Now().Format("2006-01-02"))
|
||||
|
||||
// 处理日志文件路径
|
||||
if logFilePath != "" {
|
||||
// 如果是相对路径,则使用可执行文件所在的目录作为基准目录
|
||||
if !filepath.IsAbs(logFilePath) {
|
||||
// 获取可执行文件的目录
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to get executable path, using current directory for log file")
|
||||
logFileName = logFilePath
|
||||
} else {
|
||||
execDir := filepath.Dir(execPath)
|
||||
logFileName = filepath.Join(execDir, logFilePath)
|
||||
}
|
||||
} else {
|
||||
logFileName = logFilePath
|
||||
}
|
||||
}
|
||||
|
||||
// 打开日志文件
|
||||
logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to open log file %s, logging only to stdout: %v", logFileName, err)
|
||||
@@ -73,6 +188,28 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 如果指定了守护进程模式,则启动守护进程
|
||||
if daemonMode {
|
||||
if err := daemonize(); err != nil {
|
||||
log.Fatalf("Failed to daemonize: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存PID文件
|
||||
if err := savePID(); err != nil {
|
||||
log.Printf("Warning: Failed to save PID file: %v", err)
|
||||
}
|
||||
|
||||
// 注册信号处理,确保进程退出时删除PID文件
|
||||
go func() {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
// 只处理可以捕获的信号
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||
<-sigCh
|
||||
removePID()
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// 创建存储实例
|
||||
store := storage.NewStorage(cfg)
|
||||
defer store.Close()
|
||||
@@ -156,6 +293,19 @@ func main() {
|
||||
handler.RegisterRoutes(r)
|
||||
|
||||
// 处理所有未匹配的路由,返回静态文件或index.html
|
||||
// 静态文件服务的路径处理:如果是相对路径,使用可执行文件所在目录作为基准目录
|
||||
staticDir := "./static"
|
||||
if !filepath.IsAbs(staticDir) {
|
||||
// 获取可执行文件的目录
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to get executable path, using current directory for static files")
|
||||
} else {
|
||||
execDir := filepath.Dir(execPath)
|
||||
staticDir = filepath.Join(execDir, staticDir)
|
||||
}
|
||||
}
|
||||
|
||||
r.NoRoute(func(c *gin.Context) {
|
||||
// 尝试提供静态文件
|
||||
file := c.Request.URL.Path
|
||||
@@ -164,7 +314,7 @@ func main() {
|
||||
}
|
||||
|
||||
// 从static目录提供文件
|
||||
c.File("./static" + file)
|
||||
c.File(staticDir + file)
|
||||
})
|
||||
|
||||
// 启动服务器
|
||||
|
||||
Reference in New Issue
Block a user