diff options
| author | Taras Madan <tarasmadan@google.com> | 2024-09-10 12:16:33 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-09-10 14:05:26 +0000 |
| commit | c97c816133b42257d0bcf1ee4bd178bb2a7a2b9e (patch) | |
| tree | 0bcbc2e540bbf8f62f6c17887cdd53b8c2cee637 /vendor/github.com/yeya24 | |
| parent | 54e657429ab892ad06c90cd7c1a4eb33ba93a3dc (diff) | |
vendor: update
Diffstat (limited to 'vendor/github.com/yeya24')
| -rw-r--r-- | vendor/github.com/yeya24/promlinter/promlinter.go | 237 |
1 files changed, 200 insertions, 37 deletions
diff --git a/vendor/github.com/yeya24/promlinter/promlinter.go b/vendor/github.com/yeya24/promlinter/promlinter.go index 2ed4d60a8..17a7f4c3e 100644 --- a/vendor/github.com/yeya24/promlinter/promlinter.go +++ b/vendor/github.com/yeya24/promlinter/promlinter.go @@ -82,6 +82,23 @@ type MetricFamilyWithPos struct { Pos token.Position } +func (m *MetricFamilyWithPos) Labels() []string { + var arr []string + if len(m.MetricFamily.Metric) > 0 { + for _, label := range m.MetricFamily.Metric[0].Label { + if label.Value != nil { + arr = append(arr, + fmt.Sprintf("%s=%s", + strings.Trim(*label.Name, `"`), + strings.Trim(*label.Value, `"`))) + } else { + arr = append(arr, strings.Trim(*label.Name, `"`)) + } + } + } + return arr +} + type visitor struct { fs *token.FileSet metrics []MetricFamilyWithPos @@ -93,6 +110,12 @@ type opt struct { namespace string subsystem string name string + + help string + helpSet bool + + labels []string + constLabels map[string]string } func RunList(fs *token.FileSet, files []*ast.File, strict bool) []MetricFamilyWithPos { @@ -151,9 +174,6 @@ func RunLint(fs *token.FileSet, files []*ast.File, s Setting) []Issue { } } - sort.Slice(v.issues, func(i, j int) bool { - return v.issues[i].Pos.String() < v.issues[j].Pos.String() - }) return v.issues } @@ -168,11 +188,23 @@ func (v *visitor) Visit(n ast.Node) ast.Visitor { case *ast.SendStmt: return v.parseSendMetricChanExpr(t) + + default: } return v } +func (v *visitor) addMetric(mfp *MetricFamilyWithPos) { + for _, m := range v.metrics { + if mfp.MetricFamily.String() == m.MetricFamily.String() { + return + } + } + + v.metrics = append(v.metrics, *mfp) +} + func (v *visitor) parseCallerExpr(call *ast.CallExpr) ast.Visitor { var ( metricType dto.MetricType @@ -190,16 +222,17 @@ func (v *visitor) parseCallerExpr(call *ast.CallExpr) ast.Visitor { */ case *ast.Ident: if stmt.Name == "NewCounterFunc" { - return v.parseOpts(call.Args[0], dto.MetricType_COUNTER) + return v.parseOpts(call.Args, dto.MetricType_COUNTER) } if stmt.Name == "NewGaugeFunc" { - return v.parseOpts(call.Args[0], dto.MetricType_GAUGE) + return v.parseOpts(call.Args, dto.MetricType_GAUGE) } if metricType, ok = metricsType[stmt.Name]; !ok { return v } + methodName = stmt.Name /* @@ -216,11 +249,11 @@ func (v *visitor) parseCallerExpr(call *ast.CallExpr) ast.Visitor { */ case *ast.SelectorExpr: if stmt.Sel.Name == "NewCounterFunc" { - return v.parseOpts(call.Args[0], dto.MetricType_COUNTER) + return v.parseOpts(call.Args, dto.MetricType_COUNTER) } if stmt.Sel.Name == "NewGaugeFunc" { - return v.parseOpts(call.Args[0], dto.MetricType_GAUGE) + return v.parseOpts(call.Args, dto.MetricType_GAUGE) } if stmt.Sel.Name == "NewFamilyGenerator" && len(call.Args) == 5 { @@ -230,6 +263,7 @@ func (v *visitor) parseCallerExpr(call *ast.CallExpr) ast.Visitor { if metricType, ok = metricsType[stmt.Sel.Name]; !ok { return v } + methodName = stmt.Sel.Name default: @@ -254,19 +288,44 @@ func (v *visitor) parseCallerExpr(call *ast.CallExpr) ast.Visitor { return v } - return v.parseOpts(call.Args[0], metricType) + return v.parseOpts(call.Args, metricType) } -func (v *visitor) parseOpts(optArg ast.Node, metricType dto.MetricType) ast.Visitor { +func (v *visitor) parseOpts(optArgs []ast.Expr, metricType dto.MetricType) ast.Visitor { // position for the first arg of the CallExpr - optsPosition := v.fs.Position(optArg.Pos()) - opts, help := v.parseOptsExpr(optArg) + optsPosition := v.fs.Position(optArgs[0].Pos()) + opts := v.parseOptsExpr(optArgs[0]) + + var metric *dto.Metric + if len(optArgs) > 1 { + // parse labels + if labelOpts := v.parseOptsExpr(optArgs[1]); labelOpts != nil && len(labelOpts.labels) > 0 { + metric = &dto.Metric{} + for idx, _ := range labelOpts.labels { + metric.Label = append(metric.Label, + &dto.LabelPair{ + Name: &labelOpts.labels[idx], + }) + } + } + } + if opts == nil { return v } + currentMetric := dto.MetricFamily{ Type: &metricType, - Help: help, + } + + if !opts.helpSet { + currentMetric.Help = nil + } else { + currentMetric.Help = &opts.help + } + + if metric != nil { + currentMetric.Metric = append(currentMetric.Metric, metric) } metricName := prometheus.BuildFQName(opts.namespace, opts.subsystem, opts.name) @@ -278,7 +337,7 @@ func (v *visitor) parseOpts(optArg ast.Node, metricType dto.MetricType) ast.Visi } currentMetric.Name = &metricName - v.metrics = append(v.metrics, MetricFamilyWithPos{MetricFamily: ¤tMetric, Pos: optsPosition}) + v.addMetric(&MetricFamilyWithPos{MetricFamily: ¤tMetric, Pos: optsPosition}) return v } @@ -307,7 +366,8 @@ func (v *visitor) parseKSMMetrics(nameArg ast.Node, helpArg ast.Node, metricType } } - v.metrics = append(v.metrics, MetricFamilyWithPos{MetricFamily: ¤tMetric, Pos: optsPosition}) + v.addMetric(&MetricFamilyWithPos{MetricFamily: ¤tMetric, Pos: optsPosition}) + return v } @@ -347,15 +407,40 @@ func (v *visitor) parseSendMetricChanExpr(chExpr *ast.SendStmt) ast.Visitor { return v } - name, help := v.parseConstMetricOptsExpr(call.Args[0]) - if name == nil { + if len(call.Args) == 0 { + return v + } + + descCall := v.parseConstMetricOptsExpr(call.Args[0]) + if descCall == nil { return v } metric := &dto.MetricFamily{ - Name: name, - Help: help, + Name: descCall.name, + Help: descCall.help, } + + if len(descCall.labels) > 0 { + m := &dto.Metric{} + for idx, _ := range descCall.labels { + m.Label = append(m.Label, + &dto.LabelPair{ + Name: &descCall.labels[idx], + }) + } + + for idx, _ := range descCall.constLabels { + m.Label = append(m.Label, + &dto.LabelPair{ + Name: &descCall.constLabels[idx][0], + Value: &descCall.constLabels[idx][1], + }) + } + + metric.Metric = append(metric.Metric, m) + } + switch methodName { case "MustNewConstMetric", "NewLazyConstMetric": switch t := call.Args[1].(type) { @@ -373,11 +458,11 @@ func (v *visitor) parseSendMetricChanExpr(chExpr *ast.SendStmt) ast.Visitor { metric.Type = &metricType } - v.metrics = append(v.metrics, MetricFamilyWithPos{MetricFamily: metric, Pos: v.fs.Position(call.Pos())}) + v.addMetric(&MetricFamilyWithPos{MetricFamily: metric, Pos: v.fs.Position(call.Pos())}) return v } -func (v *visitor) parseOptsExpr(n ast.Node) (*opt, *string) { +func (v *visitor) parseOptsExpr(n ast.Node) *opt { switch stmt := n.(type) { case *ast.CompositeLit: return v.parseCompositeOpts(stmt) @@ -395,17 +480,49 @@ func (v *visitor) parseOptsExpr(n ast.Node) (*opt, *string) { return v.parseOptsExpr(stmt.X) } - return nil, nil + return nil } -func (v *visitor) parseCompositeOpts(stmt *ast.CompositeLit) (*opt, *string) { +func (v *visitor) parseCompositeOpts(stmt *ast.CompositeLit) *opt { metricOption := &opt{} - var help *string + for _, elt := range stmt.Elts { + + // labels + label, ok := elt.(*ast.BasicLit) + if ok { + metricOption.labels = append(metricOption.labels, strings.Trim(label.Value, `"`)) + continue + } + kvExpr, ok := elt.(*ast.KeyValueExpr) if !ok { continue } + + // const labels + if key, ok := kvExpr.Key.(*ast.BasicLit); ok { + + if metricOption.constLabels == nil { + metricOption.constLabels = map[string]string{} + } + + // only accept literal string value + // + // { + // "key": "some-string-literal", + // } + switch val := kvExpr.Value.(type) { + case *ast.BasicLit: + metricOption.constLabels[key.Value] = val.Value + + default: + metricOption.constLabels[key.Value] = "?" // use a placeholder for the const label + } + + continue + } + object, ok := kvExpr.Key.(*ast.Ident) if !ok { continue @@ -418,7 +535,7 @@ func (v *visitor) parseCompositeOpts(stmt *ast.CompositeLit) (*opt, *string) { // If failed to parse field value, stop parsing. stringLiteral, ok := v.parseValue(object.Name, kvExpr.Value) if !ok { - return nil, nil + return nil } switch object.Name { @@ -429,14 +546,16 @@ func (v *visitor) parseCompositeOpts(stmt *ast.CompositeLit) (*opt, *string) { case "Name": metricOption.name = stringLiteral case "Help": - help = &stringLiteral + metricOption.help = stringLiteral + metricOption.helpSet = true } } - return metricOption, help + return metricOption } func (v *visitor) parseValue(object string, n ast.Node) (string, bool) { + switch t := n.(type) { // make sure it is string literal value @@ -452,14 +571,26 @@ func (v *visitor) parseValue(object string, n ast.Node) (string, bool) { return "", false } - if vs, ok := t.Obj.Decl.(*ast.ValueSpec); ok { + switch vs := t.Obj.Decl.(type) { + + case *ast.ValueSpec: + // var some string = "some string" return v.parseValue(object, vs) + + case *ast.AssignStmt: + // TODO: + // some := "some string" + return "", false + + default: + return "", false } case *ast.ValueSpec: if len(t.Values) == 0 { return "", false } + return v.parseValue(object, t.Values[0]) // For binary expr, we only support adding two strings like `foo` + `bar`. @@ -539,7 +670,7 @@ func (v *visitor) parseValueCallExpr(object string, call *ast.CallExpr) (string, return "", false } -func (v *visitor) parseConstMetricOptsExpr(n ast.Node) (*string, *string) { +func (v *visitor) parseConstMetricOptsExpr(n ast.Node) *descCallExpr { switch stmt := n.(type) { case *ast.CallExpr: return v.parseNewDescCallExpr(stmt) @@ -580,10 +711,16 @@ func (v *visitor) parseConstMetricOptsExpr(n ast.Node) (*string, *string) { } } - return nil, nil + return nil } -func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) (*string, *string) { +type descCallExpr struct { + name, help *string + labels []string + constLabels [][2]string +} + +func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) *descCallExpr { var ( help string name string @@ -600,7 +737,7 @@ func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) (*string, *string) { Text: fmt.Sprintf("parsing desc with function %s is not supported", expr.Name), }) } - return nil, nil + return nil } case *ast.SelectorExpr: if expr.Sel.Name != "NewDesc" { @@ -611,7 +748,7 @@ func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) (*string, *string) { Text: fmt.Sprintf("parsing desc with function %s is not supported", expr.Sel.Name), }) } - return nil, nil + return nil } default: if v.strict { @@ -621,7 +758,7 @@ func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) (*string, *string) { Text: fmt.Sprintf("parsing desc of %T is not supported", expr), }) } - return nil, nil + return nil } // k8s.io/component-base/metrics.NewDesc has 6 args @@ -632,19 +769,45 @@ func (v *visitor) parseNewDescCallExpr(call *ast.CallExpr) (*string, *string) { Pos: v.fs.Position(call.Pos()), Text: "NewDesc should have at least 4 args", }) - return nil, nil + return nil } name, ok = v.parseValue("fqName", call.Args[0]) if !ok { - return nil, nil + return nil } + help, ok = v.parseValue("help", call.Args[1]) if !ok { - return nil, nil + return nil + } + + res := &descCallExpr{ + name: &name, + help: &help, + } + + if x, ok := call.Args[2].(*ast.CompositeLit); ok { + opt := v.parseCompositeOpts(x) + if opt == nil { + return nil + } + + res.labels = opt.labels + } + + if x, ok := call.Args[3].(*ast.CompositeLit); ok { + opt := v.parseCompositeOpts(x) + if opt == nil { + return nil + } + + for k, v := range opt.constLabels { + res.constLabels = append(res.constLabels, [2]string{k, v}) + } } - return &name, &help + return res } func mustUnquote(str string) string { |
