master
go 88 lines 2.79 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package program
4
5 import (
6 "errors"
7 "fmt"
8 )
9
10 // SelectorMatcher is the runtime predicate compiled from selector expressions.
11 //
12 // Implementations are expected to be immutable and safe for concurrent reads.
13 type SelectorMatcher interface {
14 Matches(metricName string, labels SelectorLabels) bool
15 }
16
17 // SelectorLabels is the minimal read-only label view required by selector
18 // matchers. metrix.LabelView satisfies this interface.
19 type SelectorLabels interface {
20 Len() int
21 Get(key string) (string, bool)
22 Range(fn func(key, value string) bool)
23 }
24
25 // SelectorBinding stores selector expression + compiled runtime matcher metadata.
26 type SelectorBinding struct {
27 // Expression is original selector text (for diagnostics/debugging).
28 Expression string
29 // Matcher is compiled selector predicate.
30 Matcher SelectorMatcher
31 // MetricNames are normalized metric-name constraints extracted from selector.
32 MetricNames []string
33 // ConstrainedLabelKeys are matcher keys (sorted/unique) used by label policies.
34 ConstrainedLabelKeys []string
35 }
36
37 // Dimension is one compiled dimension mapping rule for a chart.
38 type Dimension struct {
39 Selector SelectorBinding
40
41 // NameTemplate is used for static/dynamic dimension rendering.
42 NameTemplate Template
43 // NameFromLabel is explicit dynamic name source in placeholder-free mode.
44 NameFromLabel string
45 // InferNameFromSeriesMeta requests runtime inference based on series origin
46 // metadata (e.g. histogram/state-set flatten semantics).
47 InferNameFromSeriesMeta bool
48
49 // Hidden maps to DIMENSION hidden option.
50 Hidden bool
51 // Multiplier maps to DIMENSION multiplier option.
52 Multiplier int
53 // Divisor maps to DIMENSION divisor option.
54 Divisor int
55 // Float maps to DIMENSION type=float option.
56 Float bool
57 // Dynamic is compile-derived and true when rendering can fan out by labels.
58 Dynamic bool
59 }
60
61 func validateDimension(dimension Dimension) error {
62 var errs []error
63 if dimension.Selector.Expression == "" {
64 errs = append(errs, fmt.Errorf("selector expression is required"))
65 }
66 if dimension.Selector.Matcher == nil {
67 errs = append(errs, fmt.Errorf("selector matcher is required"))
68 }
69 if dimension.NameTemplate.Raw == "" && dimension.NameFromLabel == "" && !dimension.InferNameFromSeriesMeta {
70 errs = append(errs, fmt.Errorf("dimension name is required (name template or name_from_label)"))
71 }
72 return errors.Join(errs...)
73 }
74
75 func (d Dimension) clone() Dimension {
76 out := d
77 out.Selector = d.Selector.clone()
78 out.NameTemplate = d.NameTemplate.clone()
79 return out
80 }
81
82 func (s SelectorBinding) clone() SelectorBinding {
83 out := s
84 // Matcher instance is immutable compiled program and can be shared.
85 out.MetricNames = append([]string(nil), s.MetricNames...)
86 out.ConstrainedLabelKeys = append([]string(nil), s.ConstrainedLabelKeys...)
87 return out
88 }