ValidateLabels returns an err if the labels are invalid. The returned error may retain the provided series labels. Callers must validate metric name (e.g. via ValidateMetricName) before calling this when EnforceMetricName is true.
(validateMetrics *ValidateMetrics, limits *Limits, userID string, ls []cortexpb.LabelAdapter, skipLabelNameValidation bool, nameValidationScheme model.ValidationScheme)
| 297 | // The returned error may retain the provided series labels. |
| 298 | // Callers must validate metric name (e.g. via ValidateMetricName) before calling this when EnforceMetricName is true. |
| 299 | func ValidateLabels(validateMetrics *ValidateMetrics, limits *Limits, userID string, ls []cortexpb.LabelAdapter, skipLabelNameValidation bool, nameValidationScheme model.ValidationScheme) ValidationError { |
| 300 | numLabelNames := len(ls) |
| 301 | if numLabelNames > limits.MaxLabelNamesPerSeries { |
| 302 | validateMetrics.DiscardedSamples.WithLabelValues(maxLabelNamesPerSeries, userID).Inc() |
| 303 | return newTooManyLabelsError(ls, limits.MaxLabelNamesPerSeries) |
| 304 | } |
| 305 | |
| 306 | maxLabelNameLength := limits.MaxLabelNameLength |
| 307 | maxLabelValueLength := limits.MaxLabelValueLength |
| 308 | lastLabelName := "" |
| 309 | maxLabelsSizeBytes := limits.MaxLabelsSizeBytes |
| 310 | labelsSizeBytes := 0 |
| 311 | |
| 312 | for _, l := range ls { |
| 313 | if !skipLabelNameValidation && !nameValidationScheme.IsValidLabelName(l.Name) { |
| 314 | validateMetrics.DiscardedSamples.WithLabelValues(invalidLabel, userID).Inc() |
| 315 | return newInvalidLabelError(ls, l.Name) |
| 316 | } else if len(l.Name) > maxLabelNameLength { |
| 317 | validateMetrics.DiscardedSamples.WithLabelValues(labelNameTooLong, userID).Inc() |
| 318 | return newLabelNameTooLongError(ls, l.Name, maxLabelNameLength) |
| 319 | } else if len(l.Value) > maxLabelValueLength { |
| 320 | validateMetrics.DiscardedSamples.WithLabelValues(labelValueTooLong, userID).Inc() |
| 321 | return newLabelValueTooLongError(ls, l.Name, l.Value, maxLabelValueLength) |
| 322 | } else if cmp := strings.Compare(lastLabelName, l.Name); cmp >= 0 { |
| 323 | if cmp == 0 { |
| 324 | validateMetrics.DiscardedSamples.WithLabelValues(duplicateLabelNames, userID).Inc() |
| 325 | return newDuplicatedLabelError(ls, l.Name) |
| 326 | } |
| 327 | |
| 328 | validateMetrics.DiscardedSamples.WithLabelValues(labelsNotSorted, userID).Inc() |
| 329 | return newLabelsNotSortedError(ls, l.Name) |
| 330 | } |
| 331 | |
| 332 | lastLabelName = l.Name |
| 333 | labelsSizeBytes += l.Size() |
| 334 | } |
| 335 | validateMetrics.LabelSizeBytes.WithLabelValues(userID).Observe(float64(labelsSizeBytes)) |
| 336 | if maxLabelsSizeBytes > 0 && labelsSizeBytes > maxLabelsSizeBytes { |
| 337 | validateMetrics.DiscardedSamples.WithLabelValues(labelsSizeBytesExceeded, userID).Inc() |
| 338 | return labelSizeBytesExceededError(ls, labelsSizeBytes, maxLabelsSizeBytes) |
| 339 | } |
| 340 | return nil |
| 341 | } |
| 342 | |
| 343 | // ValidateMetadata returns an err if a metric metadata is invalid. |
| 344 | func ValidateMetadata(validateMetrics *ValidateMetrics, cfg *Limits, userID string, metadata *cortexpb.MetricMetadata) error { |