// Copyright 2019 Yunion // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package monitor import ( "strconv" "strings" "time" ) var ( UNIFIED_MONITOR_FIELD_OPT_TYPE = []string{"Aggregations", "Selectors"} UNIFIED_MONITOR_GROUPBY_OPT_TYPE = []string{"time", "tag", "fill"} UNIFIED_MONITOR_FIELD_OPT_VALUE = map[string][]string{ "Aggregations": {"MEAN", "SUM", "MAX", "MIN"}, // {"COUNT", "DISTINCT", "INTEGRAL", "MEAN", "MEDIAN", "MODE", "STDDEV", "SUM"}, "Selectors": {"BOTTOM", "FIRST", "LAST", "MAX", "MIN", "TOP"}, } UNIFIED_MONITOR_GROUPBY_OPT_VALUE = map[string][]string{ "fill": {"linear", "none", "previous", "0"}, } MEASUREMENT_TAG_KEYWORD = map[string]string{ METRIC_RES_TYPE_HOST: "host", METRIC_RES_TYPE_GUEST: "vm_name", METRIC_RES_TYPE_REDIS: "redis_name", METRIC_RES_TYPE_RDS: "rds_name", METRIC_RES_TYPE_OSS: "oss_name", METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_name", METRIC_RES_TYPE_STORAGE: "storage_name", METRIC_RES_TYPE_AGENT: "vm_name", } MEASUREMENT_TAG_ID = map[string]string{ METRIC_RES_TYPE_HOST: "host_id", METRIC_RES_TYPE_GUEST: "vm_id", METRIC_RES_TYPE_AGENT: "vm_id", METRIC_RES_TYPE_REDIS: "redis_id", METRIC_RES_TYPE_RDS: "rds_id", METRIC_RES_TYPE_OSS: "oss_id", METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_id", METRIC_RES_TYPE_TENANT: "tenant_id", METRIC_RES_TYPE_DOMAIN: "domain_id", METRIC_RES_TYPE_STORAGE: "storage_id", } AlertReduceFunc = map[string]string{ "avg": "average value", "sum": "Summation", "min": "minimum value", "max": "Maximum", "count": "count value", "last": "Latest value", "median": "median", "diff": "The difference between the latest value and the oldest value. The judgment basis value must be legal", "delta": "The signed difference between the latest value and the oldest value (can be positive or negative)", "percent_diff": "The difference between the new value and the old value,based on the percentage of the old value", } ) func GetMeasurementTagIdKeyByResType(resType string) string { return MEASUREMENT_TAG_ID[resType] } func GetMeasurementTagIdKeyByResTypeWithDefault(resType string) string { tagId := GetMeasurementTagIdKeyByResType(resType) if len(tagId) == 0 { tagId = "host_id" } return tagId } func GetMeasurementResourceId(tags map[string]string, resType string) string { return tags[GetMeasurementTagIdKeyByResType(resType)] } func GetResourceIdFromTagWithDefault(tags map[string]string, resType string) string { tagId := GetMeasurementTagIdKeyByResTypeWithDefault(resType) return tags[tagId] } type MetricFunc struct { FieldOptType []string `json:"field_opt_type"` FieldOptValue map[string][]string `json:"field_opt_value"` GroupOptType []string `json:"group_opt_type"` GroupOptValue map[string][]string `json:"group_opt_value"` } type SimpleQueryInput struct { // 资源Id, 可以不填, 代表查询指定监控的所有监控数据 Id string `json:"id"` // 查询指定数据库 // default: telegraf Database string `json:"database"` // 监控指标: https://github.com/codelinz/cloudpods/blob/monitor/pkg/cloudprovider/metrics.go MetricName string `json:"metric_name"` // 开始时间 StartTime time.Time `json:"start_time"` // 结束时间 EndTime time.Time `json:"end_time"` // 指定标签 Tags map[string]string `json:"tag_pairs"` // 间隔周期 // default: 5m Interval string `json:"interval"` } type CdfQueryInput struct { // 查询指定数据库 // default: telegraf Database string `json:"database"` // 监控指标: https://github.com/codelinz/cloudpods/blob/monitor/pkg/cloudprovider/metrics.go MetricName string `json:"metric_name"` // 查询周期 // exaple: 4h // default: 1h Period string `json:"period"` // 指定标签 Tags map[string]string `json:"tag_pairs"` } type SimpleQueryOutput struct { Id string `json:"id"` Time time.Time `json:"time"` Value float64 `json:"value"` } type MetricsQueryResult struct { SeriesTotal int64 `json:"series_total"` Series TimeSeriesSlice `json:"series"` Metas []QueryResultMeta `json:"metas"` ReducedResult *ReducedResult `json:"reduced_result"` } type TimeSeriesPoints []TimePoint type TimeSeriesSlice []*TimeSeries type TimeSeries struct { // RawName is used to frontend displaying the curve name RawName string `json:"raw_name"` Columns []string `json:"columns"` Name string `json:"name"` Points TimeSeriesPoints `json:"points"` Tags map[string]string `json:"tags,omitempty"` CloudTags map[string]string `json:"cloud_tags,omitempty"` } type TimePoint []interface{} func NewTimePoint(value *float64, timestamp float64) TimePoint { return TimePoint{value, timestamp} } func NewTimePointByVal(value float64, timestamp float64) TimePoint { return NewTimePoint(&value, timestamp) } func (p TimePoint) IsValid() bool { if val, ok := p[0].(*float64); ok && val != nil { return true } return false //return p[0].(*float64) != nil } func (p TimePoint) IsValids() bool { for i := 0; i < len(p)-1; i++ { if p[i] == nil { return false } if p[i].(*float64) == nil { return false } } return true } func (p TimePoint) Value() float64 { v := p[0] if fval, ok := v.(*float64); ok { return *fval } if ival, ok := v.(*int64); ok { return float64(*ival) } if t, ok := v.(float64); ok { return t } if t, ok := v.(int64); ok { return float64(t) } return 0 } func (p TimePoint) Timestamp() float64 { v := p[len(p)-1] if t, ok := v.(float64); ok { return t } if t, ok := v.(int64); ok { return float64(t) } return 0 } func (p TimePoint) Time() time.Time { return time.UnixMilli(int64(p.Timestamp())) } func (p TimePoint) Values() []float64 { values := make([]float64, 0) for i := 0; i < len(p)-1; i++ { values = append(values, *(p[i].(*float64))) } return values } func (p TimePoint) PointValueStr() []string { arrStr := make([]string, 0) for i := 0; i < len(p)-1; i++ { if p[i] == nil { arrStr = append(arrStr, "") } if fval, ok := p[i].(*float64); ok { arrStr = append(arrStr, strconv.FormatFloat((*fval), 'f', -1, 64)) continue } if ival, ok := p[i].(*int64); ok { arrStr = append(arrStr, strconv.FormatInt((*ival), 64)) continue } arrStr = append(arrStr, p[i].(string)) } return arrStr } func NewTimeSeriesPointsFromArgs(values ...float64) TimeSeriesPoints { points := make(TimeSeriesPoints, 0) for i := 0; i < len(values); i += 2 { points = append(points, NewTimePoint(&values[i], values[i+1])) } return points } type QueryResultMeta struct { RawQuery string `json:"raw_query"` ResultReducerValue float64 `json:"result_reducer_value"` } const ConditionTypeMetricQuery = "metricquery" type CdfQueryData struct { Vmrange string `json:"vmrange"` Metric float64 `json:"metric"` Value int `json:"value"` ValueAsc int `json:"value_asc"` ValueDesc int `json:"value_desc"` Total int `json:"total"` } func (c CdfQueryData) Copy() CdfQueryData { return CdfQueryData{ Vmrange: c.Vmrange, Metric: c.Metric, Value: c.Value, ValueAsc: c.ValueAsc, ValueDesc: c.ValueDesc, Total: c.Total, } } func (c CdfQueryData) Start() float64 { s := strings.Split(c.Vmrange, "...")[0] v, _ := strconv.ParseFloat(s, 64) return v } func (c CdfQueryData) End() float64 { info := strings.Split(c.Vmrange, "...") v := 0.0 if len(info) == 2 { v, _ = strconv.ParseFloat(info[1], 64) } return v } type CdfQueryDataSet []CdfQueryData func (c CdfQueryDataSet) Len() int { return len(c) } func (c CdfQueryDataSet) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c CdfQueryDataSet) Less(i, j int) bool { return c[i].Start() < c[j].Start() } type CdfQueryOutput struct { Data CdfQueryDataSet `json:"data"` } // ResourceMetricsQueryInput 批量查询资源监控数据的输入参数 type ResourceMetricsQueryInput struct { // 资源类型: "host" 或 "guest" ResType string `json:"res_type"` // 资源 ID 列表 ResIds []string `json:"res_ids"` // 查询开始时间(默认: 1小时前) StartTime time.Time `json:"start_time"` // 查询结束时间(默认: now) EndTime time.Time `json:"end_time"` // 查询间隔(默认: 5m) Interval string `json:"interval"` } // ResourceMetricValues 单个资源的监控数据 type ResourceMetricValues struct { // CPU 使用率 (%) CpuUsage *float64 `json:"cpu_usage"` // 内存使用率 (%) MemUsage *float64 `json:"mem_usage"` // 磁盘使用率 (%) DiskUsage *float64 `json:"disk_usage"` // 磁盘读速率 (Bps) DiskReadRate *float64 `json:"disk_read_rate"` // 磁盘写速率 (Bps) DiskWriteRate *float64 `json:"disk_write_rate"` // 网络入流量 (bps) NetInRate *float64 `json:"net_in_rate"` // 网络出流量 (bps) NetOutRate *float64 `json:"net_out_rate"` // 告警状态: init/attach/alerting AlertState string `json:"alert_state"` } // ResourceMetricsQueryOutput 批量查询资源监控数据的输出 type ResourceMetricsQueryOutput struct { ResourceMetrics map[string]ResourceMetricValues `json:"resource_metrics"` }