unifiedmonitor_query.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package monitor
  15. import (
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. var (
  21. UNIFIED_MONITOR_FIELD_OPT_TYPE = []string{"Aggregations", "Selectors"}
  22. UNIFIED_MONITOR_GROUPBY_OPT_TYPE = []string{"time", "tag", "fill"}
  23. UNIFIED_MONITOR_FIELD_OPT_VALUE = map[string][]string{
  24. "Aggregations": {"MEAN", "SUM", "MAX", "MIN"}, // {"COUNT", "DISTINCT", "INTEGRAL", "MEAN", "MEDIAN", "MODE", "STDDEV", "SUM"},
  25. "Selectors": {"BOTTOM", "FIRST", "LAST", "MAX", "MIN", "TOP"},
  26. }
  27. UNIFIED_MONITOR_GROUPBY_OPT_VALUE = map[string][]string{
  28. "fill": {"linear", "none", "previous", "0"},
  29. }
  30. MEASUREMENT_TAG_KEYWORD = map[string]string{
  31. METRIC_RES_TYPE_HOST: "host",
  32. METRIC_RES_TYPE_GUEST: "vm_name",
  33. METRIC_RES_TYPE_REDIS: "redis_name",
  34. METRIC_RES_TYPE_RDS: "rds_name",
  35. METRIC_RES_TYPE_OSS: "oss_name",
  36. METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_name",
  37. METRIC_RES_TYPE_STORAGE: "storage_name",
  38. METRIC_RES_TYPE_AGENT: "vm_name",
  39. }
  40. MEASUREMENT_TAG_ID = map[string]string{
  41. METRIC_RES_TYPE_HOST: "host_id",
  42. METRIC_RES_TYPE_GUEST: "vm_id",
  43. METRIC_RES_TYPE_AGENT: "vm_id",
  44. METRIC_RES_TYPE_REDIS: "redis_id",
  45. METRIC_RES_TYPE_RDS: "rds_id",
  46. METRIC_RES_TYPE_OSS: "oss_id",
  47. METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_id",
  48. METRIC_RES_TYPE_TENANT: "tenant_id",
  49. METRIC_RES_TYPE_DOMAIN: "domain_id",
  50. METRIC_RES_TYPE_STORAGE: "storage_id",
  51. }
  52. AlertReduceFunc = map[string]string{
  53. "avg": "average value",
  54. "sum": "Summation",
  55. "min": "minimum value",
  56. "max": "Maximum",
  57. "count": "count value",
  58. "last": "Latest value",
  59. "median": "median",
  60. "diff": "The difference between the latest value and the oldest value. The judgment basis value must be legal",
  61. "delta": "The signed difference between the latest value and the oldest value (can be positive or negative)",
  62. "percent_diff": "The difference between the new value and the old value,based on the percentage of the old value",
  63. }
  64. )
  65. func GetMeasurementTagIdKeyByResType(resType string) string {
  66. return MEASUREMENT_TAG_ID[resType]
  67. }
  68. func GetMeasurementTagIdKeyByResTypeWithDefault(resType string) string {
  69. tagId := GetMeasurementTagIdKeyByResType(resType)
  70. if len(tagId) == 0 {
  71. tagId = "host_id"
  72. }
  73. return tagId
  74. }
  75. func GetMeasurementResourceId(tags map[string]string, resType string) string {
  76. return tags[GetMeasurementTagIdKeyByResType(resType)]
  77. }
  78. func GetResourceIdFromTagWithDefault(tags map[string]string, resType string) string {
  79. tagId := GetMeasurementTagIdKeyByResTypeWithDefault(resType)
  80. return tags[tagId]
  81. }
  82. type MetricFunc struct {
  83. FieldOptType []string `json:"field_opt_type"`
  84. FieldOptValue map[string][]string `json:"field_opt_value"`
  85. GroupOptType []string `json:"group_opt_type"`
  86. GroupOptValue map[string][]string `json:"group_opt_value"`
  87. }
  88. type SimpleQueryInput struct {
  89. // 资源Id, 可以不填, 代表查询指定监控的所有监控数据
  90. Id string `json:"id"`
  91. // 查询指定数据库
  92. // default: telegraf
  93. Database string `json:"database"`
  94. // 监控指标: https://github.com/codelinz/cloudpods/blob/monitor/pkg/cloudprovider/metrics.go
  95. MetricName string `json:"metric_name"`
  96. // 开始时间
  97. StartTime time.Time `json:"start_time"`
  98. // 结束时间
  99. EndTime time.Time `json:"end_time"`
  100. // 指定标签
  101. Tags map[string]string `json:"tag_pairs"`
  102. // 间隔周期
  103. // default: 5m
  104. Interval string `json:"interval"`
  105. }
  106. type CdfQueryInput struct {
  107. // 查询指定数据库
  108. // default: telegraf
  109. Database string `json:"database"`
  110. // 监控指标: https://github.com/codelinz/cloudpods/blob/monitor/pkg/cloudprovider/metrics.go
  111. MetricName string `json:"metric_name"`
  112. // 查询周期
  113. // exaple: 4h
  114. // default: 1h
  115. Period string `json:"period"`
  116. // 指定标签
  117. Tags map[string]string `json:"tag_pairs"`
  118. }
  119. type SimpleQueryOutput struct {
  120. Id string `json:"id"`
  121. Time time.Time `json:"time"`
  122. Value float64 `json:"value"`
  123. }
  124. type MetricsQueryResult struct {
  125. SeriesTotal int64 `json:"series_total"`
  126. Series TimeSeriesSlice `json:"series"`
  127. Metas []QueryResultMeta `json:"metas"`
  128. ReducedResult *ReducedResult `json:"reduced_result"`
  129. }
  130. type TimeSeriesPoints []TimePoint
  131. type TimeSeriesSlice []*TimeSeries
  132. type TimeSeries struct {
  133. // RawName is used to frontend displaying the curve name
  134. RawName string `json:"raw_name"`
  135. Columns []string `json:"columns"`
  136. Name string `json:"name"`
  137. Points TimeSeriesPoints `json:"points"`
  138. Tags map[string]string `json:"tags,omitempty"`
  139. CloudTags map[string]string `json:"cloud_tags,omitempty"`
  140. }
  141. type TimePoint []interface{}
  142. func NewTimePoint(value *float64, timestamp float64) TimePoint {
  143. return TimePoint{value, timestamp}
  144. }
  145. func NewTimePointByVal(value float64, timestamp float64) TimePoint {
  146. return NewTimePoint(&value, timestamp)
  147. }
  148. func (p TimePoint) IsValid() bool {
  149. if val, ok := p[0].(*float64); ok && val != nil {
  150. return true
  151. }
  152. return false
  153. //return p[0].(*float64) != nil
  154. }
  155. func (p TimePoint) IsValids() bool {
  156. for i := 0; i < len(p)-1; i++ {
  157. if p[i] == nil {
  158. return false
  159. }
  160. if p[i].(*float64) == nil {
  161. return false
  162. }
  163. }
  164. return true
  165. }
  166. func (p TimePoint) Value() float64 {
  167. v := p[0]
  168. if fval, ok := v.(*float64); ok {
  169. return *fval
  170. }
  171. if ival, ok := v.(*int64); ok {
  172. return float64(*ival)
  173. }
  174. if t, ok := v.(float64); ok {
  175. return t
  176. }
  177. if t, ok := v.(int64); ok {
  178. return float64(t)
  179. }
  180. return 0
  181. }
  182. func (p TimePoint) Timestamp() float64 {
  183. v := p[len(p)-1]
  184. if t, ok := v.(float64); ok {
  185. return t
  186. }
  187. if t, ok := v.(int64); ok {
  188. return float64(t)
  189. }
  190. return 0
  191. }
  192. func (p TimePoint) Time() time.Time {
  193. return time.UnixMilli(int64(p.Timestamp()))
  194. }
  195. func (p TimePoint) Values() []float64 {
  196. values := make([]float64, 0)
  197. for i := 0; i < len(p)-1; i++ {
  198. values = append(values, *(p[i].(*float64)))
  199. }
  200. return values
  201. }
  202. func (p TimePoint) PointValueStr() []string {
  203. arrStr := make([]string, 0)
  204. for i := 0; i < len(p)-1; i++ {
  205. if p[i] == nil {
  206. arrStr = append(arrStr, "")
  207. }
  208. if fval, ok := p[i].(*float64); ok {
  209. arrStr = append(arrStr, strconv.FormatFloat((*fval), 'f', -1, 64))
  210. continue
  211. }
  212. if ival, ok := p[i].(*int64); ok {
  213. arrStr = append(arrStr, strconv.FormatInt((*ival), 64))
  214. continue
  215. }
  216. arrStr = append(arrStr, p[i].(string))
  217. }
  218. return arrStr
  219. }
  220. func NewTimeSeriesPointsFromArgs(values ...float64) TimeSeriesPoints {
  221. points := make(TimeSeriesPoints, 0)
  222. for i := 0; i < len(values); i += 2 {
  223. points = append(points, NewTimePoint(&values[i], values[i+1]))
  224. }
  225. return points
  226. }
  227. type QueryResultMeta struct {
  228. RawQuery string `json:"raw_query"`
  229. ResultReducerValue float64 `json:"result_reducer_value"`
  230. }
  231. const ConditionTypeMetricQuery = "metricquery"
  232. type CdfQueryData struct {
  233. Vmrange string `json:"vmrange"`
  234. Metric float64 `json:"metric"`
  235. Value int `json:"value"`
  236. ValueAsc int `json:"value_asc"`
  237. ValueDesc int `json:"value_desc"`
  238. Total int `json:"total"`
  239. }
  240. func (c CdfQueryData) Copy() CdfQueryData {
  241. return CdfQueryData{
  242. Vmrange: c.Vmrange,
  243. Metric: c.Metric,
  244. Value: c.Value,
  245. ValueAsc: c.ValueAsc,
  246. ValueDesc: c.ValueDesc,
  247. Total: c.Total,
  248. }
  249. }
  250. func (c CdfQueryData) Start() float64 {
  251. s := strings.Split(c.Vmrange, "...")[0]
  252. v, _ := strconv.ParseFloat(s, 64)
  253. return v
  254. }
  255. func (c CdfQueryData) End() float64 {
  256. info := strings.Split(c.Vmrange, "...")
  257. v := 0.0
  258. if len(info) == 2 {
  259. v, _ = strconv.ParseFloat(info[1], 64)
  260. }
  261. return v
  262. }
  263. type CdfQueryDataSet []CdfQueryData
  264. func (c CdfQueryDataSet) Len() int {
  265. return len(c)
  266. }
  267. func (c CdfQueryDataSet) Swap(i, j int) {
  268. c[i], c[j] = c[j], c[i]
  269. }
  270. func (c CdfQueryDataSet) Less(i, j int) bool {
  271. return c[i].Start() < c[j].Start()
  272. }
  273. type CdfQueryOutput struct {
  274. Data CdfQueryDataSet `json:"data"`
  275. }
  276. // ResourceMetricsQueryInput 批量查询资源监控数据的输入参数
  277. type ResourceMetricsQueryInput struct {
  278. // 资源类型: "host" 或 "guest"
  279. ResType string `json:"res_type"`
  280. // 资源 ID 列表
  281. ResIds []string `json:"res_ids"`
  282. // 查询开始时间(默认: 1小时前)
  283. StartTime time.Time `json:"start_time"`
  284. // 查询结束时间(默认: now)
  285. EndTime time.Time `json:"end_time"`
  286. // 查询间隔(默认: 5m)
  287. Interval string `json:"interval"`
  288. }
  289. // ResourceMetricValues 单个资源的监控数据
  290. type ResourceMetricValues struct {
  291. // CPU 使用率 (%)
  292. CpuUsage *float64 `json:"cpu_usage"`
  293. // 内存使用率 (%)
  294. MemUsage *float64 `json:"mem_usage"`
  295. // 磁盘使用率 (%)
  296. DiskUsage *float64 `json:"disk_usage"`
  297. // 磁盘读速率 (Bps)
  298. DiskReadRate *float64 `json:"disk_read_rate"`
  299. // 磁盘写速率 (Bps)
  300. DiskWriteRate *float64 `json:"disk_write_rate"`
  301. // 网络入流量 (bps)
  302. NetInRate *float64 `json:"net_in_rate"`
  303. // 网络出流量 (bps)
  304. NetOutRate *float64 `json:"net_out_rate"`
  305. // 告警状态: init/attach/alerting
  306. AlertState string `json:"alert_state"`
  307. }
  308. // ResourceMetricsQueryOutput 批量查询资源监控数据的输出
  309. type ResourceMetricsQueryOutput struct {
  310. ResourceMetrics map[string]ResourceMetricValues `json:"resource_metrics"`
  311. }