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  }