github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/query/metricsquery.go (about) 1 /* 2 Copyright 2023. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package query 18 19 import ( 20 "time" 21 22 "github.com/cespare/xxhash" 23 dtu "github.com/siglens/siglens/pkg/common/dtypeutils" 24 "github.com/siglens/siglens/pkg/config" 25 "github.com/siglens/siglens/pkg/segment/query/metadata" 26 "github.com/siglens/siglens/pkg/segment/query/summary" 27 "github.com/siglens/siglens/pkg/segment/reader/metrics/tagstree" 28 "github.com/siglens/siglens/pkg/segment/results/mresults" 29 "github.com/siglens/siglens/pkg/segment/search" 30 "github.com/siglens/siglens/pkg/segment/structs" 31 "github.com/siglens/siglens/pkg/segment/utils" 32 "github.com/siglens/siglens/pkg/segment/writer/metrics" 33 log "github.com/sirupsen/logrus" 34 ) 35 36 func ApplyMetricsQuery(mQuery *structs.MetricsQuery, timeRange *dtu.MetricsTimeRange, qid uint64, querySummary *summary.QuerySummary) *mresults.MetricsResult { 37 38 // init metrics results structs 39 mRes := mresults.InitMetricResults(mQuery, qid) 40 41 // get all metrics segments that pass the initial time + metric name filter 42 mSegments, err := metadata.GetMetricsSegmentRequests(mQuery.MetricName, timeRange, querySummary, mQuery.OrgId) 43 if err != nil { 44 log.Errorf("ApplyMetricsQuery: failed to get rotated metric segments: %v", err) 45 return &mresults.MetricsResult{ 46 ErrList: []error{err}, 47 } 48 } 49 50 unrotatedMSegments, err := metrics.GetUnrotatedMetricsSegmentRequests(mQuery.MetricName, timeRange, querySummary, mQuery.OrgId) 51 if err != nil { 52 log.Errorf("ApplyMetricsQuery: failed to get unrotated metric segments: %v", err) 53 return &mresults.MetricsResult{ 54 ErrList: []error{err}, 55 } 56 } 57 58 mSegments = mergeRotatedAndUnrotatedRequests(unrotatedMSegments, mSegments) 59 allTagKeys := make(map[string]bool) 60 61 for _, allMSearchReqs := range mSegments { 62 for _, mSeg := range allMSearchReqs { 63 for tk := range mSeg.AllTagKeys { 64 allTagKeys[tk] = true 65 } 66 } 67 } 68 69 if mQuery.SelectAllSeries { 70 for _, v := range mQuery.TagsFilters { 71 delete(allTagKeys, v.TagKey) 72 } 73 for tkey, present := range allTagKeys { 74 if present { 75 mQuery.TagsFilters = append(mQuery.TagsFilters, &structs.TagsFilter{ 76 TagKey: tkey, 77 RawTagValue: tagstree.STAR, 78 HashTagValue: xxhash.Sum64String(tagstree.STAR), 79 LogicalOperator: utils.And, 80 TagOperator: utils.Equal, 81 }) 82 } 83 } 84 } 85 mQuery.ReorderTagFilters() 86 87 // iterate through all metrics segments, applying search as needed 88 applyMetricsOperatorOnSegments(mQuery, mSegments, mRes, timeRange, qid, querySummary) 89 parallelism := int(config.GetParallelism()) * 2 90 errors := mRes.DownsampleResults(mQuery.Downsampler, parallelism) 91 if errors != nil { 92 for _, err := range errors { 93 mRes.AddError(err) 94 } 95 96 return mRes 97 } 98 99 errors = mRes.AggregateResults(parallelism) 100 if errors != nil { 101 for _, err := range errors { 102 mRes.AddError(err) 103 } 104 105 return mRes 106 } 107 108 err = mRes.ApplyRangeFunctionsToResults(parallelism, mQuery.Aggregator.RangeFunction) 109 if err != nil { 110 mRes.AddError(err) 111 } 112 113 return mRes 114 } 115 116 func mergeRotatedAndUnrotatedRequests(unrotatedMSegments map[string][]*structs.MetricsSearchRequest, mSegments map[string][]*structs.MetricsSearchRequest) map[string][]*structs.MetricsSearchRequest { 117 for k, v := range unrotatedMSegments { 118 if _, ok := mSegments[k]; ok { 119 mSegments[k] = append(mSegments[k], v...) 120 } else { 121 mSegments[k] = v 122 } 123 } 124 return mSegments 125 } 126 127 func applyMetricsOperatorOnSegments(mQuery *structs.MetricsQuery, allSearchReqests map[string][]*structs.MetricsSearchRequest, 128 mRes *mresults.MetricsResult, timeRange *dtu.MetricsTimeRange, qid uint64, querySummary *summary.QuerySummary) { 129 // for each metrics segment, apply a single metrics segment search 130 // var tsidInfo *tsidtracker.AllMatchedTSIDs 131 132 for baseDir, allMSearchReqs := range allSearchReqests { 133 attr, err := tagstree.InitAllTagsTreeReader(baseDir) 134 if err != nil { 135 mRes.AddError(err) 136 continue 137 } 138 sTime := time.Now() 139 140 tsidInfo, err := attr.FindTSIDS(mQuery) 141 querySummary.UpdateTimeSearchingTagsTrees(time.Since(sTime)) 142 querySummary.IncrementNumTagsTreesSearched(1) 143 if err != nil { 144 mRes.AddError(err) 145 continue 146 } 147 querySummary.IncrementNumTSIDsMatched(uint64(tsidInfo.GetNumMatchedTSIDs())) 148 for _, mSeg := range allMSearchReqs { 149 search.RawSearchMetricsSegment(mQuery, tsidInfo, mSeg, mRes, timeRange, qid, querySummary) 150 } 151 } 152 }