goProject/trunk/framework/monitorNewMgr/monitor.go
皮蛋13361098506 1b77f62820 初始化项目
2025-01-06 16:01:02 +08:00

317 lines
8.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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