2018-01-08 21:36:07 +00:00
|
|
|
// Package testlog creates a *log.Logger backed by *testing.T to ease logging
|
|
|
|
// in tests. This allows logs from components being tested to only be printed
|
|
|
|
// if the test fails (or the verbose flag is specified).
|
2018-01-08 20:53:58 +00:00
|
|
|
package testlog
|
|
|
|
|
|
|
|
import (
|
2019-01-26 00:51:20 +00:00
|
|
|
"bytes"
|
2022-03-18 12:48:08 +00:00
|
|
|
"fmt"
|
2018-01-08 20:53:58 +00:00
|
|
|
"io"
|
|
|
|
"log"
|
2018-02-16 23:07:49 +00:00
|
|
|
"os"
|
2018-09-13 17:43:40 +00:00
|
|
|
|
|
|
|
hclog "github.com/hashicorp/go-hclog"
|
2018-01-08 20:53:58 +00:00
|
|
|
)
|
|
|
|
|
2018-01-08 21:36:07 +00:00
|
|
|
// LogPrinter is the methods of testing.T (or testing.B) needed by the test
|
2018-01-08 20:53:58 +00:00
|
|
|
// logger.
|
2018-01-08 21:36:07 +00:00
|
|
|
type LogPrinter interface {
|
2018-01-08 20:53:58 +00:00
|
|
|
Logf(format string, args ...interface{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewWriter creates a new io.Writer backed by a Logger.
|
2018-01-08 21:36:07 +00:00
|
|
|
func NewWriter(t LogPrinter) io.Writer {
|
2020-05-26 13:11:38 +00:00
|
|
|
return os.Stderr
|
2019-01-26 00:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewPrefixWriter creates a new io.Writer backed by a Logger with a custom
|
|
|
|
// prefix per Write.
|
|
|
|
func NewPrefixWriter(t LogPrinter, prefix string) io.Writer {
|
2020-05-26 13:11:38 +00:00
|
|
|
return &prefixStderr{[]byte(prefix)}
|
2018-01-08 20:53:58 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 21:36:07 +00:00
|
|
|
// New returns a new test logger. See https://golang.org/pkg/log/#New
|
|
|
|
func New(t LogPrinter, prefix string, flag int) *log.Logger {
|
2020-05-26 13:11:38 +00:00
|
|
|
return log.New(os.Stderr, prefix, flag)
|
2018-01-08 20:53:58 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 21:36:07 +00:00
|
|
|
// WithPrefix returns a new test logger with the Lmicroseconds flag set.
|
|
|
|
func WithPrefix(t LogPrinter, prefix string) *log.Logger {
|
|
|
|
return New(t, prefix, log.Lmicroseconds)
|
|
|
|
}
|
|
|
|
|
2022-03-18 12:48:08 +00:00
|
|
|
// Logger returns a new test logger with the Lmicroseconds flag set and no prefix.
|
|
|
|
//
|
|
|
|
// Note: only use this where HCLogger cannot be used (i.e. RPC yamux configuration).
|
2018-01-08 21:36:07 +00:00
|
|
|
func Logger(t LogPrinter) *log.Logger {
|
2018-02-15 23:22:57 +00:00
|
|
|
return WithPrefix(t, "")
|
2018-01-08 20:53:58 +00:00
|
|
|
}
|
2018-09-13 17:43:40 +00:00
|
|
|
|
2022-03-18 12:48:08 +00:00
|
|
|
// HCLogger returns a new test hc-logger.
|
|
|
|
//
|
|
|
|
// Default log level is TRACE. Set NOMAD_TEST_LOG_LEVEL for custom log level.
|
2019-10-15 19:14:25 +00:00
|
|
|
func HCLogger(t LogPrinter) hclog.InterceptLogger {
|
2022-03-18 12:48:08 +00:00
|
|
|
logger, _ := HCLoggerNode(t, -1)
|
|
|
|
return logger
|
|
|
|
}
|
|
|
|
|
|
|
|
// HCLoggerTestLevel returns the level in which hc log should emit logs.
|
|
|
|
//
|
|
|
|
// Default log level is TRACE. Set NOMAD_TEST_LOG_LEVEL for custom log level.
|
|
|
|
func HCLoggerTestLevel() hclog.Level {
|
2019-08-29 18:59:12 +00:00
|
|
|
level := hclog.Trace
|
|
|
|
envLogLevel := os.Getenv("NOMAD_TEST_LOG_LEVEL")
|
|
|
|
if envLogLevel != "" {
|
|
|
|
level = hclog.LevelFromString(envLogLevel)
|
|
|
|
}
|
2022-03-18 12:48:08 +00:00
|
|
|
return level
|
|
|
|
}
|
|
|
|
|
|
|
|
// HCLoggerNode returns a new hc-logger, but with a prefix indicating the node number
|
|
|
|
// on each log line. Useful for TestServer in tests with more than one server.
|
|
|
|
//
|
|
|
|
// Default log level is TRACE. Set NOMAD_TEST_LOG_LEVEL for custom log level.
|
|
|
|
func HCLoggerNode(t LogPrinter, node int32) (hclog.InterceptLogger, io.Writer) {
|
|
|
|
var output io.Writer = os.Stderr
|
|
|
|
if node > -1 {
|
|
|
|
output = NewPrefixWriter(t, fmt.Sprintf("node-%03d", node))
|
|
|
|
}
|
2018-09-13 17:43:40 +00:00
|
|
|
opts := &hclog.LoggerOptions{
|
2022-03-18 12:48:08 +00:00
|
|
|
Level: HCLoggerTestLevel(),
|
|
|
|
Output: output,
|
2018-09-13 17:43:40 +00:00
|
|
|
IncludeLocation: true,
|
|
|
|
}
|
2022-03-18 12:48:08 +00:00
|
|
|
return hclog.NewInterceptLogger(opts), output
|
2018-09-13 17:43:40 +00:00
|
|
|
}
|
2019-01-26 00:51:20 +00:00
|
|
|
|
2020-05-26 13:11:38 +00:00
|
|
|
type prefixStderr struct {
|
2019-01-26 00:51:20 +00:00
|
|
|
prefix []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write to stdout with a prefix per call containing non-whitespace characters.
|
2020-05-26 13:11:38 +00:00
|
|
|
func (w *prefixStderr) Write(p []byte) (int, error) {
|
2019-01-26 00:51:20 +00:00
|
|
|
if len(p) == 0 {
|
|
|
|
return 0, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip prefix if only writing whitespace
|
2020-06-07 13:16:11 +00:00
|
|
|
if len(bytes.TrimSpace(p)) == 0 {
|
|
|
|
return os.Stderr.Write(p)
|
2019-01-26 00:51:20 +00:00
|
|
|
}
|
|
|
|
|
2020-06-07 13:16:11 +00:00
|
|
|
// decrease likely hood of partial line writes that may mess up test
|
|
|
|
// indicator success detection
|
|
|
|
buf := make([]byte, 0, len(w.prefix)+len(p))
|
|
|
|
buf = append(buf, w.prefix...)
|
|
|
|
buf = append(buf, p...)
|
|
|
|
|
|
|
|
return os.Stderr.Write(buf)
|
2019-01-26 00:51:20 +00:00
|
|
|
}
|