初始化项目
This commit is contained in:
41
trunk/framework/monitorNewMgr/model.go
Normal file
41
trunk/framework/monitorNewMgr/model.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package monitorNewMgr
|
||||
|
||||
// 监控信息传输对象
|
||||
type MonitorModel struct {
|
||||
//状态码 0 是心跳,非零为错误信息
|
||||
Code int `json:"Code"`
|
||||
|
||||
//组Id
|
||||
GroupId string `json:"GroupId"`
|
||||
|
||||
//组密钥
|
||||
ProjectId string `json:"ProjectId"`
|
||||
|
||||
//项目Id
|
||||
ServerIp string `json:"ServerIp"`
|
||||
|
||||
// 监控使用的服务器IP
|
||||
ServerName string `json:"ServerName"`
|
||||
|
||||
// 监控使用的服务器名称
|
||||
Content string `json:"Content"`
|
||||
|
||||
// 消息产生时的时间戳
|
||||
Timestamp int64 `json:"Timestamp"`
|
||||
|
||||
// 签名
|
||||
Sign string `json:"Sign"`
|
||||
}
|
||||
|
||||
func newMonitorModel(code int, groupId, projectId, serverIp, serverName, content string, timestamp int64, sign string) *MonitorModel {
|
||||
return &MonitorModel{
|
||||
Code: code,
|
||||
GroupId: groupId,
|
||||
ProjectId: projectId,
|
||||
ServerIp: serverIp,
|
||||
ServerName: serverName,
|
||||
Content: content,
|
||||
Timestamp: timestamp,
|
||||
Sign: sign,
|
||||
}
|
||||
}
|
||||
316
trunk/framework/monitorNewMgr/monitor.go
Normal file
316
trunk/framework/monitorNewMgr/monitor.go
Normal file
@@ -0,0 +1,316 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
18
trunk/framework/monitorNewMgr/monitorHistory.go
Normal file
18
trunk/framework/monitorNewMgr/monitorHistory.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package monitorNewMgr
|
||||
|
||||
//历史监控信息
|
||||
type MonitorHistory struct {
|
||||
//监控信息
|
||||
MonitorMessage string
|
||||
|
||||
//时间戳
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
//new一个监控历史信息
|
||||
func newMonitorHistory(monitorMessage string, timestamp int64) *MonitorHistory {
|
||||
return &MonitorHistory{
|
||||
MonitorMessage: monitorMessage,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
}
|
||||
63
trunk/framework/monitorNewMgr/monitor_history.go
Normal file
63
trunk/framework/monitorNewMgr/monitor_history.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package monitorNewMgr
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"goutil/stringUtil"
|
||||
)
|
||||
|
||||
const (
|
||||
// CON_MONITOR_HISTORY_SIZE 历史监控信息保存数量
|
||||
CON_MONITOR_HISTORY_SIZE = 3
|
||||
|
||||
// CON_MONITOR_HISTORY_VALID_SECONDS 历史监控信息有效的秒数
|
||||
CON_MONITOR_HISTORY_VALID_SECONDS = 30
|
||||
|
||||
// CON_MONITOR_HISTORY_SIMILARITY_THERSHOLD 历史监控信息相似度的阈值
|
||||
CON_MONITOR_HISTORY_SIMILARITY_THERSHOLD = 0.9
|
||||
)
|
||||
|
||||
var (
|
||||
monitorHistoryList = make([]*MonitorHistory, 0, CON_MONITOR_HISTORY_SIZE)
|
||||
monitorHistoryMutex sync.Mutex
|
||||
)
|
||||
|
||||
func checkSimilarity(monitorMessage string, timestamp int64) (valid bool) {
|
||||
//默认监控信息有效
|
||||
valid = true
|
||||
|
||||
monitorHistoryMutex.Lock()
|
||||
defer monitorHistoryMutex.Unlock()
|
||||
|
||||
// 从后往前(按时间从后往前)遍历,以便于可以及时退出
|
||||
for i := len(monitorHistoryList) - 1; i >= 0; i-- {
|
||||
item := monitorHistoryList[i]
|
||||
|
||||
// 如果已经过期,则不用处理; 返回之前的状态即可(当前的已经过期,则之前的也一定已经过期)
|
||||
if time.Now().Unix()-item.Timestamp > CON_MONITOR_HISTORY_VALID_SECONDS {
|
||||
break
|
||||
}
|
||||
|
||||
// 如果两个字符串的长度相差2倍,则无须继续判断,继续与下一条数据进行比较
|
||||
lenA, lenB := len(monitorMessage), len(item.MonitorMessage)
|
||||
if lenA > 2*lenB || lenB > 2*lenA {
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断两个字符串的相似度(如果相似度超过阈值,则此日志无效)
|
||||
_, similarity := stringUtil.Similarity(monitorMessage, item.MonitorMessage)
|
||||
if similarity >= CON_MONITOR_HISTORY_SIMILARITY_THERSHOLD {
|
||||
valid = false
|
||||
return // 直接返回,无需将当前日志添加到历史列表中,以提高性能
|
||||
}
|
||||
}
|
||||
|
||||
// 将消息添加到历史消息列表中
|
||||
monitorHistoryList = append(monitorHistoryList, newMonitorHistory(monitorMessage, timestamp))
|
||||
if len(monitorHistoryList) > CON_MONITOR_HISTORY_SIZE {
|
||||
monitorHistoryList = monitorHistoryList[len(monitorHistoryList)-CON_MONITOR_HISTORY_SIZE:]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
20
trunk/framework/monitorNewMgr/monitor_test.go
Normal file
20
trunk/framework/monitorNewMgr/monitor_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package monitorNewMgr
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReport(t *testing.T) {
|
||||
//var groupIdWrong = "wrong"
|
||||
var groupId = "lj"
|
||||
//var groupSecretWrong = "wrong"
|
||||
var groupSecret = "8DD58C6C-E9C2-4DA3-8CBC-D5D5C6629CB8"
|
||||
//var projectIdWrong = "wrong"
|
||||
var projectId = "lj3"
|
||||
var serverName = "testservername"
|
||||
var serverIp = "127.0.0.1"
|
||||
//设置完全正确的参数
|
||||
SetURL("http://monitorservice.7qule.com/monitor")
|
||||
SetParam(groupId, groupSecret, projectId, serverIp, serverName)
|
||||
Report("test", "test success")
|
||||
}
|
||||
76
trunk/framework/monitorNewMgr/serviceMonitorModel.go
Normal file
76
trunk/framework/monitorNewMgr/serviceMonitorModel.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package monitorNewMgr
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//服务器节点信息
|
||||
type ServerNodeMessage struct {
|
||||
//通用信息
|
||||
CommInfo CommInfoModel
|
||||
|
||||
// indexMap 指标对象
|
||||
IndexSlice []Index
|
||||
}
|
||||
|
||||
type Index struct {
|
||||
// IndexName 指标名字(eg:可以为cpu,mem,numGoroutine,proxy)
|
||||
IndexName string
|
||||
|
||||
// moduleName 模块名字
|
||||
ModuleName string
|
||||
|
||||
// methodName 方法名字
|
||||
MethodName string
|
||||
|
||||
// value 指标值(eg:indexName为cpu时,value 为cpu使用率,indexName为内存时,value为内存使用率)
|
||||
Value float64
|
||||
}
|
||||
|
||||
//服务监控中心信息
|
||||
type MonitorCenterMessage struct {
|
||||
//通用信息
|
||||
CommInfo CommInfoModel
|
||||
|
||||
// Cpu 核数
|
||||
Cpu int32
|
||||
|
||||
// Mem 内存大小
|
||||
Mem int32
|
||||
|
||||
// Status
|
||||
Status int32
|
||||
}
|
||||
|
||||
// 通用信息
|
||||
type CommInfoModel struct {
|
||||
// 项目组ID
|
||||
GroupId string
|
||||
|
||||
// projectId 项目Id (eg:迪士尼)
|
||||
ProjectId string
|
||||
|
||||
// clusterId 集群Id(一个集群相当于一个大区)
|
||||
ClusterId string
|
||||
|
||||
// 组密钥
|
||||
ProjectSecret string
|
||||
|
||||
// 服务器IP
|
||||
IP string
|
||||
|
||||
// Port 服务端口
|
||||
Port int32
|
||||
|
||||
// 服务名(eg:玩家服务player,城市服务:city,代理服务:proxy)
|
||||
ServiceName string
|
||||
|
||||
// instanceId 服务实例Id
|
||||
InstanceId string
|
||||
|
||||
// tll 时间戳
|
||||
Tll time.Duration
|
||||
|
||||
// 签名
|
||||
Sign string
|
||||
}
|
||||
Reference in New Issue
Block a user