github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/log/testlogger.go (about)

     1  package log
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/datawire/dlib/dlog"
    12  	"github.com/telepresenceio/telepresence/v2/pkg/maps"
    13  )
    14  
    15  type tbWrapper struct {
    16  	testing.TB
    17  	level  dlog.LogLevel
    18  	fields map[string]any
    19  }
    20  
    21  type tbWriter struct {
    22  	*tbWrapper
    23  	l dlog.LogLevel
    24  }
    25  
    26  func (w *tbWriter) Write(data []byte) (n int, err error) {
    27  	w.Helper()
    28  	w.Log(w.l, strings.TrimSuffix(string(data), "\n")) // strip trailing newline if present, since the Log() call appends a newline
    29  	return len(data), nil
    30  }
    31  
    32  func NewTestLogger(t testing.TB, level dlog.LogLevel) dlog.Logger {
    33  	return &tbWrapper{TB: t, level: level}
    34  }
    35  
    36  func (w *tbWrapper) StdLogger(l dlog.LogLevel) *log.Logger {
    37  	return log.New(&tbWriter{tbWrapper: w, l: l}, "", 0)
    38  }
    39  
    40  func (w *tbWrapper) WithField(key string, value any) dlog.Logger {
    41  	ret := tbWrapper{
    42  		TB:     w.TB,
    43  		fields: make(map[string]any, len(w.fields)+1),
    44  	}
    45  	maps.Merge(ret.fields, w.fields)
    46  	ret.fields[key] = value
    47  	return &ret
    48  }
    49  
    50  func (w *tbWrapper) Log(level dlog.LogLevel, msg string) {
    51  	if level > w.level {
    52  		return
    53  	}
    54  	w.Helper()
    55  	w.UnformattedLog(level, msg)
    56  }
    57  
    58  func (w *tbWrapper) UnformattedLog(level dlog.LogLevel, args ...any) {
    59  	if level > w.level {
    60  		return
    61  	}
    62  	w.Helper()
    63  	sb := strings.Builder{}
    64  	sb.WriteString(time.Now().Format("15:04:05.0000"))
    65  	for _, arg := range args {
    66  		sb.WriteString(" ")
    67  		fmt.Fprint(&sb, arg)
    68  	}
    69  
    70  	if len(w.fields) > 0 {
    71  		parts := make([]string, 0, len(w.fields))
    72  		for k := range w.fields {
    73  			parts = append(parts, k)
    74  		}
    75  		sort.Strings(parts)
    76  
    77  		for i, k := range parts {
    78  			if i > 0 {
    79  				sb.WriteString(" ")
    80  			}
    81  			fmt.Fprintf(&sb, "%s=%#v", k, w.fields[k])
    82  		}
    83  	}
    84  	w.TB.Log(sb.String())
    85  }
    86  
    87  func (w *tbWrapper) UnformattedLogf(level dlog.LogLevel, format string, args ...any) {
    88  	if level > w.level {
    89  		return
    90  	}
    91  	w.Helper()
    92  	w.Log(level, fmt.Sprintf(format, args...))
    93  }
    94  
    95  func (w *tbWrapper) UnformattedLogln(level dlog.LogLevel, args ...any) {
    96  	if level > w.level {
    97  		return
    98  	}
    99  	w.Helper()
   100  	w.Log(level, fmt.Sprintln(args...))
   101  }