@@ -14,7 +14,7 @@ import (
14
14
"github.com/cortexproject/cortex/pkg/util/validation"
15
15
)
16
16
17
- const QueryRejectErrorMessage = "This query has been rejected by the service operator."
17
+ const QueryRejectErrorMessage = "This query has been rejected by the service operator due to its high load on the service and impact to performance of other queries ."
18
18
19
19
func rejectQueryOrSetPriority (r * http.Request , now time.Time , lookbackDelta time.Duration , limits Limits , userStr string , rejectedQueriesPerTenant * prometheus.CounterVec ) error {
20
20
if limits == nil || ! (limits .QueryPriority (userStr ).Enabled || limits .QueryRejection (userStr ).Enabled ) {
@@ -86,89 +86,120 @@ func getOperation(r *http.Request) string {
86
86
}
87
87
88
88
func matchAttributeForExpressionQuery (attribute validation.QueryAttribute , op string , r * http.Request , query string , now time.Time , minTime , maxTime int64 ) bool {
89
- if attribute .ApiType != "" && attribute .ApiType != op {
90
- return false
89
+ matched := false
90
+ if attribute .ApiType != "" {
91
+ matched = true
92
+ if attribute .ApiType != op {
93
+ return false
94
+ }
91
95
}
92
- if attribute .Regex != "" && attribute .Regex != ".*" && attribute .Regex != ".+" {
93
- if attribute .CompiledRegex != nil && ! attribute .CompiledRegex .MatchString (query ) {
96
+ if attribute .Regex != "" {
97
+ matched = true
98
+ if attribute .Regex != ".*" && attribute .Regex != ".+" && attribute .CompiledRegex != nil && ! attribute .CompiledRegex .MatchString (query ) {
94
99
return false
95
100
}
96
101
}
97
102
98
- if ! isWithinTimeAttributes (attribute .TimeWindow , now , minTime , maxTime ) {
99
- return false
103
+ if attribute .TimeWindow .Start != 0 || attribute .TimeWindow .End != 0 {
104
+ matched = true
105
+ if ! isWithinTimeAttributes (attribute .TimeWindow , now , minTime , maxTime ) {
106
+ return false
107
+ }
100
108
}
101
109
102
- if ! isWithinTimeRangeAttribute (attribute .TimeRangeLimit , minTime , maxTime ) {
103
- return false
110
+ if attribute .TimeRangeLimit .Min != 0 || attribute .TimeRangeLimit .Max != 0 {
111
+ matched = true
112
+ if ! isWithinTimeRangeAttribute (attribute .TimeRangeLimit , minTime , maxTime ) {
113
+ return false
114
+ }
104
115
}
105
116
106
- if op == "query_range" && ! isWithinQueryStepLimit (attribute .QueryStepLimit , r ) {
107
- return false
117
+ if op == "query_range" && (attribute .QueryStepLimit .Min != 0 || attribute .QueryStepLimit .Max != 0 ) {
118
+ matched = true
119
+ if ! isWithinQueryStepLimit (attribute .QueryStepLimit , r ) {
120
+ return false
121
+ }
108
122
}
109
123
110
- if attribute .UserAgentRegex != "" && attribute .UserAgentRegex != ".*" && attribute .CompiledUserAgentRegex != nil {
111
- if ! attribute .CompiledUserAgentRegex .MatchString (r .Header .Get ("User-Agent" )) {
124
+ if attribute .UserAgentRegex != "" {
125
+ matched = true
126
+ if attribute .UserAgentRegex != ".*" && attribute .CompiledUserAgentRegex != nil && ! attribute .CompiledUserAgentRegex .MatchString (r .Header .Get ("User-Agent" )) {
112
127
return false
113
128
}
114
129
}
115
130
116
- if attribute .DashboardUID != "" && attribute .DashboardUID != r .Header .Get ("X-Dashboard-Uid" ) {
117
- return false
131
+ if attribute .DashboardUID != "" {
132
+ matched = true
133
+ if attribute .DashboardUID != r .Header .Get ("X-Dashboard-Uid" ) {
134
+ return false
135
+ }
118
136
}
119
137
120
- if attribute .PanelID != "" && attribute .PanelID != r .Header .Get ("X-Panel-Id" ) {
121
- return false
138
+ if attribute .PanelID != "" {
139
+ matched = true
140
+ if attribute .PanelID != r .Header .Get ("X-Panel-Id" ) {
141
+ return false
142
+ }
122
143
}
123
144
124
- return true
145
+ return matched
125
146
}
126
147
127
148
func matchAttributeForMetadataQuery (attribute validation.QueryAttribute , op string , r * http.Request , now time.Time ) bool {
128
- if attribute .ApiType != "" && attribute .ApiType != op {
129
- return false
149
+ matched := false
150
+ if attribute .ApiType != "" {
151
+ matched = true
152
+ if attribute .ApiType != op {
153
+ return false
154
+ }
130
155
}
131
156
if err := r .ParseForm (); err != nil {
132
157
return false
133
158
}
134
- if attribute .Regex != "" && attribute .Regex != ".*" && attribute .CompiledRegex != nil {
135
- atLeastOneMatched := false
136
- for _ , matcher := range r .Form ["match[]" ] {
137
- if attribute .CompiledRegex .MatchString (matcher ) {
138
- atLeastOneMatched = true
139
- break
159
+ if attribute .Regex != "" {
160
+ matched = true
161
+ if attribute .Regex != ".*" && attribute .CompiledRegex != nil {
162
+ atLeastOneMatched := false
163
+ for _ , matcher := range r .Form ["match[]" ] {
164
+ if attribute .CompiledRegex .MatchString (matcher ) {
165
+ atLeastOneMatched = true
166
+ break
167
+ }
168
+ }
169
+ if ! atLeastOneMatched {
170
+ return false
140
171
}
141
- }
142
- if ! atLeastOneMatched {
143
- return false
144
172
}
145
173
}
146
174
147
175
startTime , _ := util .ParseTime (r .FormValue ("start" ))
148
176
endTime , _ := util .ParseTime (r .FormValue ("end" ))
149
177
150
- if ! isWithinTimeAttributes (attribute .TimeWindow , now , startTime , endTime ) {
151
- return false
178
+ if attribute .TimeWindow .Start != 0 || attribute .TimeWindow .End != 0 {
179
+ matched = true
180
+ if ! isWithinTimeAttributes (attribute .TimeWindow , now , startTime , endTime ) {
181
+ return false
182
+ }
152
183
}
153
184
154
- if ! isWithinTimeRangeAttribute (attribute .TimeRangeLimit , startTime , endTime ) {
155
- return false
185
+ if attribute .TimeRangeLimit .Min != 0 || attribute .TimeRangeLimit .Max != 0 {
186
+ matched = true
187
+ if ! isWithinTimeRangeAttribute (attribute .TimeRangeLimit , startTime , endTime ) {
188
+ return false
189
+ }
156
190
}
157
191
158
- if attribute .UserAgentRegex != "" && attribute .UserAgentRegex != ".*" && attribute .CompiledUserAgentRegex != nil {
159
- if ! attribute .CompiledUserAgentRegex .MatchString (r .Header .Get ("User-Agent" )) {
192
+ if attribute .UserAgentRegex != "" {
193
+ matched = true
194
+ if attribute .UserAgentRegex != ".*" && attribute .CompiledUserAgentRegex != nil && ! attribute .CompiledUserAgentRegex .MatchString (r .Header .Get ("User-Agent" )) {
160
195
return false
161
196
}
162
197
}
163
198
164
- return true
199
+ return matched
165
200
}
166
201
167
202
func isWithinTimeAttributes (timeWindow validation.TimeWindow , now time.Time , startTime , endTime int64 ) bool {
168
- if timeWindow .Start == 0 && timeWindow .End == 0 {
169
- return true
170
- }
171
-
172
203
if timeWindow .Start != 0 {
173
204
startTimeThreshold := now .Add (- 1 * time .Duration (timeWindow .Start ).Abs ()).Add (- 1 * time .Minute ).Truncate (time .Minute ).UnixMilli ()
174
205
if startTime == 0 || startTime < startTimeThreshold {
@@ -187,9 +218,6 @@ func isWithinTimeAttributes(timeWindow validation.TimeWindow, now time.Time, sta
187
218
}
188
219
189
220
func isWithinTimeRangeAttribute (limit validation.TimeRangeLimit , startTime , endTime int64 ) bool {
190
- if limit .Min == 0 && limit .Max == 0 {
191
- return true
192
- }
193
221
194
222
if startTime == 0 || endTime == 0 {
195
223
return false
@@ -208,9 +236,6 @@ func isWithinTimeRangeAttribute(limit validation.TimeRangeLimit, startTime, endT
208
236
}
209
237
210
238
func isWithinQueryStepLimit (queryStepLimit validation.QueryStepLimit , r * http.Request ) bool {
211
- if queryStepLimit .Min == 0 && queryStepLimit .Max == 0 {
212
- return true
213
- }
214
239
215
240
step , err := util .ParseDurationMs (r .FormValue ("step" ))
216
241
if err != nil {
0 commit comments