service2.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package service
  2. import (
  3. "context"
  4. "go-admin/app/observe/models"
  5. "go-admin/app/observe/service/dto"
  6. "go-admin/render"
  7. "go-admin/render/report"
  8. "github.com/go-admin-team/go-admin-core/logger"
  9. )
  10. type ScopeGraphBasic struct {
  11. ADD []render.NodeSummary `json:"add"`
  12. Update []render.NodeSummary `json:"update"`
  13. Remove []render.NodeSummary `json:"remove"`
  14. Reset bool `json:"reset"`
  15. }
  16. func (sgb *ScopeGraphBasic) setShape(icon string) string {
  17. switch icon {
  18. case "cloud":
  19. return "cloud"
  20. case "mysql":
  21. return "cylinder"
  22. case "clickhouse":
  23. return "cylinder"
  24. case "mssql":
  25. return "cylinder"
  26. case "oracle":
  27. return "cylinder"
  28. case "db2":
  29. return "cylinder"
  30. case "postgresql":
  31. return "cylinder"
  32. case "hive":
  33. return "cylinder"
  34. case "mariadb":
  35. return "cylinder"
  36. case "sqlite":
  37. return "cylinder"
  38. case "mongodb":
  39. return "cylinder"
  40. case "redis":
  41. return "cylinder"
  42. case "neo4j":
  43. return "cylinder"
  44. case "elasticsearch":
  45. return "cylinder"
  46. case "opensearch":
  47. return "cylinder"
  48. case "memcached":
  49. return "cylinder"
  50. case "other_sql":
  51. return "cylinder"
  52. case "kafka":
  53. return "dottedcylinder"
  54. case "activemq":
  55. return "dottedcylinder"
  56. case "jms":
  57. return "dottedcylinder"
  58. case "rabbitmq":
  59. return "dottedcylinder"
  60. case "rocketmq":
  61. return "dottedcylinder"
  62. default:
  63. return "circle"
  64. }
  65. }
  66. func (sgb *ScopeGraphBasic) AddNoSoulGraph(
  67. svc *Service,
  68. ctx context.Context,
  69. req *dto.ServiceGetEdgesReq,
  70. resp *models.Graph) {
  71. if err := svc.GetNoSoulGraph(ctx, req, resp); err != nil {
  72. logger.Error("get no-soul graph err: ", err.Error())
  73. // api.Error(http.StatusInternalServerError, err, err.Error())
  74. return
  75. }
  76. for _, node := range resp.Nodes {
  77. ns := render.NodeSummary{
  78. BasicNodeSummary: render.BasicNodeSummary{
  79. ID: node.ID,
  80. Label: node.Title, //钻取下级 从属依赖下级
  81. LabelMinor: node.SubTitle, //钻取下下级 从属依赖下下级
  82. Shape: sgb.setShape(node.Icon),
  83. Color: "DI",
  84. },
  85. }
  86. //TODO:
  87. for _, es := range resp.Edges {
  88. if es.Source == node.ID {
  89. ns.Adjacency = append(ns.Adjacency, es.Target)
  90. }
  91. }
  92. sgb.ADD = append(sgb.ADD, ns)
  93. }
  94. sgb.Reset = true
  95. }
  96. func (sgb *ScopeGraphBasic) UpdateGraph(
  97. svc *Service,
  98. ctx context.Context,
  99. req *dto.ServiceGetEdgesReq,
  100. resp *models.Graph) {
  101. if err := svc.GetGraph(ctx, req, resp); err != nil {
  102. logger.Error("get graph err: ", err.Error())
  103. // api.Error(http.StatusInternalServerError, err, err.Error())
  104. return
  105. }
  106. for _, node := range resp.Nodes {
  107. ns := render.NodeSummary{
  108. BasicNodeSummary: render.BasicNodeSummary{
  109. ID: node.ID,
  110. Label: node.Title, //钻取下级 从属依赖下级
  111. LabelMinor: node.SubTitle, //钻取下下级 从属依赖下下级
  112. Shape: sgb.setShape(node.Icon),
  113. Color: "G",
  114. // Tag: "camera",
  115. },
  116. }
  117. if node.Apdex == 0 {
  118. node.Apdex = 1
  119. }
  120. // 当成功和失败都为0时,为系统组件,系统组件标记为100%成功率(暂定)
  121. if node.ArcFaild == 0 && node.ArcSuccess == 0 {
  122. node.ArcSuccess = 1
  123. }
  124. mrApdex := report.MetricRow{
  125. ID: "apdex",
  126. Label: "可用性",
  127. Format: "percent",
  128. Value: node.Apdex * 100,
  129. Priority: 1,
  130. Metric: report.Metric{
  131. Min: 0,
  132. Max: 100,
  133. },
  134. }
  135. mrErr := report.MetricRow{
  136. ID: "request failed",
  137. Label: "错误率",
  138. Format: "percent",
  139. Value: node.ArcFaild * 100,
  140. Priority: 1,
  141. Metric: report.Metric{
  142. Min: 0,
  143. Max: 100,
  144. },
  145. }
  146. mrSucc := report.MetricRow{
  147. ID: "request success",
  148. Label: "成功率",
  149. Format: "percent",
  150. Value: node.ArcSuccess * 100,
  151. Priority: 2,
  152. Metric: report.Metric{
  153. Min: 0,
  154. Max: 100,
  155. },
  156. }
  157. // mrSend := report.MetricRow{
  158. // ID: "Send Req",
  159. // Label: "发送量",
  160. // Format: "",
  161. // Value: float64(node.Send),
  162. // Priority: 3,
  163. // Metric: report.Metric{
  164. // Min: 0,
  165. // Max: float64(node.Send) + float64(node.Receive),
  166. // },
  167. // }
  168. // mrReceive := report.MetricRow{
  169. // ID: "Receive Req",
  170. // Label: "接收量",
  171. // Format: "",
  172. // Value: float64(node.Receive),
  173. // Priority: 4,
  174. // Metric: report.Metric{
  175. // Min: 0,
  176. // Max: float64(node.Send) + float64(node.Receive),
  177. // },
  178. // }
  179. if node.ArcFaild+node.ArcSuccess == 0 {
  180. ns.Color = "DI"
  181. } else {
  182. if node.ArcSuccess < 0.6 || node.Apdex < 0.4 {
  183. ns.Color = "R"
  184. } else if (node.ArcSuccess >= 0.6 && node.ArcSuccess < 0.8) ||
  185. (node.Apdex >= 0.4 && node.Apdex < 0.8) {
  186. ns.Color = "Y"
  187. }
  188. }
  189. ns.Metrics = append(ns.Metrics, mrApdex)
  190. ns.Metrics = append(ns.Metrics, mrErr)
  191. ns.Metrics = append(ns.Metrics, mrSucc)
  192. // ns.Metrics = append(ns.Metrics, mrSend)
  193. // ns.Metrics = append(ns.Metrics, mrReceive)
  194. for _, es := range resp.Edges {
  195. if es.Source == node.ID {
  196. ns.Adjacency = append(ns.Adjacency, es.Target)
  197. }
  198. }
  199. sgb.Update = append(sgb.Update, ns)
  200. }
  201. // sgb.Reset = true
  202. }