1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Worker// Package logger implements a logging package designed for command line 16*333d2b36SAndroid Build Coastguard Worker// utilities. It uses the standard 'log' package and function, but splits 17*333d2b36SAndroid Build Coastguard Worker// output between stderr and a rotating log file. 18*333d2b36SAndroid Build Coastguard Worker// 19*333d2b36SAndroid Build Coastguard Worker// In addition to the standard logger functions, Verbose[f|ln] calls only go to 20*333d2b36SAndroid Build Coastguard Worker// the log file by default, unless SetVerbose(true) has been called. 21*333d2b36SAndroid Build Coastguard Worker// 22*333d2b36SAndroid Build Coastguard Worker// The log file also includes extended date/time/source information, which are 23*333d2b36SAndroid Build Coastguard Worker// omitted from the stderr output for better readability. 24*333d2b36SAndroid Build Coastguard Worker// 25*333d2b36SAndroid Build Coastguard Worker// In order to better handle resource cleanup after a Fatal error, the Fatal 26*333d2b36SAndroid Build Coastguard Worker// functions panic instead of calling os.Exit(). To actually do the cleanup, 27*333d2b36SAndroid Build Coastguard Worker// and prevent the printing of the panic, call defer logger.Cleanup() at the 28*333d2b36SAndroid Build Coastguard Worker// beginning of your main function. 29*333d2b36SAndroid Build Coastguard Workerpackage logger 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Workerimport ( 32*333d2b36SAndroid Build Coastguard Worker "android/soong/ui/metrics" 33*333d2b36SAndroid Build Coastguard Worker "errors" 34*333d2b36SAndroid Build Coastguard Worker "fmt" 35*333d2b36SAndroid Build Coastguard Worker "io" 36*333d2b36SAndroid Build Coastguard Worker "io/ioutil" 37*333d2b36SAndroid Build Coastguard Worker "log" 38*333d2b36SAndroid Build Coastguard Worker "os" 39*333d2b36SAndroid Build Coastguard Worker "path/filepath" 40*333d2b36SAndroid Build Coastguard Worker "strconv" 41*333d2b36SAndroid Build Coastguard Worker "sync" 42*333d2b36SAndroid Build Coastguard Worker "syscall" 43*333d2b36SAndroid Build Coastguard Worker) 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Workertype Logger interface { 46*333d2b36SAndroid Build Coastguard Worker // Print* prints to both stderr and the file log. 47*333d2b36SAndroid Build Coastguard Worker // Arguments to Print are handled in the manner of fmt.Print. 48*333d2b36SAndroid Build Coastguard Worker Print(v ...interface{}) 49*333d2b36SAndroid Build Coastguard Worker // Arguments to Printf are handled in the manner of fmt.Printf 50*333d2b36SAndroid Build Coastguard Worker Printf(format string, v ...interface{}) 51*333d2b36SAndroid Build Coastguard Worker // Arguments to Println are handled in the manner of fmt.Println 52*333d2b36SAndroid Build Coastguard Worker Println(v ...interface{}) 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Worker // Verbose* is equivalent to Print*, but skips stderr unless the 55*333d2b36SAndroid Build Coastguard Worker // logger has been configured in verbose mode. 56*333d2b36SAndroid Build Coastguard Worker Verbose(v ...interface{}) 57*333d2b36SAndroid Build Coastguard Worker Verbosef(format string, v ...interface{}) 58*333d2b36SAndroid Build Coastguard Worker Verboseln(v ...interface{}) 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker // Fatal* is equivalent to Print* followed by a call to panic that 61*333d2b36SAndroid Build Coastguard Worker // can be converted to an error using Recover, or will be converted 62*333d2b36SAndroid Build Coastguard Worker // to a call to os.Exit(1) with a deferred call to Cleanup() 63*333d2b36SAndroid Build Coastguard Worker Fatal(v ...interface{}) 64*333d2b36SAndroid Build Coastguard Worker Fatalf(format string, v ...interface{}) 65*333d2b36SAndroid Build Coastguard Worker Fatalln(v ...interface{}) 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker // Panic is equivalent to Print* followed by a call to panic. 68*333d2b36SAndroid Build Coastguard Worker Panic(v ...interface{}) 69*333d2b36SAndroid Build Coastguard Worker Panicf(format string, v ...interface{}) 70*333d2b36SAndroid Build Coastguard Worker Panicln(v ...interface{}) 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker // Output writes the string to both stderr and the file log. 73*333d2b36SAndroid Build Coastguard Worker Output(calldepth int, str string) error 74*333d2b36SAndroid Build Coastguard Worker} 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Worker// fatalError is the type used when Fatal[f|ln] 77*333d2b36SAndroid Build Coastguard Workertype fatalError struct { 78*333d2b36SAndroid Build Coastguard Worker error 79*333d2b36SAndroid Build Coastguard Worker} 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Workerfunc fileRotation(from, baseName, ext string, cur, max int) error { 82*333d2b36SAndroid Build Coastguard Worker newName := baseName + "." + strconv.Itoa(cur) + ext 83*333d2b36SAndroid Build Coastguard Worker 84*333d2b36SAndroid Build Coastguard Worker if _, err := os.Lstat(newName); err == nil { 85*333d2b36SAndroid Build Coastguard Worker if cur+1 <= max { 86*333d2b36SAndroid Build Coastguard Worker fileRotation(newName, baseName, ext, cur+1, max) 87*333d2b36SAndroid Build Coastguard Worker } 88*333d2b36SAndroid Build Coastguard Worker } 89*333d2b36SAndroid Build Coastguard Worker 90*333d2b36SAndroid Build Coastguard Worker if err := os.Rename(from, newName); err != nil { 91*333d2b36SAndroid Build Coastguard Worker return fmt.Errorf("Failed to rotate %s to %s. %s", from, newName, err) 92*333d2b36SAndroid Build Coastguard Worker } 93*333d2b36SAndroid Build Coastguard Worker return nil 94*333d2b36SAndroid Build Coastguard Worker} 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker// CreateFileWithRotation returns a new os.File using os.Create, renaming any 97*333d2b36SAndroid Build Coastguard Worker// existing files to <filename>.#.<ext>, keeping up to maxCount files. 98*333d2b36SAndroid Build Coastguard Worker// <filename>.1.<ext> is the most recent backup, <filename>.2.<ext> is the 99*333d2b36SAndroid Build Coastguard Worker// second most recent backup, etc. 100*333d2b36SAndroid Build Coastguard Workerfunc CreateFileWithRotation(filename string, maxCount int) (*os.File, error) { 101*333d2b36SAndroid Build Coastguard Worker lockFileName := filepath.Join(filepath.Dir(filename), ".lock_"+filepath.Base(filename)) 102*333d2b36SAndroid Build Coastguard Worker lockFile, err := os.OpenFile(lockFileName, os.O_RDWR|os.O_CREATE, 0666) 103*333d2b36SAndroid Build Coastguard Worker if err != nil { 104*333d2b36SAndroid Build Coastguard Worker return nil, err 105*333d2b36SAndroid Build Coastguard Worker } 106*333d2b36SAndroid Build Coastguard Worker defer lockFile.Close() 107*333d2b36SAndroid Build Coastguard Worker 108*333d2b36SAndroid Build Coastguard Worker err = syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX) 109*333d2b36SAndroid Build Coastguard Worker if err != nil { 110*333d2b36SAndroid Build Coastguard Worker return nil, err 111*333d2b36SAndroid Build Coastguard Worker } 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Worker if _, err := os.Lstat(filename); err == nil { 114*333d2b36SAndroid Build Coastguard Worker ext := filepath.Ext(filename) 115*333d2b36SAndroid Build Coastguard Worker basename := filename[:len(filename)-len(ext)] 116*333d2b36SAndroid Build Coastguard Worker if err = fileRotation(filename, basename, ext, 1, maxCount); err != nil { 117*333d2b36SAndroid Build Coastguard Worker return nil, err 118*333d2b36SAndroid Build Coastguard Worker } 119*333d2b36SAndroid Build Coastguard Worker } 120*333d2b36SAndroid Build Coastguard Worker 121*333d2b36SAndroid Build Coastguard Worker return os.Create(filename) 122*333d2b36SAndroid Build Coastguard Worker} 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Worker// Recover can be used with defer in a GoRoutine to convert a Fatal panics to 125*333d2b36SAndroid Build Coastguard Worker// an error that can be handled. 126*333d2b36SAndroid Build Coastguard Workerfunc Recover(fn func(err error)) { 127*333d2b36SAndroid Build Coastguard Worker p := recover() 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Worker if p == nil { 130*333d2b36SAndroid Build Coastguard Worker return 131*333d2b36SAndroid Build Coastguard Worker } else if log, ok := p.(fatalError); ok { 132*333d2b36SAndroid Build Coastguard Worker fn(error(log)) 133*333d2b36SAndroid Build Coastguard Worker } else { 134*333d2b36SAndroid Build Coastguard Worker panic(p) 135*333d2b36SAndroid Build Coastguard Worker } 136*333d2b36SAndroid Build Coastguard Worker} 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Workertype stdLogger struct { 139*333d2b36SAndroid Build Coastguard Worker stderr *log.Logger 140*333d2b36SAndroid Build Coastguard Worker verbose bool 141*333d2b36SAndroid Build Coastguard Worker 142*333d2b36SAndroid Build Coastguard Worker fileLogger *log.Logger 143*333d2b36SAndroid Build Coastguard Worker mutex sync.Mutex 144*333d2b36SAndroid Build Coastguard Worker file *os.File 145*333d2b36SAndroid Build Coastguard Worker metrics *metrics.Metrics 146*333d2b36SAndroid Build Coastguard Worker} 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Workervar _ Logger = &stdLogger{} 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker// New creates a new Logger. The out variable sets the destination, commonly 151*333d2b36SAndroid Build Coastguard Worker// os.Stderr, but it may be a buffer for tests, or a separate log file if 152*333d2b36SAndroid Build Coastguard Worker// the user doesn't need to see the output. 153*333d2b36SAndroid Build Coastguard Workerfunc New(out io.Writer) *stdLogger { 154*333d2b36SAndroid Build Coastguard Worker return NewWithMetrics(out, nil) 155*333d2b36SAndroid Build Coastguard Worker} 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Workerfunc NewWithMetrics(out io.Writer, m *metrics.Metrics) *stdLogger { 158*333d2b36SAndroid Build Coastguard Worker return &stdLogger{ 159*333d2b36SAndroid Build Coastguard Worker stderr: log.New(out, "", log.Ltime), 160*333d2b36SAndroid Build Coastguard Worker fileLogger: log.New(ioutil.Discard, "", log.Ldate|log.Lmicroseconds|log.Llongfile), 161*333d2b36SAndroid Build Coastguard Worker metrics: m, 162*333d2b36SAndroid Build Coastguard Worker } 163*333d2b36SAndroid Build Coastguard Worker} 164*333d2b36SAndroid Build Coastguard Worker 165*333d2b36SAndroid Build Coastguard Worker// SetVerbose controls whether Verbose[f|ln] logs to stderr as well as the 166*333d2b36SAndroid Build Coastguard Worker// file-backed log. 167*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) SetVerbose(v bool) *stdLogger { 168*333d2b36SAndroid Build Coastguard Worker s.verbose = v 169*333d2b36SAndroid Build Coastguard Worker return s 170*333d2b36SAndroid Build Coastguard Worker} 171*333d2b36SAndroid Build Coastguard Worker 172*333d2b36SAndroid Build Coastguard Worker// SetOutput controls where the file-backed log will be saved. It will keep 173*333d2b36SAndroid Build Coastguard Worker// some number of backups of old log files. 174*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) SetOutput(path string) *stdLogger { 175*333d2b36SAndroid Build Coastguard Worker if f, err := CreateFileWithRotation(path, 5); err == nil { 176*333d2b36SAndroid Build Coastguard Worker s.mutex.Lock() 177*333d2b36SAndroid Build Coastguard Worker defer s.mutex.Unlock() 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker if s.file != nil { 180*333d2b36SAndroid Build Coastguard Worker s.file.Close() 181*333d2b36SAndroid Build Coastguard Worker } 182*333d2b36SAndroid Build Coastguard Worker s.file = f 183*333d2b36SAndroid Build Coastguard Worker s.fileLogger.SetOutput(f) 184*333d2b36SAndroid Build Coastguard Worker } else { 185*333d2b36SAndroid Build Coastguard Worker s.Fatal(err.Error()) 186*333d2b36SAndroid Build Coastguard Worker } 187*333d2b36SAndroid Build Coastguard Worker return s 188*333d2b36SAndroid Build Coastguard Worker} 189*333d2b36SAndroid Build Coastguard Worker 190*333d2b36SAndroid Build Coastguard Workertype panicWriter struct{} 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Workerfunc (panicWriter) Write([]byte) (int, error) { panic("write to panicWriter") } 193*333d2b36SAndroid Build Coastguard Worker 194*333d2b36SAndroid Build Coastguard Worker// Close disables logging to the file and closes the file handle. 195*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Close() { 196*333d2b36SAndroid Build Coastguard Worker s.mutex.Lock() 197*333d2b36SAndroid Build Coastguard Worker defer s.mutex.Unlock() 198*333d2b36SAndroid Build Coastguard Worker if s.file != nil { 199*333d2b36SAndroid Build Coastguard Worker s.fileLogger.SetOutput(panicWriter{}) 200*333d2b36SAndroid Build Coastguard Worker s.file.Close() 201*333d2b36SAndroid Build Coastguard Worker s.file = nil 202*333d2b36SAndroid Build Coastguard Worker } 203*333d2b36SAndroid Build Coastguard Worker} 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker// Cleanup should be used with defer in your main function. It will close the 206*333d2b36SAndroid Build Coastguard Worker// log file and convert any Fatal panics back to os.Exit(1) 207*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Cleanup() { 208*333d2b36SAndroid Build Coastguard Worker fatal := false 209*333d2b36SAndroid Build Coastguard Worker p := recover() 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Worker if _, ok := p.(fatalError); ok { 212*333d2b36SAndroid Build Coastguard Worker fatal = true 213*333d2b36SAndroid Build Coastguard Worker p = nil 214*333d2b36SAndroid Build Coastguard Worker } else if p != nil { 215*333d2b36SAndroid Build Coastguard Worker s.Println(p) 216*333d2b36SAndroid Build Coastguard Worker } 217*333d2b36SAndroid Build Coastguard Worker 218*333d2b36SAndroid Build Coastguard Worker s.Close() 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Worker if p != nil { 221*333d2b36SAndroid Build Coastguard Worker panic(p) 222*333d2b36SAndroid Build Coastguard Worker } else if fatal { 223*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 224*333d2b36SAndroid Build Coastguard Worker } 225*333d2b36SAndroid Build Coastguard Worker} 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Workertype verbosityLevel int 228*333d2b36SAndroid Build Coastguard Worker 229*333d2b36SAndroid Build Coastguard Workerconst ( 230*333d2b36SAndroid Build Coastguard Worker verboseLog verbosityLevel = iota 231*333d2b36SAndroid Build Coastguard Worker infoLog 232*333d2b36SAndroid Build Coastguard Worker fatalLog 233*333d2b36SAndroid Build Coastguard Worker panicLog 234*333d2b36SAndroid Build Coastguard Worker) 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker// Output writes string to both stderr and the file log. 237*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Output(calldepth int, str string) error { 238*333d2b36SAndroid Build Coastguard Worker return s.output(calldepth, str, infoLog) 239*333d2b36SAndroid Build Coastguard Worker} 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker// output writes string to stderr, the file log, and if fatal or panic, to metrics. 242*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) output(calldepth int, str string, level verbosityLevel) error { 243*333d2b36SAndroid Build Coastguard Worker if level != verboseLog || s.verbose { 244*333d2b36SAndroid Build Coastguard Worker s.stderr.Output(calldepth+1, str) 245*333d2b36SAndroid Build Coastguard Worker } 246*333d2b36SAndroid Build Coastguard Worker if level >= fatalLog { 247*333d2b36SAndroid Build Coastguard Worker s.metrics.SetFatalOrPanicMessage(str) 248*333d2b36SAndroid Build Coastguard Worker } 249*333d2b36SAndroid Build Coastguard Worker return s.fileLogger.Output(calldepth+1, str) 250*333d2b36SAndroid Build Coastguard Worker} 251*333d2b36SAndroid Build Coastguard Worker 252*333d2b36SAndroid Build Coastguard Worker// VerboseOutput is equivalent to Output, but only goes to the file log 253*333d2b36SAndroid Build Coastguard Worker// unless SetVerbose(true) has been called. 254*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) VerboseOutput(calldepth int, str string) error { 255*333d2b36SAndroid Build Coastguard Worker return s.output(calldepth, str, verboseLog) 256*333d2b36SAndroid Build Coastguard Worker} 257*333d2b36SAndroid Build Coastguard Worker 258*333d2b36SAndroid Build Coastguard Worker// Print prints to both stderr and the file log. 259*333d2b36SAndroid Build Coastguard Worker// Arguments are handled in the manner of fmt.Print. 260*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Print(v ...interface{}) { 261*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprint(v...) 262*333d2b36SAndroid Build Coastguard Worker s.output(2, output, infoLog) 263*333d2b36SAndroid Build Coastguard Worker} 264*333d2b36SAndroid Build Coastguard Worker 265*333d2b36SAndroid Build Coastguard Worker// Printf prints to both stderr and the file log. 266*333d2b36SAndroid Build Coastguard Worker// Arguments are handled in the manner of fmt.Printf. 267*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Printf(format string, v ...interface{}) { 268*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintf(format, v...) 269*333d2b36SAndroid Build Coastguard Worker s.output(2, output, infoLog) 270*333d2b36SAndroid Build Coastguard Worker} 271*333d2b36SAndroid Build Coastguard Worker 272*333d2b36SAndroid Build Coastguard Worker// Println prints to both stderr and the file log. 273*333d2b36SAndroid Build Coastguard Worker// Arguments are handled in the manner of fmt.Println. 274*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Println(v ...interface{}) { 275*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintln(v...) 276*333d2b36SAndroid Build Coastguard Worker s.output(2, output, infoLog) 277*333d2b36SAndroid Build Coastguard Worker} 278*333d2b36SAndroid Build Coastguard Worker 279*333d2b36SAndroid Build Coastguard Worker// Verbose is equivalent to Print, but only goes to the file log unless 280*333d2b36SAndroid Build Coastguard Worker// SetVerbose(true) has been called. 281*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Verbose(v ...interface{}) { 282*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprint(v...) 283*333d2b36SAndroid Build Coastguard Worker s.VerboseOutput(2, output) 284*333d2b36SAndroid Build Coastguard Worker} 285*333d2b36SAndroid Build Coastguard Worker 286*333d2b36SAndroid Build Coastguard Worker// Verbosef is equivalent to Printf, but only goes to the file log unless 287*333d2b36SAndroid Build Coastguard Worker// SetVerbose(true) has been called. 288*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Verbosef(format string, v ...interface{}) { 289*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintf(format, v...) 290*333d2b36SAndroid Build Coastguard Worker s.VerboseOutput(2, output) 291*333d2b36SAndroid Build Coastguard Worker} 292*333d2b36SAndroid Build Coastguard Worker 293*333d2b36SAndroid Build Coastguard Worker// Verboseln is equivalent to Println, but only goes to the file log unless 294*333d2b36SAndroid Build Coastguard Worker// SetVerbose(true) has been called. 295*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Verboseln(v ...interface{}) { 296*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintln(v...) 297*333d2b36SAndroid Build Coastguard Worker s.VerboseOutput(2, output) 298*333d2b36SAndroid Build Coastguard Worker} 299*333d2b36SAndroid Build Coastguard Worker 300*333d2b36SAndroid Build Coastguard Worker// Fatal is equivalent to Print() followed by a call to panic() that 301*333d2b36SAndroid Build Coastguard Worker// Cleanup will convert to a os.Exit(1). 302*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Fatal(v ...interface{}) { 303*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprint(v...) 304*333d2b36SAndroid Build Coastguard Worker s.output(2, output, fatalLog) 305*333d2b36SAndroid Build Coastguard Worker panic(fatalError{errors.New(output)}) 306*333d2b36SAndroid Build Coastguard Worker} 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Worker// Fatalf is equivalent to Printf() followed by a call to panic() that 309*333d2b36SAndroid Build Coastguard Worker// Cleanup will convert to a os.Exit(1). 310*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Fatalf(format string, v ...interface{}) { 311*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintf(format, v...) 312*333d2b36SAndroid Build Coastguard Worker s.output(2, output, fatalLog) 313*333d2b36SAndroid Build Coastguard Worker panic(fatalError{errors.New(output)}) 314*333d2b36SAndroid Build Coastguard Worker} 315*333d2b36SAndroid Build Coastguard Worker 316*333d2b36SAndroid Build Coastguard Worker// Fatalln is equivalent to Println() followed by a call to panic() that 317*333d2b36SAndroid Build Coastguard Worker// Cleanup will convert to a os.Exit(1). 318*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Fatalln(v ...interface{}) { 319*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintln(v...) 320*333d2b36SAndroid Build Coastguard Worker s.output(2, output, fatalLog) 321*333d2b36SAndroid Build Coastguard Worker panic(fatalError{errors.New(output)}) 322*333d2b36SAndroid Build Coastguard Worker} 323*333d2b36SAndroid Build Coastguard Worker 324*333d2b36SAndroid Build Coastguard Worker// Panic is equivalent to Print() followed by a call to panic(). 325*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Panic(v ...interface{}) { 326*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprint(v...) 327*333d2b36SAndroid Build Coastguard Worker s.output(2, output, panicLog) 328*333d2b36SAndroid Build Coastguard Worker panic(output) 329*333d2b36SAndroid Build Coastguard Worker} 330*333d2b36SAndroid Build Coastguard Worker 331*333d2b36SAndroid Build Coastguard Worker// Panicf is equivalent to Printf() followed by a call to panic(). 332*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Panicf(format string, v ...interface{}) { 333*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintf(format, v...) 334*333d2b36SAndroid Build Coastguard Worker s.output(2, output, panicLog) 335*333d2b36SAndroid Build Coastguard Worker panic(output) 336*333d2b36SAndroid Build Coastguard Worker} 337*333d2b36SAndroid Build Coastguard Worker 338*333d2b36SAndroid Build Coastguard Worker// Panicln is equivalent to Println() followed by a call to panic(). 339*333d2b36SAndroid Build Coastguard Workerfunc (s *stdLogger) Panicln(v ...interface{}) { 340*333d2b36SAndroid Build Coastguard Worker output := fmt.Sprintln(v...) 341*333d2b36SAndroid Build Coastguard Worker s.output(2, output, panicLog) 342*333d2b36SAndroid Build Coastguard Worker panic(output) 343*333d2b36SAndroid Build Coastguard Worker} 344