diff --git a/docs/content.en/docs/release-notes/_index.md b/docs/content.en/docs/release-notes/_index.md index 49a07c9d..53790b3f 100644 --- a/docs/content.en/docs/release-notes/_index.md +++ b/docs/content.en/docs/release-notes/_index.md @@ -17,6 +17,7 @@ Information about release notes of INFINI Console is provided here. ### Bug fix - Fixed query thread pool metrics when cluster uuid is empty +- Fixed unit tests ### Improvements - Optimize UI of agent list when its columns are overflow. diff --git a/model/alerting/rule_test.go b/model/alerting/rule_test.go index f885f51f..a4e6fe47 100644 --- a/model/alerting/rule_test.go +++ b/model/alerting/rule_test.go @@ -102,7 +102,7 @@ func TestCreateRule( t *testing.T) { }, }, - Channels: NotificationConfig{ + Channels: &NotificationConfig{ Normal: []Channel{ {Name: "钉钉", Type: ChannelWebhook, Webhook: &CustomWebhook{ HeaderParams: map[string]string{ diff --git a/modules/elastic/api/metrics_util_test.go b/modules/elastic/api/metrics_util_test.go index d7d4db15..ee60c8d9 100644 --- a/modules/elastic/api/metrics_util_test.go +++ b/modules/elastic/api/metrics_util_test.go @@ -34,8 +34,11 @@ import ( func TestGetMetricParams(t *testing.T) { handler:=APIHandler{} - req:=http.Request{} - bucketSize, min, max, err:=handler.getMetricRangeAndBucketSize(&req,60,15) + req, err :=http.NewRequest("GET","https://infinilabs.com/api/?bucket_size=1m",nil) + if err != nil { + t.Fatal(err) + } + bucketSize, min, max, err:=handler.GetMetricRangeAndBucketSize(req,"", "",15) fmt.Println(bucketSize) fmt.Println(util.FormatUnixTimestamp(min/1000))//2022-01-27 15:28:57 diff --git a/modules/elastic/api/v1/metrics_util_test.go b/modules/elastic/api/v1/metrics_util_test.go deleted file mode 100644 index e7f04607..00000000 --- a/modules/elastic/api/v1/metrics_util_test.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) INFINI Labs & INFINI LIMITED. -// -// The INFINI Console is offered under the GNU Affero General Public License v3.0 -// and as commercial software. -// -// For commercial licensing, contact us at: -// - Website: infinilabs.com -// - Email: hello@infini.ltd -// -// Open Source licensed under AGPL V3: -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package v1 - -import ( - "fmt" - "infini.sh/framework/core/util" - "infini.sh/framework/modules/elastic/common" - "net/http" - "testing" - "time" -) - -func TestGetMetricParams(t *testing.T) { - handler:=APIHandler{} - req:=http.Request{} - bucketSize, min, max, err:=handler.getMetricRangeAndBucketSize(&req,60,15) - - fmt.Println(bucketSize) - fmt.Println(util.FormatUnixTimestamp(min/1000))//2022-01-27 15:28:57 - fmt.Println(util.FormatUnixTimestamp(max/1000))//2022-01-27 15:28:57 - fmt.Println(time.Now())//2022-01-27 15:28:57 - - fmt.Println(bucketSize, min, max, err) -} - -func TestConvertBucketItemsToAggQueryParams(t *testing.T) { - bucketItem:=common.BucketItem{} - bucketItem.Key="key1" - bucketItem.Type=common.TermsBucket - bucketItem.Parameters=map[string]interface{}{} - bucketItem.Parameters["field"]="metadata.labels.cluster_id" - bucketItem.Parameters["size"]=2 - - - nestBucket:=common.BucketItem{} - nestBucket.Key="key2" - nestBucket.Type=common.DateHistogramBucket - nestBucket.Parameters=map[string]interface{}{} - nestBucket.Parameters["field"]="timestamp" - nestBucket.Parameters["calendar_interval"]="1d" - nestBucket.Parameters["time_zone"]="+08:00" - - leafBucket:=common.NewBucketItem(common.TermsBucket,util.MapStr{ - "size":5, - "field":"payload.elasticsearch.cluster_health.status", - }) - - leafBucket.Key="key3" - - metricItems:=[]*common.MetricItem{} - var bucketSizeStr ="10s" - metricItem:=newMetricItem("cluster_summary", 2, "cluster") - metricItem.Key="key4" - metricItem.AddLine("Indexing","Total Indexing","Number of documents being indexed for primary and replica shards.","group1", - "payload.elasticsearch.index_stats.total.indexing.index_total","max",bucketSizeStr,"doc/s","num","0,0.[00]","0,0.[00]",false,true) - metricItem.AddLine("Search","Total Search","Number of search requests being executed across primary and replica shards. A single search can run against multiple shards!","group1", - "payload.elasticsearch.index_stats.total.search.query_total","max",bucketSizeStr,"query/s","num","0,0.[00]","0,0.[00]",false,true) - metricItems=append(metricItems,metricItem) - - nestBucket.AddNestBucket(leafBucket) - nestBucket.Metrics=metricItems - - bucketItem.Buckets=[]*common.BucketItem{} - bucketItem.Buckets=append(bucketItem.Buckets,&nestBucket) - - - aggs:=ConvertBucketItemsToAggQuery([]*common.BucketItem{&bucketItem},nil) - fmt.Println(util.MustToJSON(aggs)) - - response:="{ \"took\": 37, \"timed_out\": false, \"_shards\": { \"total\": 1, \"successful\": 1, \"skipped\": 0, \"failed\": 0 }, \"hits\": { \"total\": { \"value\": 10000, \"relation\": \"gte\" }, \"max_score\": null, \"hits\": [] }, \"aggregations\": { \"key1\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"c7pqhptj69a0sg3rn05g\", \"doc_count\": 80482, \"key2\": { \"buckets\": [ { \"key_as_string\": \"2022-01-28T00:00:00.000+08:00\", \"key\": 1643299200000, \"doc_count\": 14310, \"c7qi5hii4h935v9bs91g\": { \"value\": 15680 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 2985 } }, { \"key_as_string\": \"2022-01-29T00:00:00.000+08:00\", \"key\": 1643385600000, \"doc_count\": 66172, \"c7qi5hii4h935v9bs91g\": { \"value\": 106206 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 20204 }, \"c7qi5hii4h935v9bs91g_deriv\": { \"value\": 90526 }, \"c7qi5hii4h935v9bs920_deriv\": { \"value\": 17219 } } ] } }, { \"key\": \"c7qi42ai4h92sksk979g\", \"doc_count\": 660, \"key2\": { \"buckets\": [ { \"key_as_string\": \"2022-01-29T00:00:00.000+08:00\", \"key\": 1643385600000, \"doc_count\": 660, \"c7qi5hii4h935v9bs91g\": { \"value\": 106206 }, \"key3\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [] }, \"c7qi5hii4h935v9bs920\": { \"value\": 20204 } } ] } } ] } } }" - res:=SearchResponse{} - util.FromJSONBytes([]byte(response),&res) - fmt.Println(response) - groupKey:="key1" - metricLabelKey:="key2" - metricValueKey:="c7qi5hii4h935v9bs920" - data:=ParseAggregationResult(int(10),res.Aggregations,groupKey,metricLabelKey,metricValueKey) - fmt.Println(data) - -} - -func TestConvertBucketItems(t *testing.T) { - response:="{ \"took\": 8, \"timed_out\": false, \"_shards\": { \"total\": 1, \"successful\": 1, \"skipped\": 0, \"failed\": 0 }, \"hits\": { \"total\": { \"value\": 81, \"relation\": \"eq\" }, \"max_score\": null, \"hits\": [] }, \"aggregations\": { \"c7v2gm3i7638vvo4pv80\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"c7uv7p3i76360kgdmpb0\", \"doc_count\": 81, \"c7v2gm3i7638vvo4pv8g\": { \"buckets\": [ { \"key_as_string\": \"2022-02-05T00:00:00.000+08:00\", \"key\": 1643990400000, \"doc_count\": 81, \"c7v2gm3i7638vvo4pv90\": { \"doc_count_error_upper_bound\": 0, \"sum_other_doc_count\": 0, \"buckets\": [ { \"key\": \"yellow\", \"doc_count\": 81 } ] } } ] } } ] } } }" - res:=SearchResponse{} - util.FromJSONBytes([]byte(response),&res) - - data:=ParseAggregationBucketResult(int(10),res.Aggregations,"c7v2gm3i7638vvo4pv80","c7v2gm3i7638vvo4pv8g","c7v2gm3i7638vvo4pv90", func() { - - }) - - fmt.Println(data) - -} diff --git a/service/alerting/elasticsearch/engine_test.go b/service/alerting/elasticsearch/engine_test.go index 30736387..09d4c9b7 100644 --- a/service/alerting/elasticsearch/engine_test.go +++ b/service/alerting/elasticsearch/engine_test.go @@ -30,7 +30,10 @@ package elasticsearch import ( "fmt" "infini.sh/console/model/alerting" + "infini.sh/console/model/insight" + "infini.sh/framework/core/elastic" "infini.sh/framework/core/util" + "infini.sh/framework/modules/elastic/adapter/elasticsearch" "net/http" "sort" "testing" @@ -77,12 +80,15 @@ func TestEngine( t *testing.T) { }, Metrics: alerting.Metric{ - PeriodInterval: "1m", - Items: []alerting.MetricItem{ - {Name: "a", Field: "payload.elasticsearch.node_stats.fs.total.free_in_bytes", Statistic: "min", Group: []string{"metadata.labels.cluster_id", "metadata.labels.node_id"}}, - {Name: "b", Field: "payload.elasticsearch.node_stats.fs.total.total_in_bytes", Statistic: "max", Group: []string{"metadata.labels.cluster_id", "metadata.labels.node_id"}}, + Metric: insight.Metric{ + BucketSize: "1m", + Items: []insight.MetricItem{ + {Name: "a", Field: "payload.elasticsearch.node_stats.fs.total.free_in_bytes", Statistic: "min"}, + {Name: "b", Field: "payload.elasticsearch.node_stats.fs.total.total_in_bytes", Statistic: "max"}, + }, + Formula: "a/b*100", }, - Formula: "a/b*100", + //Expression: "min(fs.free_in_bytes)/max(fs.total_in_bytes)*100", }, Conditions: alerting.Condition{ @@ -93,7 +99,7 @@ func TestEngine( t *testing.T) { }, }, - Channels: alerting.NotificationConfig{ + Channels: &alerting.NotificationConfig{ Normal: []alerting.Channel{ {Name: "钉钉", Type: alerting.ChannelWebhook, Webhook: &alerting.CustomWebhook{ HeaderParams: map[string]string{ @@ -139,7 +145,7 @@ func TestEngine( t *testing.T) { func TestGenerateAgg(t *testing.T) { eng := &Engine{} - agg := eng.generateAgg(&alerting.MetricItem{ + agg := eng.generateAgg(&insight.MetricItem{ Name: "a", Field: "cpu.percent", Statistic: "p99", @@ -199,13 +205,23 @@ func TestGeneratePercentilesAggQuery(t *testing.T) { // EscalationThrottlePeriod: "30m", // }, //} + cfg := elastic.ElasticsearchConfig{} + cfg.ID = "test" + esClient := elasticsearch.ESAPIV7{} + esClient.Elasticsearch = cfg.ID + esClient.Version = elastic.Version{ + Number: "7.10.2", + Major: 7, + Distribution: elastic.Elasticsearch, + } + elastic.UpdateClient(cfg, &esClient) rule := alerting.Rule{ ID: util.GetUUID(), Created: time.Now(), Updated: time.Now(), Enabled: true, Resource: alerting.Resource{ - ID: "c8i18llath2blrusdjng", + ID: cfg.ID, Type: "elasticsearch", Objects: []string{".infini_metrics*"}, TimeField: "timestamp", @@ -225,12 +241,14 @@ func TestGeneratePercentilesAggQuery(t *testing.T) { }, Metrics: alerting.Metric{ - PeriodInterval: "1m", - Items: []alerting.MetricItem{ - {Name: "a", Field: "payload.elasticsearch.index_stats.total.search.query_total", Statistic: "rate", Group: []string{"metadata.labels.cluster_id"}}, - {Name: "b", Field: "payload.elasticsearch.index_stats.total.search.query_time_in_millis", Statistic: "rate", Group: []string{"metadata.labels.cluster_id"}}, + Metric: insight.Metric{ + BucketSize: "1m", + Items: []insight.MetricItem{ + {Name: "a", Field: "payload.elasticsearch.index_stats.total.search.query_total", Statistic: "rate"}, + {Name: "b", Field: "payload.elasticsearch.index_stats.total.search.query_time_in_millis", Statistic: "rate"}, + }, + Formula: "b/a", }, - Formula: "b/a", }, Conditions: alerting.Condition{ Operator: "any", @@ -239,7 +257,7 @@ func TestGeneratePercentilesAggQuery(t *testing.T) { }, }, - Channels: alerting.NotificationConfig{ + Channels: &alerting.NotificationConfig{ Normal: []alerting.Channel{ {Name: "钉钉", Type: alerting.ChannelWebhook, Webhook: &alerting.CustomWebhook{ HeaderParams: map[string]string{