Commit 2e020fdb authored by jingbo.wang's avatar jingbo.wang

删除废弃代码:(注:node-check模块后续会移植回来,其他模块废弃)

parent 9082abfb
package service
import (
"fmt"
"git.quantgroup.cn/DevOps/enoch/service/consumer"
"git.quantgroup.cn/DevOps/enoch/service/util"
"net/http"
"strconv"
"strings"
)
func DurationInterface(w http.ResponseWriter, r *http.Request) {
day := r.Header.Get("day")
DurationCalcAndSendEmail(day)
fmt.Fprint(w)
}
func DurationCalcAndSendEmail(day string) {
info := ""
consumer.Duration(day, func(sysName string, durations map[string]string) {
info = info + "\n" + "系统名称 : " + strings.Split(sysName, ":")[1] + "\n"
for k, v := range durations {
i, err := strconv.Atoi(v)
if err != nil {
fmt.Print("转换类型出错了. ", err)
}
i = i / 1000
info = info + k + " , 耗时:" + strconv.Itoa(i) + "ms" + "\n"
}
})
util.SendEmail("接口耗时情况"+day, info, "xiaoguang.xu@quantgroup.cn")
}
func CounterInterface(w http.ResponseWriter, r *http.Request) {
day := r.Header.Get("day")
CounterCalcAndSendEmail(day)
fmt.Fprint(w)
}
func CounterCalcAndSendEmail(day string) {
info := ""
consumer.Counter(day, func(sysName string, durations map[string]string) {
info = info + "\n" + "系统名称 : " + strings.Split(sysName, ":")[1] + "\n"
for k, v := range durations {
info = info + k + " , 次数:" + v + "\n"
}
})
util.SendEmail("接口调用量"+day, info, "xiaoguang.xu@quantgroup.cn")
}
package alarm
import (
"encoding/json"
"git.quantgroup.cn/DevOps/enoch/service/conf"
"git.quantgroup.cn/DevOps/enoch/service/data"
"git.quantgroup.cn/DevOps/enoch/service/log"
"io/ioutil"
)
func Load() {
config,err := ioutil.ReadFile(conf.GlobalConfig.StrategyConfPath)
if err != nil {
logger.Error.Print("!!!轮训监控,未找到配置文件!!!")
return
}
strategies := make([]Strategy, 0)
err = json.Unmarshal(config, &strategies)
if err != nil {
logger.Error.Printf("!!!策略文件格式错误:%s!!!\n", err)
return
}
if !CheckArray(strategies) {
logger.Error.Print("!!!策略文件未通过校验!!!")
return
}
sql := BuildSql(strategies)
result := data.QueryMonitor(sql)
DealResult(result, strategies)
}
package alarm
import (
"encoding/json"
"git.quantgroup.cn/DevOps/enoch/service/log"
"git.quantgroup.cn/DevOps/enoch/service/util"
"net/http"
"strings"
"sync"
"time"
)
var SenderWatcher sync.Map
func Sender(target []string, title string, info string, notice Notice) {
uniqueKey := buildUniqueKey(target)
if !isExpired(uniqueKey, notice.Interval) { //小于报警周期
return
}
info = uniqueKey + info
switch notice.Sender {
case DING_DING:
senderDingDing(title, info, notice.Receiver)
break
case MAIL:
senderMail(title, info, notice.Receiver)
default:
logger.Error.Println("策略配置错误,未匹配到对应的Sender")
}
}
func senderMail(title string, info string, receiver []string) {
for _, r := range receiver {
util.SendEmail(title, info, r)
}
}
func senderDingDing(title string, info string, receiver [] string) {
bodyStr := buildDingDingMsg(title, info)
for _, r := range receiver {
data := strings.NewReader(string(bodyStr))
_, err := http.Post(r, "application/json;charset=utf-8", data)
if err != nil {
logger.Error.Println(err)
}
}
}
func buildDingDingMsg(title string, info string) []byte {
msg := DinDingMsg{
MsgType: "link",
Link: Link{
Title: title,
Text: info,
MessageUrl: "http://172.20.6.33:3000/d/y1Ju2slik/apdexlist?refresh=1m&orgId=1",
},
}
msgStr, err := json.Marshal(msg)
if nil != err {
logger.Error.Println("无法序列化ding ding msg", err)
}
return msgStr
}
/**
判断是否符合报警的时间间隔
*/
func isExpired(key string, interval int64) bool {
now := time.Now().Unix()
lastTime, hasValue := SenderWatcher.LoadOrStore(key, now)
logger.Info.Println("---------时间间隔:old:", lastTime, ",new:", now)
if hasValue { // 存在旧值,判断是否过期
if now-lastTime.(int64) >= interval { //过期
SenderWatcher.Store(key, now)
return true
}
return false
}
return true
}
func buildUniqueKey(target []string) string {
length := len(target)
str := strings.Builder{}
for i := length - 1; i >= 0; i-- {
str.WriteString(target[i])
str.WriteString(":")
}
return str.String()
}
/**
持久化报警
*/
func persistence() {
}
package alarm
import (
"fmt"
"git.quantgroup.cn/DevOps/enoch/service/log"
"log"
"strconv"
"strings"
)
type Compare struct {
}
/**
real < alter
*/
func (Compare) Less(alter string, real []string) bool {
rs := true
lastIndex := len(real) - 1
for i, r := range real {
if i != 0 || i != lastIndex {
if r == "0" {
continue
}
rs = rs && (r < alter)
}
}
return rs
}
func (Compare) Greater(alter string, real []string) bool {
rs := true
lastIndex := len(real) - 1
for i, r := range real {
if i != 0 || i != lastIndex {
rs = rs && (r > alter)
}
}
return rs
}
/**
real = alter
*/
func (Compare) Equal(alter string, real []string) bool {
rs := true
lastIndex := len(real) - 1
for i, r := range real {
if i != 0 || i != lastIndex {
rs = rs && (r == alter)
}
}
return rs
}
//限制同比
func (Compare) LimitComparedWithSame(alter string, old []string, current []string) bool {
log.Println(alter, old, current)
logger.Info.Println("old:", strings.Join(old, ","), "new: ", strings.Join(current, ","))
rs := true
lastIndex := len(current) - 1
for i, r := range current {
if i != 0 || i != lastIndex {
rs = rs && limitCompareSame(alter, old[i], r)
}
}
return rs
}
/**
同比超过alter
*/
func (Compare) ComparedWithSame(alter string, old []string, current []string) bool {
logger.Info.Println("old:", strings.Join(old, ","), "new: ", strings.Join(current, ","))
rs := true
lastIndex := len(current) - 1
for i, r := range current {
if i != 0 || i != lastIndex {
rs = rs && compareSame(alter, old[i], r)
}
}
return rs
}
func limitCompareSame(alter string, old string, current string) bool {
cf := parseToFloat(current)
of := parseToFloat(old)
if cf < 200 && of < 200 {
return false
}
return (cf-of)/of > parseToFloat(alter)
}
func compareSame(alter string, old string, current string) bool {
cf := parseToFloat(current)
of := parseToFloat(old)
if of == 0 { //jingbo.wang, 忽略of为0的场景
return false
}
return (cf-of)/of > parseToFloat(alter)
}
func parseToFloat(value string) float64 {
rs, err := strconv.ParseFloat(value, 64)
if nil != err {
logger.Error.Println(err)
}
return rs
}
type MsgBuilder struct {
}
func (MsgBuilder) Less(alter string) string {
return fmt.Sprintf(" 低于阈值:%s", alter)
}
/**
real > alter
*/
func (MsgBuilder) Greater(alter string) string {
return fmt.Sprintf(" 高于阈值:%s", alter)
}
/**
real = alter
*/
func (MsgBuilder) Equal(alter string) string {
return fmt.Sprintf(" 等于阈值:%.3s", alter)
}
/**
同比超过alter
*/
func (MsgBuilder) ComparedWithSame(alter string) string {
return "同比超过" + alter
}
//限制同比
func (MsgBuilder) LimitComparedWithSame(alter string) string {
return "同比超过" + alter
}
\ No newline at end of file
package alarm
import (
"fmt"
"git.quantgroup.cn/DevOps/enoch/service/log"
"github.com/influxdata/influxdb/client/v2"
"reflect"
"strings"
)
var operators = reflect.ValueOf(Compare{})
var msgBuilder = reflect.ValueOf(MsgBuilder{})
func DealResult(res []client.Result, strategies []Strategy) {
var resIndex = 0
for _, strategy := range strategies {
logger.Info.Println("-------", strategy.Name, resIndex, "---------")
operator := strategy.Operator
operatorMethod := operators.MethodByName(operator)
buildMsgMethod := msgBuilder.MethodByName(operator)
alterValue := strategy.AlterValue
alterValueLen := len(alterValue)
ignoreTag := strategy.IgnoreTag
tags := strategy.Tag
notice := strategy.Notice
noDataAlter := strategy.NoDataAlter
personalAlterValue := strategy.PersonalAlterValue
if strategy.SqlLen == 1 { //单sql
result := res[resIndex]
for _, series := range result.Series {
uniqueTag := series.Tags[tags[0]]
tagValues := getTagValues(tags, series.Tags)
if needIgnore(ignoreTag, tagValues) {
continue
}
value := make([]string,0)
for _, v := range series.Values {
value = append(value, fmt.Sprint(v[1]))
}
//value := series.Values[0][1]
if nil == value && noDataAlter { //空值报警
Sender(tagValues, strategy.Name, "no data", notice)
}
currentAlterValue := getAlterValue(personalAlterValue, uniqueTag, tagValues, alterValue)
params := make([]reflect.Value, alterValueLen+1)
for j, arg := range currentAlterValue {
params[j] = reflect.ValueOf(arg)
}
params[alterValueLen] = reflect.ValueOf(value)
logger.Info.Println(uniqueTag, ":alter", params[:1], "-", strings.Join(value, ","))
rs := operatorMethod.Call(params)
if rs[0].Bool() { //触发报警策略
//Sender(tagValues, strategy.Name, s, notice) // 报警
Sender(tagValues, strategy.Name, buildMsgMethod.Call(params[:1])[0].String(), notice) // 报警
}
}
} else {
params := make(map[string][]reflect.Value)
tagValueMap := make(map[string][]string)
for i := 0; i < strategy.SqlLen; i++ {
resIndex += i
for _, series := range res[resIndex].Series {
uniqueTag := series.Tags[tags[0]]
tagValues := getTagValues(tags, series.Tags)
if needIgnore(ignoreTag, tagValues) {
continue
}
tagValueMap[uniqueTag] = tagValues
value := make([]string,0)
for _, v := range series.Values {
value = append(value, fmt.Sprint(v[1]))
}
if nil == params[uniqueTag] {
currentParams := make([]reflect.Value, strategy.SqlLen+alterValueLen)
currentAlterValue := getAlterValue(personalAlterValue, uniqueTag, tagValues, alterValue)
for k, arg := range currentAlterValue {
currentParams[k] = reflect.ValueOf(arg)
}
params[uniqueTag] = currentParams
}
params[uniqueTag][alterValueLen+i] = reflect.ValueOf(value)
}
}
for k, v := range params {
if nil == v || hasNilValue(v) {
continue
}
logger.Info.Println(k, ":", v)
rs := operatorMethod.Call(v)
//结果报警
if rs[0].Bool() { //触发报警策略
Sender(tagValueMap[k], strategy.Name, buildMsgMethod.Call(v[:1])[0].String(), notice) // 报警
}
}
}
//循环结果集
resIndex += 1
}
}
func CheckArray(strategies []Strategy) bool {
for _, strategy := range strategies {
if !Check(strategy) {
return false
}
}
return true
}
func Check(strategy Strategy) bool {
if "" == strategy.Name {
return false
}
if "" == strategy.Name {
return false
}
if strategy.SqlLen != strings.Count(strategy.Sql, ";") {
return false
}
if len(strategy.Tag) < 1 {
return false
}
length := len(strategy.AlterValue)
for _, v := range strategy.PersonalAlterValue {
if len(v) != length {
return false
}
}
return true
}
func BuildSql(strategies []Strategy) string {
var sqlBuff strings.Builder
for _, strategy := range strategies {
sqlBuff.WriteString(strategy.Sql)
}
return sqlBuff.String()
}
func hasNilValue(params []reflect.Value) bool {
for _, c := range params {
return !c.IsValid()
}
return false
}
func needIgnore(ignoreTag map[string]bool, tags []string) bool {
for _, k := range tags {
if ignoreTag[k] {
return true
}
}
return false
}
func getAlterValue(personalAlterValue map[string][]string, uniqueTag string, tags []string, alterValue []string) []string {
value := personalAlterValue[uniqueTag]
if nil != value {
return value
}
tagLen := len(tags)
for i := 1; i < tagLen; i++ {
if nil != personalAlterValue[tags[i]] {
return personalAlterValue[tags[i]]
}
}
return alterValue
}
func getTagValues(keys []string, tag map[string]string) []string {
values := make([]string, len(keys))
for i, k := range keys {
values[i] = tag[k]
}
return values
}
package alarm
type StrategyType int8
type NoticeSender int8
const (
SERVICE StrategyType = 1 //监控服务的策略
MACHINE StrategyType = 2 //监控机器的策略
COMMON StrategyType = 3 //通用策略
)
const (
DING_DING NoticeSender = 1 //钉钉
MAIL NoticeSender = 2 //邮箱
)
type Strategy struct {
Name string `json:"name"` //策略名称
Sql string `json:"sql"`//sql 每条sql用 ; 分割
SqlLen int `json:"sql_len"` //包含的sql条数,
Type StrategyType `json:"type"` //策略类型
Operator string `json:"operator"` //结果比较方式
AlterValue []string `json:"alter_value"` //触发点
Tag []string `json:"tag"` //sql中需要展示的tag名称,将最细粒度的tag名称放在array[0], sys_name>host
IgnoreTag map[string]bool `json:"ignore_tag"` //需要忽略的服务、主机
PersonalAlterValue map[string][]string `json:"personal_alter_value"` //针对服务、主机个性化触发点配置
NoDataAlter bool `json:"no_data_alter"` //空值报警
Notice Notice `json:"notice"` //通知方式
}
type Notice struct {
Sender NoticeSender `json:"sender"` //发送方式 dingDing(1)/mail(2)
Interval int64 `json:"interval"` //相同的(同服务/主机,同策略)报警发送间隔 单位 秒
Receiver []string //接收者,dingDing 则为webHookUrl, mail 则为邮箱
}
type DinDingMsg struct {
MsgType string `json:"msgtype"`
Link Link `json:"link"`
}
type Link struct {
Title string `json:"title"`
Text string `json:"text"`
MessageUrl string `json:"messageUrl"`
}
package continuous_queries
import (
"fmt"
"git.quantgroup.cn/DevOps/enoch/service/conf"
"git.quantgroup.cn/DevOps/enoch/service/data"
"git.quantgroup.cn/DevOps/enoch/service/log"
"github.com/vrg0/go-common/logger"
"strings"
)
var (
func query(dbName string) []string {
cq := data.QueryMonitor(SHOW_CQ_SQL)
logger.Info.Println(cq)
cqName := make([]string, 0)
for _, row := range cq[0].Series {
if row.Name == dbName {
for _, v := range row.Values {
cqName = append(cqName, v[0].(string))
}
}
}
return cqName
}
func delete(db string, cqName [] string) bool {
sql := strings.Builder{}
for _, name := range cqName {
sql.WriteString(fmt.Sprintf(DROP_CQ_SQL, name, db))
}
rs := data.QueryMonitor(sql.String())
return rs == nil
}
func create(apdexThreshold conf.ApdexThreshold) {
sysName := data.QuerySysName()
logger.Info.Println(sysName)
sql := strings.Builder{}
for _, name := range sysName {
cqName := strings.Replace(name, "-", "_", 10)
threshold := apdexThreshold.Common
if c, ok := apdexThreshold.Personal[name]; ok {
threshold = c
}
sql.WriteString(buildSatSql(cqName, name, threshold))
sql.WriteString(buildTolSql(cqName, name, threshold))
}
sql.WriteString(APDEX_CQ_ALL)
data.QueryMonitor(sql.String())
}
func buildSatSql(cqName string, sysName string, threshold int) string {
return fmt.Sprintf(APDEX_CQ_SAT, cqName, sysName, threshold)
}
func buildTolSql(cqName string, sysName string, threshold int) string {
return fmt.Sprintf(APDEX_CQ_TOL, cqName, sysName, threshold, threshold*4)
}
func Load() {
name := query(data.MONITOR)
logger.Info.Println("old: ", name)
delete(data.MONITOR, name)
create(conf.GlobalConfig.ApdexThreshold)
name = query(data.MONITOR)
logger.Info.Println("new: ", name)
}
package data
const (
MONITOR = "monitor"
SYSNAME_SQL = "show tag values from trace_info with key = sys_name;"
HOST_SQL = "show tag values from trace_info with key= host where sys_name = "
)
package data
import (
"bytes"
"git.quantgroup.cn/DevOps/enoch/service/conf"
"git.quantgroup.cn/DevOps/enoch/service/log"
"github.com/influxdata/influxdb/client/v2"
)
func NewClient() client.Client {
var httpConfig = client.HTTPConfig{
Addr: conf.GlobalConfig.InfluxDb.Host + ":" + conf.GlobalConfig.InfluxDb.Port,
}
con, err := client.NewHTTPClient(httpConfig)
if err != nil {
logger.Error.Println(err.Error())
}
return con
}
func Query(sql string, db string) []client.Result {
con := NewClient()
q := client.Query{Command: sql, Database: db}
res, err := con.Query(q)
if nil != err {
logger.Error.Println("influxdb client init error", err)
}
if nil != res.Error() {
logger.Error.Println("query error", db, sql, res.Error())
}
return res.Results
}
func QueryMonitor(sql string) []client.Result {
return Query(sql, MONITOR)
}
func QuerySysName() []string {
res := QueryMonitor(SYSNAME_SQL)
var values = res[0].Series[0].Values
sysName := make([]string, 0)
for _, v := range values {
sysName = append(sysName, v[1].(string))
}
return sysName
}
func QueryHost(sysName []string) map[string][]string {
var sqlBuff bytes.Buffer
for _, name := range sysName {
sqlBuff.WriteString(HOST_SQL)
sqlBuff.WriteString("'")
sqlBuff.WriteString(name)
sqlBuff.WriteString("';")
}
res := QueryMonitor(sqlBuff.String())
nodeTree := make(map[string][]string)
for index, result := range res {
ipList := make([]string, 0)
values := result.Series[0].Values
for _, v := range values {
ipList = append(ipList, v[1].(string))
}
nodeTree[sysName[index]] = ipList
}
return nodeTree
}
package data
import (
"flag"
"git.quantgroup.cn/DevOps/enoch/service/conf"
"github.com/gomodule/redigo/redis"
"time"
)
func newPool(server, password string) *redis.Pool {
var redisConf = conf.GlobalConfig.Redis
return &redis.Pool{
MaxIdle: redisConf.MaxIdle,
MaxActive: redisConf.MaxActive,
IdleTimeout: redisConf.IdleTimeout * time.Second,
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
if password != "" {
if _, err := conn.Do("AUTH", password); err != nil {
conn.Close()
return nil, err
}
}
return conn, err
},
TestOnBorrow: func(conn redis.Conn, t time.Time) error {
_, err := conn.Do("PING")
return err
},
Wait: true,
}
}
var (
Pool *redis.Pool
redisServer = flag.String("redisServer", conf.GlobalConfig.Redis.Host+":"+conf.GlobalConfig.Redis.Port, "")
redisPassword = flag.String("redisPassword", "", "")
)
func RedisPoolInit() {
flag.Parse()
Pool = newPool(*redisServer, *redisPassword)
}
package node_check
/*
import (
"context"
"git.quantgroup.cn/DevOps/enoch/service/dingding"
"git.quantgroup.cn/DevOps/enoch/service/log"
"git.quantgroup.cn/DevOps/enoch/service/registry"
"github.com/hashicorp/consul/logger"
"net/http"
"os"
"sync"
"time"
)
const (
Passing = "passing"
Critical = "critical"
)
var HandlerMap = new(sync.Map)
var HttpGetRetryCount = 3
var HttpTimeOut = time.Second * 10
var IgnoreServiceMap = make(map[string]struct{})
func init() {
//TODO 灵活配置
HandlerMap.Store("aaaa", "http://www.baidasdfasdfasdfasdfu.com/")
HandlerMap.Store("heimdallr", "http://172.20.6.33:8989/service-down")
// HandlerMap.Store("aaaa", "http://172.20.6.33:8989/service-down")
//TODO 灵活配置
IgnoreServiceMap["vcc-talos"] = struct{}{}
IgnoreServiceMap["aaaa"] = struct{}{}
}
func httpGet(url string, timeout time.Duration) (*http.Response, error) {
ctx, cancel := context.WithCancel(context.TODO())
req, e := http.NewRequest("GET", url, nil)
if e != nil {
return nil, e
} else {
req = req.WithContext(ctx)
}
_ = time.AfterFunc(timeout, func() {
cancel()
})
return http.DefaultClient.Do(req)
}
func handler(serviceName string) {
if url, ok := HandlerMap.Load(serviceName); ok {
for i := 0; i < HttpGetRetryCount; i++ {
if resp, e := httpGet(url.(string), HttpTimeOut); e != nil {
logger.Error.Print(" handler service: ", serviceName, " ", e)
} else {
logger.Info.Print(" handler service: ", serviceName, " ", resp.StatusCode)
break
}
}
} else {
logger.Info.Print(" handler service: ", serviceName, " ", "not found handler hook api")
}
}
type watch struct{}
func (w watch) DeleteService(serviceName string) {
//pass
servicesStatusLock.Lock()
defer servicesStatusLock.Unlock()
delete(servicesStatus, serviceName)
}
func serviceStatus(service *registry.Service) bool {
for _, node := range service.NodeMap {
if node.Status == Passing {
return true
}
}
return false
}
func serviceStr(service *registry.Service) string {
rtn := service.Name + " "
for _, node := range service.NodeMap {
rtn += node.Id + ":" + node.Status + " "
}
return rtn
}
func (w watch) UpdateNodes(service *registry.Service) {
servicesStatusLock.Lock()
defer servicesStatusLock.Unlock()
//单个节点挂了告警
if oldService, ok := servicesStatus[service.Name]; ok {
for _, node := range service.NodeMap {
if oldNode, ok := oldService.NodeMap[node.Id]; ok {
if oldNode.Status == Passing && node.Status == Critical {
logger.Warning.Print(service.Name, " ", node.Id, "---!!!node critical!!!---")
if _, ok := IgnoreServiceMap[service.Name]; !ok {
_ = dingding.SenderDingDing(service.Name+" "+node.Id+" "+"---!!!node critical!!!---", dingding.DefaultDingURL)
}
}
}
}
}
//整个服务挂了告警
//如果 服务存在,并且服务的old状态为passing,并且服务的now状态为critical,则报警,否贼记录服务状态
serviceString := serviceStr(service)
if oldService, ok := servicesStatus[service.Name]; ok && serviceStatus(oldService) && !serviceStatus(service) {
logger.Warning.Print(serviceString, "---!!!service critical!!!---")
if _, ok := IgnoreServiceMap[service.Name]; !ok {
_ = dingding.SenderDingDing(serviceString+"---!!!service critical!!!---", dingding.DefaultDingURL)
}
handler(service.Name)
} else {
logger.Info.Print(serviceString)
}
//更新服务状态
//深拷贝对象
newService := registry.NewService(service.Name)
for kk, vv := range service.NodeMap {
newNode := registry.Node{
ServiceName:vv.ServiceName,
Id:vv.Id,
Port:vv.Port,
Address:vv.Address,
Status:vv.Status,
}
for x, y := range vv.Meta {
newNode.Meta[x] = y
}
newService.NodeMap[kk] = &newNode
}
servicesStatus[service.Name] = newService
}
func (w watch) AddNode(node *registry.Node) {
//pass
}
func (w watch) DelNode(node *registry.Node) {
//pass
}
var (
servicesStatus = make(map[string]*registry.Service)
servicesStatusLock = new(sync.Mutex)
)
func InitServiceStatus() {
servicesStatus = registry.GetServiceMap()
}
func NodeCheck() {
defer func() {
if e := recover(); e != nil {
logger.Info.Print("node check panic: ", e)
_ = dingding.SenderDingDing("node check panic!", dingding.DefaultDingURL)
time.Sleep(time.Second * 1)
NodeCheck()
}
}()
//注册器初始化
dc := "3c"
cluster := []string{"172.30.12.2:8500", "172.30.12.3:8500", "172.30.12.4:8500"}
if e := registry.Init("consul", map[string]interface{}{"dc": dc, "cluster": cluster}); e != nil {
logger.Info.Print("registry init error:", e)
os.Exit(-1)
}
time.Sleep(time.Second * 1)
//服务状态初始化
InitServiceStatus()
//设置观察者
if e := registry.SetObserver("watch", &watch{}); e != nil {
logger.Info.Print("set observer error:", e)
os.Exit(-1)
}
select {}
}
*/
package node_check
/*
import "testing"
func TestNodeCheck(t *testing.T) {
go NodeCheck()
select{}
}
*/
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment