github.com/grafana/pyroscope@v1.18.0/pkg/validation/relabeling.go (about) 1 package validation 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "gopkg.in/yaml.v3" 8 9 "github.com/prometheus/common/model" 10 "github.com/prometheus/prometheus/model/relabel" 11 ) 12 13 var ( 14 godeltaprof = relabel.MustNewRegexp("godeltaprof_(.*)") 15 defaultRelabelRules = []*relabel.Config{ 16 // replace godeltaprof_ prefix from name 17 { 18 SourceLabels: []model.LabelName{"__name__"}, 19 Action: relabel.Replace, 20 Regex: godeltaprof, 21 TargetLabel: "__name_replaced__", 22 Replacement: "$0", 23 }, 24 { 25 SourceLabels: []model.LabelName{"__name_replaced__"}, 26 Action: relabel.Replace, 27 Regex: godeltaprof, 28 TargetLabel: "__delta__", 29 Replacement: "false", 30 }, 31 { 32 SourceLabels: []model.LabelName{"__name__"}, 33 Regex: godeltaprof, 34 Action: relabel.Replace, 35 TargetLabel: "__name__", 36 Replacement: "$1", 37 }, 38 // replace wall with process_cpu when __type__ is cpu 39 { 40 SourceLabels: []model.LabelName{"__name__", "__type__"}, 41 Separator: "/", 42 Regex: relabel.MustNewRegexp("wall/cpu"), 43 Action: relabel.Replace, 44 Replacement: "wall", 45 TargetLabel: "__name_replaced__", 46 }, 47 { 48 SourceLabels: []model.LabelName{"__name__", "__type__"}, 49 Separator: "/", 50 Regex: relabel.MustNewRegexp("wall/cpu"), 51 Action: relabel.Replace, 52 Replacement: "process_cpu", 53 TargetLabel: "__name__", 54 }, 55 } 56 ) 57 58 type RelabelRulesPosition string 59 60 func (p *RelabelRulesPosition) Set(s string) error { 61 switch sp := RelabelRulesPosition(s); sp { 62 case RelabelRulePositionFirst, RelabelRulePositionLast, RelabelRulePositionDisabled: 63 *p = sp 64 return nil 65 } 66 return fmt.Errorf("invalid ingestion_relabeling_default_rules_position: %s", s) 67 } 68 69 func (p *RelabelRulesPosition) String() string { 70 return string(*p) 71 } 72 73 const ( 74 RelabelRulePositionFirst RelabelRulesPosition = "first" 75 RelabelRulePositionDisabled RelabelRulesPosition = "disabled" 76 RelabelRulePositionLast RelabelRulesPosition = "last" 77 ) 78 79 type RelabelRules []*relabel.Config 80 81 func (p *RelabelRules) Set(s string) error { 82 v := []*relabel.Config{} 83 if err := yaml.Unmarshal([]byte(s), &v); err != nil { 84 return err 85 } 86 87 for idx, rule := range v { 88 if err := rule.Validate(); err != nil { 89 return fmt.Errorf("rule at pos %d is not valid: %w", idx, err) 90 } 91 } 92 *p = v 93 return nil 94 } 95 96 func (p *RelabelRules) String() string { 97 yamlBytes, err := yaml.Marshal(p) 98 if err != nil { 99 panic(fmt.Errorf("error marshal yaml: %w", err)) 100 } 101 102 temp := make([]interface{}, 0, len(*p)) 103 err = yaml.Unmarshal(yamlBytes, &temp) 104 if err != nil { 105 panic(fmt.Errorf("error unmarshal yaml: %w", err)) 106 } 107 108 jsonBytes, err := json.Marshal(temp) 109 if err != nil { 110 panic(fmt.Errorf("error marshal json: %w", err)) 111 } 112 return string(jsonBytes) 113 } 114 115 type IngestionRelabelRules []*relabel.Config 116 117 func (r *IngestionRelabelRules) Set(s string) error { 118 return (*RelabelRules)(r).Set(s) 119 } 120 121 func (r *IngestionRelabelRules) String() string { 122 return (*RelabelRules)(r).String() 123 } 124 125 func (r *IngestionRelabelRules) ExampleDoc() (comment string, yaml interface{}) { 126 return `This example consists of two rules, the first one will drop all profiles received with an label 'environment="secrets"' and the second rule will add a label 'powered_by="Grafana Labs"' to all profile series.`, 127 []map[string]interface{}{ 128 {"action": "drop", "source_labels": []interface{}{"environment"}, "regex": "secret"}, 129 {"action": "replace", "replacement": "grafana-labs", "target_label": "powered_by"}, 130 } 131 } 132 133 type SampleTypeRelabelRules []*relabel.Config 134 135 func (r *SampleTypeRelabelRules) Set(s string) error { 136 if err := (*RelabelRules)(r).Set(s); err != nil { 137 return err 138 } 139 140 for idx, rule := range *r { 141 if rule.Action != relabel.Drop && rule.Action != relabel.Keep { 142 return fmt.Errorf("rule at pos %d: sample type relabeling only supports 'drop' and 'keep' actions, got '%s'", idx, rule.Action) 143 } 144 } 145 return nil 146 } 147 148 func (r *SampleTypeRelabelRules) String() string { 149 return (*RelabelRules)(r).String() 150 } 151 152 func (r *SampleTypeRelabelRules) ExampleDoc() (comment string, yaml interface{}) { 153 return `This example shows sample type filtering rules. The first rule drops all allocation-related sample types (alloc_objects, alloc_space) from memory profiles, keeping only in-use metrics. The second rule keeps only CPU-related sample types by matching the __type__ label. The third rule shows how to drop allocation sample types for a specific service by combining __type__ and service_name labels.`, 154 []map[string]interface{}{ 155 {"action": "drop", "source_labels": []interface{}{"__type__"}, "regex": "alloc_.*"}, 156 {"action": "keep", "source_labels": []interface{}{"__type__"}, "regex": "cpu|wall"}, 157 {"action": "drop", "source_labels": []interface{}{"__type__", "service_name"}, "separator": ";", "regex": "alloc_.*;my-service"}, 158 } 159 } 160 161 func (o *Overrides) IngestionRelabelingRules(tenantID string) []*relabel.Config { 162 l := o.getOverridesForTenant(tenantID) 163 164 // return only custom rules when default rules are disabled 165 if l.IngestionRelabelingDefaultRulesPosition == RelabelRulePositionDisabled { 166 return l.IngestionRelabelingRules 167 } 168 169 // quick return if no rules are defined 170 if len(l.IngestionRelabelingRules) == 0 { 171 return defaultRelabelRules 172 } 173 174 rules := make([]*relabel.Config, 0, len(l.IngestionRelabelingRules)+len(defaultRelabelRules)) 175 176 if l.IngestionRelabelingDefaultRulesPosition == "" || l.IngestionRelabelingDefaultRulesPosition == RelabelRulePositionFirst { 177 rules = append(rules, defaultRelabelRules...) 178 return append(rules, l.IngestionRelabelingRules...) 179 } 180 181 rules = append(rules, l.IngestionRelabelingRules...) 182 return append(rules, defaultRelabelRules...) 183 } 184 185 func (o *Overrides) SampleTypeRelabelingRules(tenantID string) []*relabel.Config { 186 l := o.getOverridesForTenant(tenantID) 187 return l.SampleTypeRelabelingRules 188 }