init
This commit is contained in:
commit
685abe69ca
17
config.json
Normal file
17
config.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"processes": [
|
||||
{
|
||||
"process_name": "chrome",
|
||||
"file_name": "",
|
||||
"kuma_url": "http://192.168.123.10:3001/api/push/AkN14NLK1G?status=up&msg=OK&ping=",
|
||||
"check_interval": 60
|
||||
},
|
||||
{
|
||||
"process_name": "process-monitor",
|
||||
"file_name": "process-monitor.exe",
|
||||
"kuma_url": "http://192.168.123.10:3001/api/push/AkN14NLK1G?status=up&msg=OK&ping=",
|
||||
"check_interval": 60
|
||||
}
|
||||
]
|
||||
}
|
||||
|
184
main.go
Normal file
184
main.go
Normal file
@ -0,0 +1,184 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ProcessConfig 进程配置结构体
|
||||
type ProcessConfig struct {
|
||||
ProcessName string `json:"process_name"`
|
||||
FileName string `json:"file_name"` // 文件名
|
||||
KumaURL string `json:"kuma_url"`
|
||||
CheckInterval int `json:"check_interval"`
|
||||
}
|
||||
|
||||
// Config 整体配置结构体
|
||||
type Config struct {
|
||||
Processes []ProcessConfig `json:"processes"`
|
||||
}
|
||||
|
||||
// ProcessMonitor 进程监控结构体
|
||||
type ProcessMonitor struct {
|
||||
config ProcessConfig
|
||||
httpClient *http.Client
|
||||
status string
|
||||
logDir string
|
||||
}
|
||||
|
||||
// NewProcessMonitor 创建新的进程监控
|
||||
func NewProcessMonitor(config ProcessConfig, logDir string) *ProcessMonitor {
|
||||
return &ProcessMonitor{
|
||||
config: config,
|
||||
httpClient: &http.Client{},
|
||||
status: "down",
|
||||
logDir: logDir,
|
||||
}
|
||||
}
|
||||
|
||||
// LoadConfig 加载配置文件
|
||||
func LoadConfig(filename string) (*Config, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var config Config
|
||||
if err := json.NewDecoder(file).Decode(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// InitLogFile 初始化日志文件
|
||||
func InitLogFile(logDir string) (*os.File, error) {
|
||||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create log directory: %v", err)
|
||||
}
|
||||
|
||||
logFile := filepath.Join(logDir, time.Now().Format("2006-01-02")+".log")
|
||||
file, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %v", err)
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
// IsProcessRunning 检查进程是否正在运行
|
||||
func (pm *ProcessMonitor) IsProcessRunning() bool {
|
||||
output, err := exec.Command("tasklist").Output()
|
||||
if err != nil {
|
||||
log.Printf("Error retrieving process list: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
lines := string(output)
|
||||
for _, line := range strings.Split(lines, "\n") {
|
||||
if strings.Contains(line, pm.config.ProcessName) {
|
||||
// 如果指定了文件名,则检查文件名
|
||||
if pm.config.FileName == "" || strings.Contains(line, pm.config.FileName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PushStatusToKuma 向 Uptime Kuma 推送状态
|
||||
func (pm *ProcessMonitor) PushStatusToKuma() error {
|
||||
response, err := pm.httpClient.Get(fmt.Sprintf("%s?status=%s", pm.config.KumaURL, pm.status))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
log.Printf("Pushed status '%s' for process '%s' fileName '%s' to Uptime Kuma: %s", pm.status, pm.config.ProcessName, pm.config.FileName, response.Status)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Monitor 监控进程状态
|
||||
func (pm *ProcessMonitor) Monitor() {
|
||||
ticker := time.NewTicker(time.Duration(pm.config.CheckInterval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
pm.checkAndPushStatus() // 启动时立即检查一次
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
pm.checkAndPushStatus()
|
||||
case <-time.After(24 * time.Hour): // 每天执行日志清理
|
||||
pm.cleanOldLogs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkAndPushStatus 检查进程状态并推送到 Uptime Kuma
|
||||
func (pm *ProcessMonitor) checkAndPushStatus() {
|
||||
pm.status = "down"
|
||||
if pm.IsProcessRunning() {
|
||||
pm.status = "up"
|
||||
}
|
||||
if err := pm.PushStatusToKuma(); err != nil {
|
||||
log.Printf("Error pushing status for process '%s' fileName '%s': %v", pm.config.ProcessName, pm.config.FileName, err)
|
||||
}
|
||||
}
|
||||
|
||||
// cleanOldLogs 清理旧日志
|
||||
func (pm *ProcessMonitor) cleanOldLogs() {
|
||||
logFiles, err := os.ReadDir(pm.logDir)
|
||||
if err != nil {
|
||||
log.Printf("Error reading log directory: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
threshold := time.Now().AddDate(0, 0, -30) // 30天前的日期
|
||||
for _, logFile := range logFiles {
|
||||
if logFile.Type().IsRegular() {
|
||||
if fileInfo, err := logFile.Info(); err == nil {
|
||||
if fileInfo.ModTime().Before(threshold) {
|
||||
if err := os.Remove(filepath.Join(pm.logDir, logFile.Name())); err != nil {
|
||||
log.Printf("Error deleting old log file '%s': %v", logFile.Name(), err)
|
||||
} else {
|
||||
log.Printf("Deleted old log file: '%s'", logFile.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
logDir := "logs"
|
||||
|
||||
logFile, err := InitLogFile(logDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Error initializing log file: %v\n", err)
|
||||
}
|
||||
defer logFile.Close()
|
||||
|
||||
// 设置日志同时输出到控制台和文件
|
||||
multiWriter := io.MultiWriter(logFile, os.Stdout)
|
||||
log.SetOutput(multiWriter)
|
||||
|
||||
config, err := LoadConfig("config.json")
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading config: %v", err)
|
||||
}
|
||||
|
||||
// 启动监控
|
||||
for _, processConfig := range config.Processes {
|
||||
pm := NewProcessMonitor(processConfig, logDir)
|
||||
go pm.Monitor()
|
||||
}
|
||||
|
||||
select {} // 阻止主进程退出
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user