xref: /aosp_15_r20/build/soong/ui/logger/logger.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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