From f2a80c6396524e9c554298feca98f0cc5416b8b2 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Fri, 21 Oct 2022 10:42:35 -0400 Subject: Add non-zero exit + error message to soong metrics Improves some error messages that would have given little/no information Bug: 254650145 Test: relevant unit tests Test: Induce errors and check metrics proto Change-Id: Ife6116af74af6e62c2f8ae8774e53c28178fb8d0 --- ui/logger/Android.bp | 3 +++ ui/logger/logger.go | 65 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 21 deletions(-) (limited to 'ui/logger') diff --git a/ui/logger/Android.bp b/ui/logger/Android.bp index 269a5a084..7883ea6e5 100644 --- a/ui/logger/Android.bp +++ b/ui/logger/Android.bp @@ -25,4 +25,7 @@ bootstrap_go_package { testSrcs: [ "logger_test.go", ], + deps: [ + "soong-ui-metrics", + ], } diff --git a/ui/logger/logger.go b/ui/logger/logger.go index 9b26ae80a..11852982a 100644 --- a/ui/logger/logger.go +++ b/ui/logger/logger.go @@ -29,6 +29,7 @@ package logger import ( + "android/soong/ui/metrics" "errors" "fmt" "io" @@ -72,8 +73,8 @@ type Logger interface { Output(calldepth int, str string) error } -// fatalLog is the type used when Fatal[f|ln] -type fatalLog struct { +// fatalError is the type used when Fatal[f|ln] +type fatalError struct { error } @@ -127,7 +128,7 @@ func Recover(fn func(err error)) { if p == nil { return - } else if log, ok := p.(fatalLog); ok { + } else if log, ok := p.(fatalError); ok { fn(error(log)) } else { panic(p) @@ -141,6 +142,7 @@ type stdLogger struct { fileLogger *log.Logger mutex sync.Mutex file *os.File + metrics *metrics.Metrics } var _ Logger = &stdLogger{} @@ -149,9 +151,14 @@ var _ Logger = &stdLogger{} // os.Stderr, but it may be a buffer for tests, or a separate log file if // the user doesn't need to see the output. func New(out io.Writer) *stdLogger { + return NewWithMetrics(out, nil) +} + +func NewWithMetrics(out io.Writer, m *metrics.Metrics) *stdLogger { return &stdLogger{ stderr: log.New(out, "", log.Ltime), fileLogger: log.New(ioutil.Discard, "", log.Ldate|log.Lmicroseconds|log.Llongfile), + metrics: m, } } @@ -201,7 +208,7 @@ func (s *stdLogger) Cleanup() { fatal := false p := recover() - if _, ok := p.(fatalLog); ok { + if _, ok := p.(fatalError); ok { fatal = true p = nil } else if p != nil { @@ -217,40 +224,56 @@ func (s *stdLogger) Cleanup() { } } +type verbosityLevel int + +const ( + verboseLog verbosityLevel = iota + infoLog + fatalLog + panicLog +) + // Output writes string to both stderr and the file log. func (s *stdLogger) Output(calldepth int, str string) error { - s.stderr.Output(calldepth+1, str) + return s.output(calldepth, str, infoLog) +} + +// output writes string to stderr, the file log, and if fatal or panic, to metrics. +func (s *stdLogger) output(calldepth int, str string, level verbosityLevel) error { + if level != verboseLog || s.verbose { + s.stderr.Output(calldepth+1, str) + } + if level >= fatalLog { + s.metrics.SetFatalOrPanicMessage(str) + } return s.fileLogger.Output(calldepth+1, str) } // VerboseOutput is equivalent to Output, but only goes to the file log // unless SetVerbose(true) has been called. func (s *stdLogger) VerboseOutput(calldepth int, str string) error { - if s.verbose { - s.stderr.Output(calldepth+1, str) - } - return s.fileLogger.Output(calldepth+1, str) + return s.output(calldepth, str, verboseLog) } // Print prints to both stderr and the file log. // Arguments are handled in the manner of fmt.Print. func (s *stdLogger) Print(v ...interface{}) { output := fmt.Sprint(v...) - s.Output(2, output) + s.output(2, output, infoLog) } // Printf prints to both stderr and the file log. // Arguments are handled in the manner of fmt.Printf. func (s *stdLogger) Printf(format string, v ...interface{}) { output := fmt.Sprintf(format, v...) - s.Output(2, output) + s.output(2, output, infoLog) } // Println prints to both stderr and the file log. // Arguments are handled in the manner of fmt.Println. func (s *stdLogger) Println(v ...interface{}) { output := fmt.Sprintln(v...) - s.Output(2, output) + s.output(2, output, infoLog) } // Verbose is equivalent to Print, but only goes to the file log unless @@ -278,43 +301,43 @@ func (s *stdLogger) Verboseln(v ...interface{}) { // Cleanup will convert to a os.Exit(1). func (s *stdLogger) Fatal(v ...interface{}) { output := fmt.Sprint(v...) - s.Output(2, output) - panic(fatalLog{errors.New(output)}) + s.output(2, output, fatalLog) + panic(fatalError{errors.New(output)}) } // Fatalf is equivalent to Printf() followed by a call to panic() that // Cleanup will convert to a os.Exit(1). func (s *stdLogger) Fatalf(format string, v ...interface{}) { output := fmt.Sprintf(format, v...) - s.Output(2, output) - panic(fatalLog{errors.New(output)}) + s.output(2, output, fatalLog) + panic(fatalError{errors.New(output)}) } // Fatalln is equivalent to Println() followed by a call to panic() that // Cleanup will convert to a os.Exit(1). func (s *stdLogger) Fatalln(v ...interface{}) { output := fmt.Sprintln(v...) - s.Output(2, output) - panic(fatalLog{errors.New(output)}) + s.output(2, output, fatalLog) + panic(fatalError{errors.New(output)}) } // Panic is equivalent to Print() followed by a call to panic(). func (s *stdLogger) Panic(v ...interface{}) { output := fmt.Sprint(v...) - s.Output(2, output) + s.output(2, output, panicLog) panic(output) } // Panicf is equivalent to Printf() followed by a call to panic(). func (s *stdLogger) Panicf(format string, v ...interface{}) { output := fmt.Sprintf(format, v...) - s.Output(2, output) + s.output(2, output, panicLog) panic(output) } // Panicln is equivalent to Println() followed by a call to panic(). func (s *stdLogger) Panicln(v ...interface{}) { output := fmt.Sprintln(v...) - s.Output(2, output) + s.output(2, output, panicLog) panic(output) } -- cgit v1.2.3-59-g8ed1b