github.com/manicqin/nomad@v0.9.5/helper/testlog/testlog.go (about) 1 // Package testlog creates a *log.Logger backed by *testing.T to ease logging 2 // in tests. This allows logs from components being tested to only be printed 3 // if the test fails (or the verbose flag is specified). 4 package testlog 5 6 import ( 7 "bytes" 8 "io" 9 "log" 10 "os" 11 12 hclog "github.com/hashicorp/go-hclog" 13 ) 14 15 // UseStdout returns true if NOMAD_TEST_STDOUT=1 and sends logs to stdout. 16 func UseStdout() bool { 17 return os.Getenv("NOMAD_TEST_STDOUT") == "1" 18 } 19 20 // LogPrinter is the methods of testing.T (or testing.B) needed by the test 21 // logger. 22 type LogPrinter interface { 23 Logf(format string, args ...interface{}) 24 } 25 26 // writer implements io.Writer on top of a Logger. 27 type writer struct { 28 prefix string 29 t LogPrinter 30 } 31 32 // Write to an underlying Logger. Never returns an error. 33 func (w *writer) Write(p []byte) (n int, err error) { 34 w.t.Logf("%s%s", w.prefix, p) 35 return len(p), nil 36 } 37 38 // NewWriter creates a new io.Writer backed by a Logger. 39 func NewWriter(t LogPrinter) io.Writer { 40 if UseStdout() { 41 return os.Stdout 42 } 43 return &writer{t: t} 44 } 45 46 // NewPrefixWriter creates a new io.Writer backed by a Logger with a custom 47 // prefix per Write. 48 func NewPrefixWriter(t LogPrinter, prefix string) io.Writer { 49 if UseStdout() { 50 return &prefixStdout{[]byte(prefix)} 51 } 52 return &writer{prefix, t} 53 } 54 55 // New returns a new test logger. See https://golang.org/pkg/log/#New 56 func New(t LogPrinter, prefix string, flag int) *log.Logger { 57 if UseStdout() { 58 return log.New(os.Stdout, prefix, flag) 59 } 60 return log.New(&writer{t: t}, prefix, flag) 61 } 62 63 // WithPrefix returns a new test logger with the Lmicroseconds flag set. 64 func WithPrefix(t LogPrinter, prefix string) *log.Logger { 65 return New(t, prefix, log.Lmicroseconds) 66 } 67 68 // Logger returns a new test logger with the Lmicroseconds flag set and no 69 // prefix. 70 func Logger(t LogPrinter) *log.Logger { 71 return WithPrefix(t, "") 72 } 73 74 //HCLogger returns a new test hc-logger. 75 func HCLogger(t LogPrinter) hclog.InterceptLogger { 76 level := hclog.Trace 77 envLogLevel := os.Getenv("NOMAD_TEST_LOG_LEVEL") 78 if envLogLevel != "" { 79 level = hclog.LevelFromString(envLogLevel) 80 } 81 opts := &hclog.LoggerOptions{ 82 Level: level, 83 Output: NewWriter(t), 84 IncludeLocation: true, 85 } 86 return hclog.NewInterceptLogger(opts) 87 } 88 89 type prefixStdout struct { 90 prefix []byte 91 } 92 93 // Write to stdout with a prefix per call containing non-whitespace characters. 94 func (w *prefixStdout) Write(p []byte) (int, error) { 95 if len(p) == 0 { 96 return 0, nil 97 } 98 99 // Skip prefix if only writing whitespace 100 if len(bytes.TrimSpace(p)) > 0 { 101 _, err := os.Stdout.Write(w.prefix) 102 if err != nil { 103 return 0, err 104 } 105 } 106 107 return os.Stdout.Write(p) 108 }