github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/libs/log/ocfmt_logger_test.go (about)

     1  package log_test
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"math"
     8  	"regexp"
     9  	"testing"
    10  
    11  	kitlog "github.com/go-kit/log"
    12  	"github.com/stretchr/testify/assert"
    13  
    14  	"github.com/line/ostracon/libs/log"
    15  )
    16  
    17  func TestOCFmtLogger(t *testing.T) {
    18  	t.Parallel()
    19  	buf := &bytes.Buffer{}
    20  	logger := log.NewOCFmtLogger(buf)
    21  
    22  	if err := logger.Log("hello", "world"); err != nil {
    23  		t.Fatal(err)
    24  	}
    25  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ hello=world\n$`), buf.String())
    26  
    27  	buf.Reset()
    28  	if err := logger.Log("a", 1, "err", errors.New("error")); err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ a=1 err=error\n$`), buf.String())
    32  
    33  	buf.Reset()
    34  	if err := logger.Log("std_map", map[int]int{1: 2}, "my_map", mymap{0: 0}); err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ std_map=map\[1:2\] my_map=special_behavior\n$`), buf.String())
    38  
    39  	buf.Reset()
    40  	if err := logger.Log("level", "error"); err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	assert.Regexp(t, regexp.MustCompile(`E\[.+\] unknown \s+\n$`), buf.String())
    44  
    45  	buf.Reset()
    46  	if err := logger.Log("_msg", "Hello"); err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] Hello \s+\n$`), buf.String())
    50  
    51  	buf.Reset()
    52  	if err := logger.Log("module", "main", "module", "crypto", "module", "wire"); err != nil {
    53  		t.Fatal(err)
    54  	}
    55  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+module=wire\s+\n$`), buf.String())
    56  
    57  	buf.Reset()
    58  	if err := logger.Log("hash", []byte("test me")); err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ hash=74657374206D65\n$`), buf.String())
    62  }
    63  
    64  func BenchmarkOCFmtLoggerSimple(b *testing.B) {
    65  	benchmarkRunnerKitlog(b, log.NewOCFmtLogger(io.Discard), baseMessage)
    66  }
    67  
    68  func BenchmarkOCFmtLoggerContextual(b *testing.B) {
    69  	benchmarkRunnerKitlog(b, log.NewOCFmtLogger(io.Discard), withMessage)
    70  }
    71  
    72  func TestOCFmtLoggerConcurrency(t *testing.T) {
    73  	t.Parallel()
    74  	testConcurrency(t, log.NewOCFmtLogger(io.Discard), 10000)
    75  }
    76  
    77  func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Logger)) {
    78  	lc := kitlog.With(logger, "common_key", "common_value")
    79  	b.ReportAllocs()
    80  	b.ResetTimer()
    81  	for i := 0; i < b.N; i++ {
    82  		f(lc)
    83  	}
    84  }
    85  
    86  var (
    87  	baseMessage = func(logger kitlog.Logger) { logger.Log("foo_key", "foo_value") }          //nolint:errcheck
    88  	withMessage = func(logger kitlog.Logger) { kitlog.With(logger, "a", "b").Log("d", "f") } //nolint:errcheck
    89  )
    90  
    91  // These test are designed to be run with the race detector.
    92  
    93  func testConcurrency(t *testing.T, logger kitlog.Logger, total int) {
    94  	n := int(math.Sqrt(float64(total)))
    95  	share := total / n
    96  
    97  	errC := make(chan error, n)
    98  
    99  	for i := 0; i < n; i++ {
   100  		go func() {
   101  			errC <- spam(logger, share)
   102  		}()
   103  	}
   104  
   105  	for i := 0; i < n; i++ {
   106  		err := <-errC
   107  		if err != nil {
   108  			t.Fatalf("concurrent logging error: %v", err)
   109  		}
   110  	}
   111  }
   112  
   113  func spam(logger kitlog.Logger, count int) error {
   114  	for i := 0; i < count; i++ {
   115  		err := logger.Log("key", i)
   116  		if err != nil {
   117  			return err
   118  		}
   119  	}
   120  	return nil
   121  }
   122  
   123  type mymap map[int]int
   124  
   125  func (m mymap) String() string { return "special_behavior" }