2020-08-04 14:28:25 +08:00
|
|
|
package task
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"database/sql"
|
|
|
|
"encoding/json"
|
|
|
|
"github.com/patrickmn/go-cache"
|
|
|
|
"github.com/zhenorzz/goploy/core"
|
|
|
|
"github.com/zhenorzz/goploy/model"
|
2020-09-11 15:09:38 +08:00
|
|
|
"github.com/zhenorzz/goploy/ws"
|
2020-08-04 14:28:25 +08:00
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func monitorTask() {
|
|
|
|
monitors, err := model.Monitor{State: model.Enable}.GetAllByState()
|
|
|
|
if err != nil && err != sql.ErrNoRows {
|
|
|
|
core.Log(core.ERROR, "get monitor list error, detail:"+err.Error())
|
|
|
|
}
|
|
|
|
for _, monitor := range monitors {
|
2020-09-11 15:09:38 +08:00
|
|
|
monitorCache := map[string]int64{"errorTimes": 0, "notifyTimes": 0, "time": 0}
|
2020-08-04 14:28:25 +08:00
|
|
|
if x, found := core.Cache.Get("monitor:" + strconv.Itoa(int(monitor.ID))); found {
|
|
|
|
monitorCache = x.(map[string]int64)
|
|
|
|
}
|
|
|
|
now := time.Now().Unix()
|
|
|
|
|
|
|
|
if int(now-monitorCache["time"]) > monitor.Second {
|
|
|
|
monitorCache["time"] = now
|
|
|
|
conn, err := net.DialTimeout("tcp", monitor.Domain+":"+strconv.Itoa(monitor.Port), 5*time.Second)
|
|
|
|
if err != nil {
|
|
|
|
monitorCache["errorTimes"]++
|
|
|
|
core.Log(core.ERROR, "monitor "+monitor.Name+" encounter error, "+err.Error())
|
|
|
|
if monitor.Times == uint16(monitorCache["errorTimes"]) {
|
|
|
|
monitorCache["errorTimes"] = 0
|
2020-09-11 15:09:38 +08:00
|
|
|
monitorCache["notifyTimes"]++
|
2020-08-04 14:28:25 +08:00
|
|
|
notice(monitor, err)
|
2020-09-11 15:09:38 +08:00
|
|
|
if monitor.NotifyTimes == uint16(monitorCache["notifyTimes"]) {
|
|
|
|
monitorCache["notifyTimes"] = 0
|
|
|
|
monitor.TurnOff(err.Error())
|
|
|
|
ws.GetHub().Data <- &ws.Data{
|
|
|
|
Type: ws.TypeMonitor,
|
|
|
|
Message: ws.MonitorMessage{MonitorID: monitor.ID, State: ws.MonitorTurnOff, ErrorContent: err.Error()},
|
|
|
|
}
|
|
|
|
}
|
2020-08-04 14:28:25 +08:00
|
|
|
}
|
|
|
|
} else {
|
2020-09-11 15:09:38 +08:00
|
|
|
monitorCache["errorTimes"] = 0
|
2020-08-04 14:28:25 +08:00
|
|
|
conn.Close()
|
|
|
|
}
|
|
|
|
core.Cache.Set("monitor:"+strconv.Itoa(int(monitor.ID)), monitorCache, cache.DefaultExpiration)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func notice(monitor model.Monitor, err error) {
|
|
|
|
if monitor.NotifyType == model.NotifyWeiXin {
|
|
|
|
type markdown struct {
|
|
|
|
Content string `json:"content"`
|
|
|
|
}
|
|
|
|
type message struct {
|
|
|
|
Msgtype string `json:"msgtype"`
|
|
|
|
Markdown markdown `json:"markdown"`
|
|
|
|
}
|
2020-08-15 13:38:06 +08:00
|
|
|
content := "Monitor: <font color=\"warning\">" + monitor.Name + "</font>\n "
|
|
|
|
content += "> <font color=\"warning\">can not access</font> \n "
|
2020-08-04 14:28:25 +08:00
|
|
|
content += "> <font color=\"comment\">" + err.Error() + "</font> \n "
|
|
|
|
|
|
|
|
msg := message{
|
|
|
|
Msgtype: "markdown",
|
|
|
|
Markdown: markdown{
|
|
|
|
Content: content,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
b, _ := json.Marshal(msg)
|
|
|
|
http.Post(monitor.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
|
|
|
} else if monitor.NotifyType == model.NotifyDingTalk {
|
2020-09-09 21:31:21 +08:00
|
|
|
type markdown struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
Text string `json:"text"`
|
|
|
|
}
|
2020-08-04 14:28:25 +08:00
|
|
|
type message struct {
|
2020-09-09 21:31:21 +08:00
|
|
|
Msgtype string `json:"msgtype"`
|
|
|
|
Markdown markdown `json:"markdown"`
|
2020-08-04 14:28:25 +08:00
|
|
|
}
|
2020-09-11 15:09:38 +08:00
|
|
|
text := "#### Monitor: " + monitor.Name + " can not access \n >" + err.Error()
|
2020-08-04 14:28:25 +08:00
|
|
|
|
|
|
|
msg := message{
|
|
|
|
Msgtype: "markdown",
|
2020-09-09 21:31:21 +08:00
|
|
|
Markdown: markdown{
|
|
|
|
Title: monitor.Name,
|
|
|
|
Text: text,
|
|
|
|
},
|
2020-08-04 14:28:25 +08:00
|
|
|
}
|
|
|
|
b, _ := json.Marshal(msg)
|
2020-09-11 15:09:38 +08:00
|
|
|
http.Post(monitor.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
2020-08-04 14:28:25 +08:00
|
|
|
} else if monitor.NotifyType == model.NotifyFeiShu {
|
|
|
|
type message struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
Text string `json:"text"`
|
|
|
|
}
|
|
|
|
|
2020-08-15 13:38:06 +08:00
|
|
|
text := "can not access\n "
|
|
|
|
text += "detail: " + err.Error()
|
2020-08-04 14:28:25 +08:00
|
|
|
|
|
|
|
msg := message{
|
2020-08-15 13:38:06 +08:00
|
|
|
Title: "Monitor:" + monitor.Name,
|
2020-08-04 14:28:25 +08:00
|
|
|
Text: text,
|
|
|
|
}
|
|
|
|
b, _ := json.Marshal(msg)
|
|
|
|
http.Post(monitor.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
|
|
|
} else if monitor.NotifyType == model.NotifyCustom {
|
|
|
|
type message struct {
|
|
|
|
Code int `json:"code"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Data struct {
|
|
|
|
MonitorName string `json:"monitorName"`
|
|
|
|
Domain string `json:"domain"`
|
|
|
|
Port int `json:"port"`
|
|
|
|
Second int `json:"second"`
|
|
|
|
Times uint16 `json:"times"`
|
|
|
|
} `json:"data"`
|
|
|
|
}
|
|
|
|
code := 0
|
|
|
|
msg := message{
|
|
|
|
Code: code,
|
2020-08-15 13:38:06 +08:00
|
|
|
Message: "Monitor:" + monitor.Name + "can not access",
|
2020-08-04 14:28:25 +08:00
|
|
|
}
|
|
|
|
msg.Data.MonitorName = monitor.Name
|
|
|
|
msg.Data.Domain = monitor.Domain
|
|
|
|
msg.Data.Port = monitor.Port
|
|
|
|
msg.Data.Second = monitor.Second
|
|
|
|
msg.Data.Times = monitor.Times
|
|
|
|
b, _ := json.Marshal(msg)
|
|
|
|
http.Post(monitor.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
|
|
|
}
|
|
|
|
}
|