Commit 061c81b8 authored by jingbo.wang's avatar jingbo.wang

完善服务状态报表功能

parent 53d16de2
...@@ -3,6 +3,7 @@ package report_form ...@@ -3,6 +3,7 @@ package report_form
import ( import (
"fmt" "fmt"
"git.quantgroup.cn/DevOps/enoch/pkg/glog" "git.quantgroup.cn/DevOps/enoch/pkg/glog"
"sort"
"time" "time"
) )
...@@ -12,8 +13,9 @@ type Node struct { ...@@ -12,8 +13,9 @@ type Node struct {
startTime time.Time startTime time.Time
endTime time.Time endTime time.Time
//cpu //cpu
averageCpu int removeN100MaxCpu int
maxCpu int averageCpu int
maxCpu int
//mem //mem
averageMem int averageMem int
maxMem int maxMem int
...@@ -37,10 +39,65 @@ func NewNode(serviceName string, address string, startTime time.Time, endTime ti ...@@ -37,10 +39,65 @@ func NewNode(serviceName string, address string, startTime time.Time, endTime ti
rtn.initMem() rtn.initMem()
rtn.initDisk() rtn.initDisk()
rtn.initThread() rtn.initThread()
rtn.initRemoveN100MaxCpu()
return rtn return rtn
} }
func (n *Node) initRemoveN100MaxCpu() {
const n100 = 3
//求count
countSqlFormat := `SELECT count(system_load_average) FROM machine_info ` +
`WHERE sys_name = '%s' AND host = '%s' AND time >= %d AND time < %d;`
sql := fmt.Sprintf(countSqlFormat, n.serviceName, n.address, n.startTime.UnixNano(), n.endTime.UnixNano())
count, ok := queryOneAndToInt(sql)
if !ok {
return
}
topSqlFormat := `SELECT top("x", %d) from (SELECT system_load_average/processors*100 as "x" FROM machine_info ` +
`WHERE sys_name = '%s' AND host = '%s' AND time >= %d AND time < %d)`
sql = fmt.Sprintf(topSqlFormat, count*n100/100+1, n.serviceName, n.address, n.startTime.UnixNano(), n.endTime.UnixNano())
resp, err := query(sql)
if err != nil {
glog.Error("query sql err :", err, sql)
return
}
if len(resp.Results) != 1 {
fmt.Println("??3", len(resp.Results))
return
}
res := resp.Results[0]
if len(res.Series) != 1 {
return
}
row := res.Series[0]
topIdx, ok := getModRowKeyIdx("top", row)
if !ok {
return
}
sort.Slice(row.Values, func(i, j int) bool {
x1, ok1 := jsonNumberToInt(row.Values[i][topIdx])
x2, ok2 := jsonNumberToInt(row.Values[j][topIdx])
if !ok1 || !ok2 {
return false
}
if x1 < x2 {
return true
}
return false
})
if len(row.Values) == 0 {
return
}
removeN100MaxCpu, ok := jsonNumberToInt(row.Values[0][topIdx])
if !ok {
return
}
n.removeN100MaxCpu = removeN100MaxCpu
}
//依次返回:平均、最大 //依次返回:平均、最大
//如果获取失败返回0,0,0 //如果获取失败返回0,0,0
func (n *Node) queryKey(key string) (int, int) { func (n *Node) queryKey(key string) (int, int) {
...@@ -48,13 +105,14 @@ func (n *Node) queryKey(key string) (int, int) { ...@@ -48,13 +105,14 @@ func (n *Node) queryKey(key string) (int, int) {
sqlFormat := `SELECT mean("x"), max("x") ` + sqlFormat := `SELECT mean("x"), max("x") ` +
`FROM (` + `FROM (` +
`SELECT %s AS "x" FROM machine_info ` + `SELECT %s AS "x" FROM machine_info ` +
`WHERE sys_name = '%s' AND host = '%s'AND time >= %d AND time < %d` + `WHERE sys_name = '%s' AND host = '%s'AND time >= %d AND time < %d ` +
`);` `);`
sql := fmt.Sprintf(sqlFormat, key, n.serviceName, n.address, n.startTime.UnixNano(), n.endTime.UnixNano()) sql := fmt.Sprintf(sqlFormat, key, n.serviceName, n.address, n.startTime.UnixNano(), n.endTime.UnixNano())
resp, err := query(sql) resp, err := query(sql)
if err != nil { if err != nil {
glog.Error("node query key:", err) glog.Error("node query key:", err)
return 0, 0
} }
if len(resp.Results) != 1 { if len(resp.Results) != 1 {
return 0, 0 return 0, 0
...@@ -124,6 +182,10 @@ func (n *Node) GetMaxCpu() int { ...@@ -124,6 +182,10 @@ func (n *Node) GetMaxCpu() int {
return n.maxCpu return n.maxCpu
} }
func (n *Node) GetRemoveN100MaxCpu() int {
return n.removeN100MaxCpu
}
func (n *Node) GetAverageMem() int { func (n *Node) GetAverageMem() int {
return n.averageMem return n.averageMem
} }
......
...@@ -150,8 +150,17 @@ func Run(n int) string { ...@@ -150,8 +150,17 @@ func Run(n int) string {
rtn.WriteString(fmt.Sprintf("总访问量:%v 总响应时间:%v 平均响应时间:%v\n\n", rtn.WriteString(fmt.Sprintf("总访问量:%v 总响应时间:%v 平均响应时间:%v\n\n",
sm.GetCount(), sm.GetSumDuration(), sm.GetAverageDuration())) sm.GetCount(), sm.GetSumDuration(), sm.GetAverageDuration()))
//服务平均响应时间排行
serviceTable := NewTable("服务平均响应时间排行", "duration", "sys_name", "traffic_volume")
serviceList := sm.GetAverageDurationServiceList()
for _, s := range serviceList {
_ = serviceTable.AddRecord(s.GetAverageDuration(), s.Name(), s.GetCount())
}
rtn.WriteString(serviceTable.ToString())
rtn.WriteString("\n")
//服务响应时间中位值排行 //服务响应时间中位值排行
medianTable := NewTable("服务响应时间中位值排行", "duration", "sys_name", "path", "count") medianTable := NewTable("服务接口响应时间中位值排行", "duration", "sys_name", "path", "traffic_volume")
medianList := sm.GetMedianDurationPathList() medianList := sm.GetMedianDurationPathList()
for _, m := range medianList { for _, m := range medianList {
_ = medianTable.AddRecord(m.GetMedianDuration(), m.GetServiceName(), m.GetPath(), m.GetCount()) _ = medianTable.AddRecord(m.GetMedianDuration(), m.GetServiceName(), m.GetPath(), m.GetCount())
...@@ -160,7 +169,7 @@ func Run(n int) string { ...@@ -160,7 +169,7 @@ func Run(n int) string {
rtn.WriteString("\n") rtn.WriteString("\n")
//服务响应时间平均值排行 //服务响应时间平均值排行
averageTable := NewTable("服务响应时间平均值排行", "duration", "sys_name", "path", "count") averageTable := NewTable("服务接口响应时间平均值排行", "duration", "sys_name", "path", "traffic_volume")
averageList := sm.GetAverageDurationPathList() averageList := sm.GetAverageDurationPathList()
for _, m := range averageList { for _, m := range averageList {
_ = averageTable.AddRecord(m.GetAverageDuration(), m.GetServiceName(), m.GetPath(), m.GetCount()) _ = averageTable.AddRecord(m.GetAverageDuration(), m.GetServiceName(), m.GetPath(), m.GetCount())
...@@ -169,7 +178,7 @@ func Run(n int) string { ...@@ -169,7 +178,7 @@ func Run(n int) string {
rtn.WriteString("\n") rtn.WriteString("\n")
//响应时间最长的请求排行 //响应时间最长的请求排行
maxTable := NewTable("响应时间最长的请求排行", "duration", "sys_name", "path", "timestamp", "trace_id") maxTable := NewTable("服务接口响应时间最高值排行", "duration", "sys_name", "path", "timestamp", "trace_id")
maxList := sm.GetMaxDurationTracePointList() maxList := sm.GetMaxDurationTracePointList()
for _, m := range maxList { for _, m := range maxList {
_ = maxTable.AddRecord(m.Duration, m.ServiceName, m.Path, m.Timestamp, m.TraceId) _ = maxTable.AddRecord(m.Duration, m.ServiceName, m.Path, m.Timestamp, m.TraceId)
...@@ -177,20 +186,20 @@ func Run(n int) string { ...@@ -177,20 +186,20 @@ func Run(n int) string {
rtn.WriteString(maxTable.ToString()) rtn.WriteString(maxTable.ToString())
rtn.WriteString("\n") rtn.WriteString("\n")
//平均cpu使用率排行 //去topN100后的峰值cpu使用率排行
cpuTable := NewTable("平均cpu使用率排行", "cpu", "sys_name", "count", "average_duration") maxRemoveN100CpuTable := NewTable("常规cpu使用率排行", "cpu", "sys_name", "traffic_volume", "average_duration")
cpuList := sm.GetAverageCpuServiceList() maxRemoveN100CpuList := sm.GetRemoveN100MaxCpuServiceList()
for _, s := range cpuList { for _, s := range maxRemoveN100CpuList {
if s.GetAverageCpu() < cpuMin { if s.GetRemoveN100MaxCpu() < cpuMin {
break break
} }
_ = cpuTable.AddRecord(s.GetAverageCpu(), s.Name(), s.GetCount(), s.GetAverageDuration()) _ = maxRemoveN100CpuTable.AddRecord(s.GetRemoveN100MaxCpu(), s.Name(), s.GetCount(), s.GetAverageDuration())
} }
rtn.WriteString(cpuTable.ToString()) rtn.WriteString(maxRemoveN100CpuTable.ToString())
rtn.WriteString("\n") rtn.WriteString("\n")
//平均cpu使用率排行 //峰值cpu使用率排行
maxCpuTable := NewTable("峰值cpu使用率排行", "cpu", "sys_name", "count", "average_duration") maxCpuTable := NewTable("峰值cpu使用率排行", "cpu", "sys_name", "traffic_volume", "average_duration")
maxCpuList := sm.GetMaxCpuServiceList() maxCpuList := sm.GetMaxCpuServiceList()
for _, s := range maxCpuList { for _, s := range maxCpuList {
if s.GetMaxCpu() < cpuMin { if s.GetMaxCpu() < cpuMin {
...@@ -202,7 +211,7 @@ func Run(n int) string { ...@@ -202,7 +211,7 @@ func Run(n int) string {
rtn.WriteString("\n") rtn.WriteString("\n")
//内存峰值使用率排行 //内存峰值使用率排行
memTable := NewTable("峰值内存使用率排行", "mem", "sys_name", "count", "average_duration") memTable := NewTable("峰值内存使用率排行", "mem", "sys_name", "traffic_volume", "average_duration")
memList := sm.GetMaxMemServiceList() memList := sm.GetMaxMemServiceList()
for _, s := range memList { for _, s := range memList {
if s.GetMaxMem() < memMin { if s.GetMaxMem() < memMin {
...@@ -214,7 +223,7 @@ func Run(n int) string { ...@@ -214,7 +223,7 @@ func Run(n int) string {
rtn.WriteString("\n") rtn.WriteString("\n")
//硬盘峰值使用率排行 //硬盘峰值使用率排行
diskTable := NewTable("峰值硬盘使用率排行", "disk", "sys_name", "count", "average_duration") diskTable := NewTable("峰值硬盘使用率排行", "disk", "sys_name", "traffic_volume", "average_duration")
diskList := sm.GetMaxDiskServiceList() diskList := sm.GetMaxDiskServiceList()
for _, s := range diskList { for _, s := range diskList {
if s.GetMaxDisk() < diskMin { if s.GetMaxDisk() < diskMin {
......
...@@ -58,7 +58,7 @@ func NewService(name string, startTime time.Time, endTime time.Time) *Service { ...@@ -58,7 +58,7 @@ func NewService(name string, startTime time.Time, endTime time.Time) *Service {
if _, ok := IgnorePathMap[strings.ToLower(pathSplit[1])]; ok { if _, ok := IgnorePathMap[strings.ToLower(pathSplit[1])]; ok {
continue continue
} }
glog.Info("init path:", rtn.name, path) glog.Info("init path: ", rtn.name, " ", path)
pathObj, ok := NewPath(rtn.name, path, rtn.startTime, rtn.endTime) pathObj, ok := NewPath(rtn.name, path, rtn.startTime, rtn.endTime)
if !ok { if !ok {
continue continue
...@@ -244,6 +244,12 @@ func (s *Service) GetAverageCpu() int { ...@@ -244,6 +244,12 @@ func (s *Service) GetAverageCpu() int {
}) })
} }
func (s *Service) GetRemoveN100MaxCpu() int {
return s.getNodeMapValue(func(node *Node) int {
return node.GetRemoveN100MaxCpu()
})
}
func (s *Service) GetMaxCpu() int { func (s *Service) GetMaxCpu() int {
return s.getNodeMapValue(func(node *Node) int { return s.getNodeMapValue(func(node *Node) int {
return node.GetMaxCpu() return node.GetMaxCpu()
......
...@@ -75,7 +75,24 @@ func (sm *ServiceMap) GetAverageCpuServiceList() []*Service { ...@@ -75,7 +75,24 @@ func (sm *ServiceMap) GetAverageCpuServiceList() []*Service {
return rtn return rtn
} }
//峰值平均cpu使用率列表 //去N100后的峰值cpu使用率列表
func (sm *ServiceMap) GetRemoveN100MaxCpuServiceList() []*Service {
rtn := make([]*Service, 0)
for _, s := range sm.serviceMap {
rtn = append(rtn, s)
}
sort.Slice(rtn, func(i, j int) bool {
if rtn[i].GetRemoveN100MaxCpu() > rtn[j].GetRemoveN100MaxCpu() {
return true
}
return false
})
return rtn
}
//峰值cpu使用率列表
func (sm *ServiceMap) GetMaxCpuServiceList() []*Service { func (sm *ServiceMap) GetMaxCpuServiceList() []*Service {
rtn := make([]*Service, 0) rtn := make([]*Service, 0)
for _, s := range sm.serviceMap { for _, s := range sm.serviceMap {
...@@ -126,6 +143,28 @@ func (sm *ServiceMap) GetMaxDiskServiceList() []*Service { ...@@ -126,6 +143,28 @@ func (sm *ServiceMap) GetMaxDiskServiceList() []*Service {
return rtn return rtn
} }
//服务平均响应时间排行
func (sm *ServiceMap) GetAverageDurationServiceList() []*Service {
rtn := make([]*Service, 0)
for _, s := range sm.serviceMap {
//屏蔽掉访问量为0的服务
if s.GetCount() == 0 {
continue
}
rtn = append(rtn, s)
}
sort.Slice(rtn, func(i, j int) bool {
if rtn[i].GetAverageDuration() > rtn[j].GetAverageDuration() {
return true
}
return false
})
return rtn
}
//获取最大中位响应时间列表 //获取最大中位响应时间列表
func (sm *ServiceMap) GetMedianDurationPathList() []*Path { func (sm *ServiceMap) GetMedianDurationPathList() []*Path {
rtn := make([]*Path, 0) rtn := make([]*Path, 0)
......
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