feat: opt exec log
This commit is contained in:
+10
-2
@@ -215,7 +215,10 @@ func (a *Agent) closeWS() {
|
||||
}
|
||||
|
||||
func (a *Agent) readWS() {
|
||||
defer a.closeWS() // 读取结束时关闭连接,停止 heartbeatLoop
|
||||
defer func() {
|
||||
log.Info("readWS 退出,准备关闭连接")
|
||||
a.closeWS()
|
||||
}()
|
||||
|
||||
for {
|
||||
a.wsMu.Lock()
|
||||
@@ -223,6 +226,7 @@ func (a *Agent) readWS() {
|
||||
a.wsMu.Unlock()
|
||||
|
||||
if conn == nil {
|
||||
log.Warn("readWS: wsConn 为 nil")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -329,7 +333,11 @@ func (a *Agent) sendWSMessage(msgType string, data interface{}) error {
|
||||
msgBytes, _ := json.Marshal(msg)
|
||||
|
||||
a.wsConn.SetWriteDeadline(time.Now().Add(10 * time.Second))
|
||||
return a.wsConn.WriteMessage(websocket.TextMessage, msgBytes)
|
||||
if err := a.wsConn.WriteMessage(websocket.TextMessage, msgBytes); err != nil {
|
||||
log.Warnf("发送消息失败 (%s): %v", msgType, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Agent) heartbeatLoop() {
|
||||
|
||||
+15
-1
@@ -134,7 +134,7 @@ var isDaemon = false
|
||||
var isRestart = false
|
||||
|
||||
func cmdStart() {
|
||||
// 检查是否已经在运行
|
||||
// 检查是否已经在运行(使用文件锁)
|
||||
pid := readPidFile()
|
||||
if pid != 0 && isProcessRunning(pid) {
|
||||
fmt.Printf("Agent 已在运行 (PID: %d)\n", pid)
|
||||
@@ -148,6 +148,13 @@ func cmdStart() {
|
||||
}
|
||||
|
||||
// 以下是 daemon 子进程的逻辑
|
||||
// 尝试获取文件锁
|
||||
if !tryLock() {
|
||||
fmt.Println("Agent 已在运行(无法获取锁)")
|
||||
return
|
||||
}
|
||||
defer unlock()
|
||||
|
||||
initLogger(logFile, true)
|
||||
|
||||
config := &Config{Interval: 30}
|
||||
@@ -207,6 +214,13 @@ func cmdRun() {
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试获取文件锁
|
||||
if !tryLock() {
|
||||
fmt.Println("Agent 已在运行(无法获取锁)")
|
||||
return
|
||||
}
|
||||
defer unlock()
|
||||
|
||||
// 重启模式下只输出到文件(因为是从 daemon 进程 exec 过来的)
|
||||
initLogger(logFile, isRestart)
|
||||
|
||||
|
||||
@@ -12,10 +12,48 @@ import (
|
||||
|
||||
// ========== PID 文件管理 ==========
|
||||
|
||||
var pidFileLock *os.File
|
||||
|
||||
func getPidFile() string {
|
||||
return filepath.Join(dataDir, "agent.pid")
|
||||
}
|
||||
|
||||
func getLockFile() string {
|
||||
return filepath.Join(dataDir, "agent.lock")
|
||||
}
|
||||
|
||||
// tryLock 尝试获取文件锁,确保只有一个实例运行
|
||||
func tryLock() bool {
|
||||
os.MkdirAll(dataDir, 0755)
|
||||
lockFile := getLockFile()
|
||||
|
||||
var err error
|
||||
pidFileLock, err = os.OpenFile(lockFile, os.O_CREATE|os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 尝试获取排他锁(非阻塞)
|
||||
err = syscall.Flock(int(pidFileLock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
|
||||
if err != nil {
|
||||
pidFileLock.Close()
|
||||
pidFileLock = nil
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// unlock 释放文件锁
|
||||
func unlock() {
|
||||
if pidFileLock != nil {
|
||||
syscall.Flock(int(pidFileLock.Fd()), syscall.LOCK_UN)
|
||||
pidFileLock.Close()
|
||||
pidFileLock = nil
|
||||
os.Remove(getLockFile())
|
||||
}
|
||||
}
|
||||
|
||||
func writePidFile() {
|
||||
os.MkdirAll(dataDir, 0755)
|
||||
pidFile := getPidFile()
|
||||
|
||||
Reference in New Issue
Block a user