You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.2 KiB

  1. package log
  2. import (
  3. "sync"
  4. "testing"
  5. "github.com/rs/zerolog"
  6. )
  7. var (
  8. // reuse the same logger across all tests
  9. testingLoggerMtx = sync.Mutex{}
  10. testingLogger Logger
  11. )
  12. // TestingLogger returns a Logger which writes to STDOUT if test(s) are being
  13. // run with the verbose (-v) flag, NopLogger otherwise.
  14. //
  15. // NOTE:
  16. // - A call to NewTestingLogger() must be made inside a test (not in the init func)
  17. // because verbose flag only set at the time of testing.
  18. // - Repeated calls to this function within a single process will
  19. // produce a single test log instance, and while the logger is safe
  20. // for parallel use it it doesn't produce meaningful feedback for
  21. // parallel tests.
  22. func TestingLogger() Logger {
  23. testingLoggerMtx.Lock()
  24. defer testingLoggerMtx.Unlock()
  25. if testingLogger != nil {
  26. return testingLogger
  27. }
  28. if testing.Verbose() {
  29. testingLogger = MustNewDefaultLogger(LogFormatText, LogLevelDebug)
  30. } else {
  31. testingLogger = NewNopLogger()
  32. }
  33. return testingLogger
  34. }
  35. type testingWriter struct {
  36. t testing.TB
  37. }
  38. func (tw testingWriter) Write(in []byte) (int, error) {
  39. tw.t.Log(string(in))
  40. return len(in), nil
  41. }
  42. // NewTestingLogger converts a testing.T into a logging interface to
  43. // make test failures and verbose provide better feedback associated
  44. // with test failures. This logging instance is safe for use from
  45. // multiple threads, but in general you should create one of these
  46. // loggers ONCE for each *testing.T instance that you interact with.
  47. //
  48. // By default it collects only ERROR messages, or DEBUG messages in
  49. // verbose mode, and relies on the underlying behavior of testing.T.Log()
  50. func NewTestingLogger(t testing.TB) Logger {
  51. level := LogLevelError
  52. if testing.Verbose() {
  53. level = LogLevelDebug
  54. }
  55. return NewTestingLoggerWithLevel(t, level)
  56. }
  57. // NewTestingLoggerWithLevel creates a testing logger instance at a
  58. // specific level that wraps the behavior of testing.T.Log().
  59. func NewTestingLoggerWithLevel(t testing.TB, level string) Logger {
  60. logLevel, err := zerolog.ParseLevel(level)
  61. if err != nil {
  62. t.Fatalf("failed to parse log level (%s): %v", level, err)
  63. }
  64. return defaultLogger{
  65. Logger: zerolog.New(newSyncWriter(testingWriter{t})).Level(logLevel),
  66. }
  67. }