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 } }