go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/bisection/compilefailureanalysis/compilelog/compile_log.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 compilelogs handles downloading logs for compile failures 16 package compilelog 17 18 import ( 19 "context" 20 "encoding/json" 21 "fmt" 22 23 "go.chromium.org/luci/bisection/internal/logdog" 24 "go.chromium.org/luci/bisection/model" 25 "go.chromium.org/luci/bisection/util" 26 27 "go.chromium.org/luci/bisection/internal/buildbucket" 28 29 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 30 "go.chromium.org/luci/common/logging" 31 "google.golang.org/protobuf/types/known/fieldmaskpb" 32 ) 33 34 // GetCompileLogs gets the compile log for a build bucket build 35 // Returns the ninja log and stdout log 36 func GetCompileLogs(c context.Context, bbid int64) (*model.CompileLogs, error) { 37 build, err := buildbucket.GetBuild(c, bbid, &buildbucketpb.BuildMask{ 38 Fields: &fieldmaskpb.FieldMask{ 39 Paths: []string{"steps"}, 40 }, 41 }) 42 if err != nil { 43 return nil, err 44 } 45 ninjaUrl := "" 46 stdoutUrl := "" 47 for _, step := range build.Steps { 48 if util.IsCompileStep(step) { 49 for _, log := range step.Logs { 50 if log.Name == "json.output[ninja_info]" { 51 ninjaUrl = log.ViewUrl 52 } 53 if log.Name == "stdout" { 54 stdoutUrl = log.ViewUrl 55 } 56 } 57 break 58 } 59 } 60 61 ninjaLog := &model.NinjaLog{} 62 stdoutLog := "" 63 64 // TODO(crbug.com/1295566): Parallelize downloading ninja & stdout logs 65 if ninjaUrl != "" { 66 log, err := logdog.GetLogFromViewUrl(c, ninjaUrl) 67 if err != nil { 68 logging.Errorf(c, "Failed to get ninja log: %v", err) 69 } 70 if err = json.Unmarshal([]byte(log), ninjaLog); err != nil { 71 return nil, fmt.Errorf("Failed to unmarshal ninja log %w. Log: %s", err, log) 72 } 73 } 74 75 if stdoutUrl != "" { 76 stdoutLog, err = logdog.GetLogFromViewUrl(c, stdoutUrl) 77 if err != nil { 78 logging.Errorf(c, "Failed to get stdout log: %v", err) 79 } 80 } 81 82 if len(ninjaLog.Failures) > 0 || stdoutLog != "" { 83 return &model.CompileLogs{ 84 NinjaLog: ninjaLog, 85 StdOutLog: stdoutLog, 86 }, nil 87 } 88 89 return nil, fmt.Errorf("Could not get compile log from build %d", bbid) 90 } 91 92 func GetFailedTargets(compileLogs *model.CompileLogs) []string { 93 if compileLogs.NinjaLog == nil { 94 return []string{} 95 } 96 results := []string{} 97 for _, failure := range compileLogs.NinjaLog.Failures { 98 results = append(results, failure.OutputNodes...) 99 } 100 return results 101 }