go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/aggrmetrics/builder_presence.go (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aggrmetrics 16 17 import ( 18 "context" 19 20 bbutil "go.chromium.org/luci/buildbucket/protoutil" 21 "go.chromium.org/luci/common/sync/parallel" 22 "go.chromium.org/luci/common/tsmon/types" 23 "go.chromium.org/luci/hardcoded/chromeinfra" 24 25 cfgpb "go.chromium.org/luci/cv/api/config/v2" 26 "go.chromium.org/luci/cv/internal/common" 27 "go.chromium.org/luci/cv/internal/configs/prjcfg" 28 "go.chromium.org/luci/cv/internal/metrics" 29 "go.chromium.org/luci/cv/internal/tryjob" 30 ) 31 32 type builderPresenceAggregator struct { 33 env *common.Env 34 } 35 36 // metrics implements aggregator interface. 37 func (t *builderPresenceAggregator) metrics() []types.Metric { 38 return []types.Metric{metrics.Public.TryjobBuilderPresence} 39 } 40 41 // report implements aggregator interface. 42 func (t *builderPresenceAggregator) report(ctx context.Context, projects []string) error { 43 err := parallel.WorkPool(min(8, len(projects)), func(work chan<- func() error) { 44 for _, project := range projects { 45 project := project 46 work <- func() error { 47 meta, err := prjcfg.GetLatestMeta(ctx, project) 48 switch { 49 case err != nil: 50 return err 51 case meta.Status != prjcfg.StatusEnabled: 52 // race condition: project gets disabled right before loading the 53 // config 54 return nil 55 } 56 cgs, err := meta.GetConfigGroups(ctx) 57 if err != nil { 58 return err 59 } 60 for _, cg := range cgs { 61 if err := reportBuilders(ctx, t.env, project, cg); err != nil { 62 return err 63 } 64 } 65 return nil 66 } 67 } 68 }) 69 return err 70 } 71 72 func reportBuilder(ctx context.Context, env *common.Env, cgName, project, bname string, cfg *cfgpb.Verifiers_Tryjob_Builder) error { 73 bid, err := bbutil.ParseBuilderID(bname) 74 if err != nil { 75 return err 76 } 77 def := &tryjob.Definition{ 78 Backend: &tryjob.Definition_Buildbucket_{ 79 Buildbucket: &tryjob.Definition_Buildbucket{ 80 Builder: bid, 81 Host: chromeinfra.BuildbucketHost, 82 }, 83 }, 84 } 85 tryjob.RunWithBuilderMetricsTarget(ctx, env, def, func(ctx context.Context) { 86 metrics.Public.TryjobBuilderPresence.Set(ctx, true, 87 project, 88 cgName, 89 cfg.GetIncludableOnly(), 90 len(cfg.GetLocationFilters()) > 0, 91 cfg.GetExperimentPercentage() > 0, 92 ) 93 }) 94 return nil 95 } 96 97 func reportBuilders(ctx context.Context, env *common.Env, project string, cg *prjcfg.ConfigGroup) error { 98 cgName := cg.Content.GetName() 99 for _, b := range cg.Content.GetVerifiers().GetTryjob().GetBuilders() { 100 if err := reportBuilder(ctx, env, cgName, project, b.GetName(), b); err != nil { 101 return err 102 } 103 // If the tryjob builder is configured with an equivalent builder, 104 // report the equivalent builder with all the configs of 105 // the tryjob builder, including incluable_only, config_group, etc. 106 if eqb := b.GetEquivalentTo(); eqb != nil { 107 if err := reportBuilder(ctx, env, cgName, project, eqb.GetName(), b); err != nil { 108 return err 109 } 110 } 111 } 112 return nil 113 }