317 lines
8.0 KiB
Go
317 lines
8.0 KiB
Go
|
|
package monitorNewMgr
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"encoding/json"
|
|||
|
|
"fmt"
|
|||
|
|
"sync"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"goutil/logUtil"
|
|||
|
|
"goutil/securityUtil"
|
|||
|
|
"goutil/webUtil"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
var (
|
|||
|
|
// 报告监控信息的URL
|
|||
|
|
remoteURL = "http://monitorservice.7qule.com/monitor"
|
|||
|
|
|
|||
|
|
//组Id
|
|||
|
|
groupId string
|
|||
|
|
|
|||
|
|
//项目Id
|
|||
|
|
projectId string
|
|||
|
|
|
|||
|
|
//组密钥
|
|||
|
|
groupSecret string
|
|||
|
|
|
|||
|
|
// 服务器IP
|
|||
|
|
serverIP string
|
|||
|
|
|
|||
|
|
// 服务器名称
|
|||
|
|
serverName string
|
|||
|
|
|
|||
|
|
// 监控时间间隔(单位:秒钟)
|
|||
|
|
monitorInterval = 10
|
|||
|
|
|
|||
|
|
// 监控方法列表
|
|||
|
|
monitorFuncList = make([]func() error, 0, 4)
|
|||
|
|
|
|||
|
|
// 监控方法锁对象
|
|||
|
|
monitorFuncMutex sync.Mutex
|
|||
|
|
|
|||
|
|
//未设置参数的提醒
|
|||
|
|
isWarning bool = false
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func init() {
|
|||
|
|
// 实际的监控方法调用
|
|||
|
|
monitorFunc := func() {
|
|||
|
|
monitorFuncMutex.Lock()
|
|||
|
|
defer monitorFuncMutex.Unlock()
|
|||
|
|
|
|||
|
|
for _, item := range monitorFuncList {
|
|||
|
|
if err := item(); err != nil {
|
|||
|
|
errContent := fmt.Sprintf("监控方法实际调用错误:%s", err.Error())
|
|||
|
|
report(-99, errContent)
|
|||
|
|
} else {
|
|||
|
|
report(0, "")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
go func() {
|
|||
|
|
// monitorNewMgr不能引用goroutineMgr,以避免循环引用
|
|||
|
|
/*
|
|||
|
|
goroutineName := fmt.Sprintf("%s.check", "monitorNewMgr")
|
|||
|
|
goroutineMgr.Monitor(goroutineName)
|
|||
|
|
defer goroutineMgr.ReleaseMonitor(goroutineName)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
defer func() {
|
|||
|
|
if r := recover(); r != nil {
|
|||
|
|
logUtil.LogUnknownError(r)
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
// 先休眠,避免系统启动时就进行报警
|
|||
|
|
time.Sleep(time.Second * time.Duration(monitorInterval))
|
|||
|
|
|
|||
|
|
// 实际的监控方法调用
|
|||
|
|
monitorFunc()
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//监控信息提交返回
|
|||
|
|
type ReportResponse struct {
|
|||
|
|
//响应结果状态
|
|||
|
|
ResultStatus string
|
|||
|
|
|
|||
|
|
// 响应结果数据
|
|||
|
|
Data string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SetURL ...设置监控信息发送的URL
|
|||
|
|
// url:监控信息发送的URL
|
|||
|
|
func SetURL(url string) {
|
|||
|
|
remoteURL = url
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SetParam ...设置参数
|
|||
|
|
//_groupId:组Id
|
|||
|
|
//_groupSecret:组密钥
|
|||
|
|
//_projectId:项目Id
|
|||
|
|
// _serverIP:服务器IP
|
|||
|
|
// _serverName:服务器名称
|
|||
|
|
func SetParam(_groupId, _groupSecret, _projectId, _serverIP, _serverName string) {
|
|||
|
|
groupId = _groupId
|
|||
|
|
groupSecret = _groupSecret
|
|||
|
|
projectId = _projectId
|
|||
|
|
serverIP = _serverIP
|
|||
|
|
serverName = _serverName
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// RegisterMonitorFunc ...注册监控方法
|
|||
|
|
// f:监控方法
|
|||
|
|
func RegisterMonitorFunc(f func() error) {
|
|||
|
|
monitorFuncMutex.Lock()
|
|||
|
|
defer monitorFuncMutex.Unlock()
|
|||
|
|
|
|||
|
|
monitorFuncList = append(monitorFuncList, f)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Report ...报告异常信息
|
|||
|
|
// title:上报的标题
|
|||
|
|
// contentFmt:报告内容
|
|||
|
|
// args:参数列表
|
|||
|
|
func Report(title, contentFmt string, args ...interface{}) {
|
|||
|
|
content := fmt.Sprintf("Title:%s Content:%s", title, contentFmt)
|
|||
|
|
if len(args) > 0 {
|
|||
|
|
content = fmt.Sprintf(content, args...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
timestamp := time.Now().Unix()
|
|||
|
|
|
|||
|
|
// 判断指定时间内是否已经处理过
|
|||
|
|
valid := checkSimilarity(content, timestamp)
|
|||
|
|
if !valid {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//上传错误
|
|||
|
|
report(-99, content)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Report2 ...报告异常信息
|
|||
|
|
// title:上报的标题
|
|||
|
|
// contentFmt:报告内容
|
|||
|
|
//code :9999为特殊状态,不加入心跳检测
|
|||
|
|
//isCheckSimilarity:是否去重
|
|||
|
|
// args:参数列表
|
|||
|
|
func Report2(title, contentFmt string, code int, isCheckSimilarity bool, args ...interface{}) {
|
|||
|
|
content := fmt.Sprintf("Title:%s Content:%s", title, contentFmt)
|
|||
|
|
if len(args) > 0 {
|
|||
|
|
content = fmt.Sprintf(content, args...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if isCheckSimilarity {
|
|||
|
|
timestamp := time.Now().Unix()
|
|||
|
|
|
|||
|
|
// 判断指定时间内是否已经处理过
|
|||
|
|
valid := checkSimilarity(content, timestamp)
|
|||
|
|
if !valid {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//上传错误
|
|||
|
|
report(code, content)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//report 统一上传信息
|
|||
|
|
//code 0为心跳,非零为错误信息
|
|||
|
|
//content 上报内容
|
|||
|
|
func report(code int, content string) {
|
|||
|
|
if groupId == "" || projectId == "" || groupSecret == "" {
|
|||
|
|
if !isWarning {
|
|||
|
|
logUtil.WarnLog("monitorNewMgr没有初始化参数,请调用SetParam进行初始化")
|
|||
|
|
isWarning = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
timestamp := time.Now().Unix()
|
|||
|
|
rawString := fmt.Sprintf("Code=%d&GroupId=%s&ProjectId=%s&ServerIP=%s&ServerName=%s&Content=%s&Timestamp=%d&GroupSecret=%s", code, groupId, projectId, serverIP, serverName, content, timestamp, groupSecret)
|
|||
|
|
sign := securityUtil.Md5String(rawString, true)
|
|||
|
|
|
|||
|
|
//构造参数对象
|
|||
|
|
monitorModel := newMonitorModel(code, groupId, projectId, serverIP, serverName, content, timestamp, sign)
|
|||
|
|
|
|||
|
|
//定义错误信息
|
|||
|
|
var logMessage string
|
|||
|
|
|
|||
|
|
//定义参数
|
|||
|
|
jsonMonitorModel, err := json.Marshal(monitorModel)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("json.Marshal(monitorModel),err:%s", err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
postDataDict := make(map[string]string)
|
|||
|
|
postDataDict["MonitorModel"] = string(jsonMonitorModel)
|
|||
|
|
|
|||
|
|
//请求url,请求头
|
|||
|
|
header := webUtil.GetFormHeader()
|
|||
|
|
transport := webUtil.NewTransport()
|
|||
|
|
transport.DisableKeepAlives = true
|
|||
|
|
transport = webUtil.GetTimeoutTransport(transport, 30)
|
|||
|
|
|
|||
|
|
statusCode, result, err := webUtil.PostMapData(remoteURL, postDataDict, header, transport)
|
|||
|
|
//statusCode, result, err := webUtil.PostMapData(remoteURL, postDataDict, webUtil.ContentType_Form, nil)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("MonitorModel:,错误信息为:%s", err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if statusCode != 200 {
|
|||
|
|
logMessage = fmt.Sprintf("MonitorReport:%d is wrong", statusCode)
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var reportResponseObj *ReportResponse
|
|||
|
|
err = json.Unmarshal(result, &reportResponseObj)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("json.Unmarshal(reportResponseObj), result:%s err:%s", result, err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if reportResponseObj.ResultStatus != "" {
|
|||
|
|
logMessage = fmt.Sprintf("上传信息返回错误,ResultStatus %s", reportResponseObj.ResultStatus)
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//上报数据
|
|||
|
|
func ReportServiceStatus(data interface{}) {
|
|||
|
|
var commInfo CommInfoModel
|
|||
|
|
var isServerMsg bool
|
|||
|
|
var isCenterMsg bool
|
|||
|
|
//定义错误信息
|
|||
|
|
var logMessage string
|
|||
|
|
|
|||
|
|
message, ok := (data).(ServerNodeMessage)
|
|||
|
|
if ok {
|
|||
|
|
isServerMsg = true
|
|||
|
|
commInfo = message.CommInfo
|
|||
|
|
//处理数据
|
|||
|
|
return
|
|||
|
|
} else {
|
|||
|
|
message, ok := (data).(MonitorCenterMessage)
|
|||
|
|
if ok {
|
|||
|
|
isCenterMsg = true
|
|||
|
|
commInfo = message.CommInfo
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//如果类型都不符合,则说明数据格式有问题
|
|||
|
|
if !isServerMsg && !isCenterMsg {
|
|||
|
|
logMessage = fmt.Sprintf("上传信息格式错误,ResultStatus %s", data)
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//构造签名字符串
|
|||
|
|
rawString := fmt.Sprintf("&GroupId=%s&ProjectId=%s&IP=%s&ServiceName=%s&InstanceId=%s&ClusterId=%s&Timestamp=%d&GroupSecret=%s",
|
|||
|
|
commInfo.GroupId, commInfo.ProjectId, commInfo.IP, commInfo.ServiceName, commInfo.InstanceId, commInfo.ClusterId, commInfo.Tll, groupSecret)
|
|||
|
|
// 签名赋值
|
|||
|
|
commInfo.Sign = rawString
|
|||
|
|
|
|||
|
|
//定义参数
|
|||
|
|
jsonMonitorModel, err := json.Marshal(data)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("json.Marshal(data),err:%s", err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
postDataDict := make(map[string]string)
|
|||
|
|
postDataDict["MonitorModel"] = string(jsonMonitorModel)
|
|||
|
|
|
|||
|
|
//请求url,请求头
|
|||
|
|
header := webUtil.GetFormHeader()
|
|||
|
|
transport := webUtil.NewTransport()
|
|||
|
|
transport.DisableKeepAlives = true
|
|||
|
|
transport = webUtil.GetTimeoutTransport(transport, 30)
|
|||
|
|
|
|||
|
|
statusCode, result, err := webUtil.PostMapData("http://monitorservice.7qule.com/serviceMonitor", postDataDict, header, transport)
|
|||
|
|
//statusCode, result, err := webUtil.PostMapData(remoteURL, postDataDict, webUtil.ContentType_Form, nil)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("ReportServiceStatus上报数据错误:,错误信息为:%s", err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if statusCode != 200 {
|
|||
|
|
logMessage = fmt.Sprintf("ReportServiceStatus上报数据错误:%d is wrong", statusCode)
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var reportResponseObj *ReportResponse
|
|||
|
|
err = json.Unmarshal(result, &reportResponseObj)
|
|||
|
|
if err != nil {
|
|||
|
|
logMessage = fmt.Sprintf("ReportServiceStatus.json.Unmarshal(reportResponseObj), result:%s err:%s", result, err.Error())
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if reportResponseObj.ResultStatus != "" {
|
|||
|
|
logMessage = fmt.Sprintf("ReportServiceStatus上传信息返回错误,ResultStatus %s", reportResponseObj.ResultStatus)
|
|||
|
|
logUtil.ErrorLog(logMessage)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|