Skip to content

Commit 951934b

Browse files
committed
doc
Signed-off-by: alanprot <[email protected]>
1 parent baf99ee commit 951934b

File tree

6 files changed

+57
-41
lines changed

6 files changed

+57
-41
lines changed

docs/configuration/config-file-reference.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,6 +3168,10 @@ The `limits_config` configures default and per-tenant limits imposed by Cortex s
31683168
# CLI flag: -ingester.max-global-series-per-metric
31693169
[max_global_series_per_metric: <int> | default = 0]
31703170
3171+
# [Experimental] The maximum number of active series per LabelSet, across the
3172+
# cluster before replication. Empty list to disable.
3173+
[max_series_per_label_set: <list of MaxSeriesPerLabelSet> | default = []]
3174+
31713175
# The maximum number of active metrics with metadata per user, per ingester. 0
31723176
# to disable.
31733177
# CLI flag: -ingester.max-metadata-per-user
@@ -4009,7 +4013,7 @@ The `ruler_config` configures the Cortex ruler.
40094013
[external_url: <url> | default = ]
40104014
40114015
# Labels to add to all alerts.
4012-
[external_labels: <list of Label> | default = []]
4016+
[external_labels: <map of string (labelName) to string (labelValue)> | default = []]
40134017
40144018
ruler_client:
40154019
# gRPC client max receive message size (bytes).
@@ -5306,6 +5310,16 @@ otel:
53065310
[tls_insecure_skip_verify: <boolean> | default = false]
53075311
```
53085312
5313+
### `MaxSeriesPerLabelSet`
5314+
5315+
```yaml
5316+
# The maximum number of active series per LabelSet before replication.
5317+
[limit: <int> | default = ]
5318+
5319+
# LabelSet which the limit should be applied.
5320+
[label_set: <map of string (labelName) to string (labelValue)> | default = []]
5321+
```
5322+
53095323
### `PriorityDef`
53105324

53115325
```yaml
@@ -5350,11 +5364,3 @@ time_window:
53505364
# name of the rule group
53515365
[name: <string> | default = ""]
53525366
```
5353-
5354-
### `Label`
5355-
5356-
```yaml
5357-
[name: <string> | default = ""]
5358-
5359-
[value: <string> | default = ""]
5360-
```

pkg/ingester/ingester_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
8484

8585
limits.MaxSeriesPerLabelSet = []validation.MaxSeriesPerLabelSet{
8686
{
87-
LabelSet: map[string]string{
87+
LabelSet: labels.FromMap(map[string]string{
8888
"label1": "value1",
89-
},
89+
}),
9090
Limit: 3,
9191
},
9292
{
93-
LabelSet: map[string]string{
93+
LabelSet: labels.FromMap(map[string]string{
9494
"label2": "value2",
95-
},
95+
}),
9696
Limit: 2,
9797
},
9898
}
@@ -122,8 +122,8 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
122122
// Create first series within the limits
123123
for _, set := range limits.MaxSeriesPerLabelSet {
124124
lbls := []string{labels.MetricName, "metric_name"}
125-
for k, v := range set.LabelSet {
126-
lbls = append(lbls, k, v)
125+
for _, lbl := range set.LabelSet {
126+
lbls = append(lbls, lbl.Name, lbl.Value)
127127
}
128128
for i := 0; i < set.Limit; i++ {
129129
_, err = ing.Push(ctx, cortexpb.ToWriteRequest(
@@ -143,8 +143,8 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
143143
// Should impose limits
144144
for _, set := range limits.MaxSeriesPerLabelSet {
145145
lbls := []string{labels.MetricName, "metric_name"}
146-
for k, v := range set.LabelSet {
147-
lbls = append(lbls, k, v)
146+
for _, lbl := range set.LabelSet {
147+
lbls = append(lbls, lbl.Name, lbl.Value)
148148
}
149149
_, err = ing.Push(ctx, cortexpb.ToWriteRequest(
150150
[]labels.Labels{labels.FromStrings(append(lbls, "newLabel", "newValue")...)}, samples, nil, nil, cortexpb.API))
@@ -164,20 +164,20 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
164164

165165
// Should apply composite limits
166166
limits.MaxSeriesPerLabelSet = append(limits.MaxSeriesPerLabelSet,
167-
validation.MaxSeriesPerLabelSet{LabelSet: map[string]string{
167+
validation.MaxSeriesPerLabelSet{LabelSet: labels.FromMap(map[string]string{
168168
"comp1": "compValue1",
169-
},
169+
}),
170170
Limit: 10,
171171
},
172-
validation.MaxSeriesPerLabelSet{LabelSet: map[string]string{
172+
validation.MaxSeriesPerLabelSet{LabelSet: labels.FromMap(map[string]string{
173173
"comp2": "compValue2",
174-
},
174+
}),
175175
Limit: 10,
176176
},
177-
validation.MaxSeriesPerLabelSet{LabelSet: map[string]string{
177+
validation.MaxSeriesPerLabelSet{LabelSet: labels.FromMap(map[string]string{
178178
"comp1": "compValue1",
179179
"comp2": "compValue2",
180-
},
180+
}),
181181
Limit: 2,
182182
},
183183
)
@@ -224,10 +224,10 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
224224

225225
// Should bootstrap and apply limits when configuration change
226226
limits.MaxSeriesPerLabelSet = append(limits.MaxSeriesPerLabelSet,
227-
validation.MaxSeriesPerLabelSet{LabelSet: map[string]string{
227+
validation.MaxSeriesPerLabelSet{LabelSet: labels.FromMap(map[string]string{
228228
labels.MetricName: "metric_name",
229229
"comp2": "compValue2",
230-
},
230+
}),
231231
Limit: 3, // we already have 2 so we need to allow 1 more
232232
},
233233
)

pkg/ingester/limiter.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,18 @@ func (l *Limiter) formatMaxSeriesPerLabelSetError(err errMaxSeriesPerLabelSetLim
189189

190190
func (l *Limiter) maxSeriesPerLabelSet(userID string, metric labels.Labels) []validation.MaxSeriesPerLabelSet {
191191
m := l.limits.MaxSeriesPerLabelSet(userID)
192+
193+
// returning early to not have any overhead
194+
if len(m) == 0 {
195+
return nil
196+
}
197+
192198
r := make([]validation.MaxSeriesPerLabelSet, 0, len(m))
193199
outer:
194200
for _, lbls := range m {
195-
for name, value := range lbls.LabelSet {
201+
for _, lbl := range lbls.LabelSet {
196202
// We did not find some of the labels on the set
197-
if v := metric.Get(name); v != value {
203+
if v := metric.Get(lbl.Name); v != lbl.Value {
198204
continue outer
199205
}
200206
}

pkg/ingester/user_state.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ func (m *labelSetCounter) canAddSeriesForLabelSet(ctx context.Context, u *userTS
136136
defer s.Unlock()
137137
if r, ok := s.valuesCounter[set.Hash]; !ok {
138138
postings := make([]index.Postings, 0, len(set.LabelSet))
139-
for k, v := range set.LabelSet {
140-
p, err := ir.Postings(ctx, k, v)
139+
for _, lbl := range set.LabelSet {
140+
p, err := ir.Postings(ctx, lbl.Name, lbl.Value)
141141
if err != nil {
142142
return 0, err
143143
}
@@ -157,7 +157,7 @@ func (m *labelSetCounter) canAddSeriesForLabelSet(ctx context.Context, u *userTS
157157

158158
s.valuesCounter[set.Hash] = &labelSetCounterEntry{
159159
count: totalCount,
160-
labels: labels.FromMap(set.LabelSet),
160+
labels: set.LabelSet,
161161
}
162162
return totalCount, nil
163163
} else {
@@ -176,7 +176,7 @@ func (m *labelSetCounter) increaseSeriesLabelSet(u *userTSDB, metric labels.Labe
176176
} else {
177177
s.valuesCounter[l.Hash] = &labelSetCounterEntry{
178178
count: 1,
179-
labels: labels.FromMap(l.LabelSet),
179+
labels: l.LabelSet,
180180
}
181181
}
182182
s.Unlock()

pkg/util/validation/limits.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ type TimeWindow struct {
7777
}
7878

7979
type MaxSeriesPerLabelSet struct {
80-
Limit int `yaml:"limit" json:"limit" doc:"nocli"`
81-
LabelSet map[string]string `yaml:"label_set" json:"label_set" doc:"nocli"`
82-
Id string `yaml:"-" json:"-" doc:"nocli"`
83-
Hash uint64 `yaml:"-" json:"-" doc:"nocli"`
80+
Limit int `yaml:"limit" json:"limit" doc:"nocli|description=The maximum number of active series per LabelSet before replication."`
81+
LabelSet labels.Labels `yaml:"label_set" json:"label_set" doc:"nocli|description=LabelSet which the limit should be applied."`
82+
Id string `yaml:"-" json:"-" doc:"nocli"`
83+
Hash uint64 `yaml:"-" json:"-" doc:"nocli"`
8484
}
8585

8686
// Limits describe all the limits for users; can be used to describe global default
@@ -115,7 +115,7 @@ type Limits struct {
115115
MaxLocalSeriesPerMetric int `yaml:"max_series_per_metric" json:"max_series_per_metric"`
116116
MaxGlobalSeriesPerUser int `yaml:"max_global_series_per_user" json:"max_global_series_per_user"`
117117
MaxGlobalSeriesPerMetric int `yaml:"max_global_series_per_metric" json:"max_global_series_per_metric"`
118-
MaxSeriesPerLabelSet []MaxSeriesPerLabelSet `yaml:"max_series_per_label_set" json:"max_series_per_label_set" doc:"hidden"`
118+
MaxSeriesPerLabelSet []MaxSeriesPerLabelSet `yaml:"max_series_per_label_set" json:"max_series_per_label_set" doc:"nocli|description=[Experimental] The maximum number of active series per LabelSet, across the cluster before replication. Empty list to disable."`
119119

120120
// Metadata
121121
MaxLocalMetricsWithMetadataPerUser int `yaml:"max_metadata_per_user" json:"max_metadata_per_user"`
@@ -330,7 +330,7 @@ func (l *Limits) UnmarshalJSON(data []byte) error {
330330

331331
func (l *Limits) calculateMaxSeriesPerLabelSetId() {
332332
for k, limit := range l.MaxSeriesPerLabelSet {
333-
limit.Id = labels.FromMap(limit.LabelSet).String()
333+
limit.Id = limit.LabelSet.String()
334334
limit.Hash = fnv1a.HashBytes64([]byte(limit.Id))
335335
l.MaxSeriesPerLabelSet[k] = limit
336336
}

tools/doc-generator/parser.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,12 @@ func parseConfig(block *configBlock, cfg interface{}, flags map[uintptr]*flag.Fl
193193
if field.Type.Kind() == reflect.Slice {
194194
sliceElementType := field.Type.Elem()
195195
if sliceElementType.Kind() == reflect.Struct {
196-
rootBlocks = append(rootBlocks, rootBlock{
197-
name: field.Type.Elem().Name(),
198-
structType: field.Type.Elem(),
199-
})
196+
if field.Type.String() != "labels.Labels" {
197+
rootBlocks = append(rootBlocks, rootBlock{
198+
name: field.Type.Elem().Name(),
199+
structType: field.Type.Elem(),
200+
})
201+
}
200202
sliceElementBlock := &configBlock{
201203
name: field.Type.Elem().Name(),
202204
desc: "",
@@ -286,6 +288,8 @@ func getFieldType(t reflect.Type) (string, error) {
286288
return "string", nil
287289
case "[]*relabel.Config":
288290
return "relabel_config...", nil
291+
case "labels.Labels":
292+
return "map of string (labelName) to string (labelValue)", nil
289293
}
290294

291295
// Fallback to auto-detection of built-in data types

0 commit comments

Comments
 (0)