github.com/jxskiss/gopkg@v0.17.3/zlog/dynamic_level_test.go (about)

     1  package zlog
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"go.uber.org/zap"
    10  	"go.uber.org/zap/zapcore"
    11  )
    12  
    13  func TestDynamicLevelCore(t *testing.T) {
    14  	buf := &bytes.Buffer{}
    15  	logger, _, err := NewWithOutput(&Config{Development: false, Level: "error"}, zapcore.AddSync(buf))
    16  	assert.Nil(t, err)
    17  
    18  	// assert we get a dynamicLevelCore
    19  	_ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
    20  		_, ok := core.(*dynamicLevelCore)
    21  		assert.True(t, ok)
    22  		return core
    23  	}))
    24  
    25  	// the level is "error", these messages won't be logged
    26  	logger.Debug("debug message 1")
    27  	logger.Info("info message 1")
    28  	logger.Warn("warn message 1")
    29  
    30  	// this error message will be logged
    31  	logger.Error("error message 1")
    32  
    33  	got1 := buf.String()
    34  	assert.NotContains(t, got1, "debug message 1")
    35  	assert.NotContains(t, got1, "info message 1")
    36  	assert.NotContains(t, got1, "warn message 1")
    37  	assert.Contains(t, got1, "error message 1")
    38  
    39  	// change level to debug
    40  	logger = B(nil).Base(logger).Level(DebugLevel).Build()
    41  	logger.Debug("debug message 2")
    42  	logger.Info("info message 2")
    43  	logger.Warn("warn message 2")
    44  	logger.Error("error message 2")
    45  
    46  	got2 := buf.String()
    47  	assert.Contains(t, got2, "debug message 2")
    48  	assert.Contains(t, got2, "info message 2")
    49  	assert.Contains(t, got2, "warn message 2")
    50  	assert.Contains(t, got2, "error message 2")
    51  }
    52  
    53  func TestDynamicLevelCore_ChangeLevelWithCtx(t *testing.T) {
    54  	var buf = &bytes.Buffer{}
    55  	var _replace = func(buf *bytes.Buffer) func() {
    56  		cfg := &Config{
    57  			Level: "warn",
    58  			GlobalConfig: GlobalConfig{
    59  				CtxFunc: func(ctx context.Context, args CtxArgs) (result CtxResult) {
    60  					if ctx.Value("level") != nil {
    61  						level := ctx.Value("level").(Level)
    62  						result.Level = &level
    63  					}
    64  					return result
    65  				},
    66  			},
    67  		}
    68  		l, p, err := NewWithOutput(cfg, zapcore.AddSync(buf))
    69  		if err != nil {
    70  			panic(err)
    71  		}
    72  		return ReplaceGlobals(l, p)
    73  	}
    74  	defer _replace(buf)()
    75  
    76  	// the level is "warn", this info message won't be logged
    77  	ctx1 := context.Background()
    78  	WithCtx(ctx1).Info("info message 1")
    79  
    80  	got1 := buf.String()
    81  	assert.NotContains(t, got1, "info message 1")
    82  
    83  	// set level to "info" from ctx, info messages will be logged
    84  	ctx2 := context.WithValue(context.Background(), "level", InfoLevel)
    85  	WithCtx(ctx2).Debug("debug message 2")
    86  	WithCtx(ctx2).Info("info message 2")
    87  
    88  	got2 := buf.String()
    89  	assert.NotContains(t, got2, "debug message 2")
    90  	assert.Contains(t, got2, "info message 2")
    91  }
    92  
    93  var (
    94  	benchmarkMessage = "some test debug message is not too long and not too short"
    95  	benchmarkFields  = []zap.Field{
    96  		zap.String("key1", "value1"),
    97  		zap.String("some_key_2", "some_value2"),
    98  		zap.Int64("some_key_3", 183491839141471),
    99  		zap.Int64s("some_slice_key_4", []int64{18412, 1312490194301, 318431849, 18912438918941}),
   100  	}
   101  )
   102  
   103  func BenchmarkZapIoCore(b *testing.B) {
   104  	logger := newBenchmarkZapIoCoreLogger()
   105  
   106  	b.ResetTimer()
   107  	b.ReportAllocs()
   108  	for i := 0; i < b.N; i++ {
   109  		logger.Debug(benchmarkMessage, benchmarkFields...)
   110  	}
   111  }
   112  
   113  func BenchmarkDynamicLevelCoreOverhead(b *testing.B) {
   114  	logger := newBenchmarkDynamicLevelCoreLogger()
   115  
   116  	b.ResetTimer()
   117  	b.ReportAllocs()
   118  	for i := 0; i < b.N; i++ {
   119  		logger.Debug(benchmarkMessage, benchmarkFields...)
   120  	}
   121  }
   122  
   123  type discardWriter struct{}
   124  
   125  func (w *discardWriter) Write(p []byte) (n int, err error) {
   126  	return len(p), nil
   127  }
   128  
   129  func (w *discardWriter) Sync() error {
   130  	return nil
   131  }
   132  
   133  func newBenchmarkZapIoCoreLogger() *zap.Logger {
   134  	logger, _, err := NewWithOutput(&Config{Development: false, Level: "debug"}, &discardWriter{})
   135  	if err != nil {
   136  		panic(err)
   137  	}
   138  
   139  	// Make sure we unwrap the dynamic level wrapper.
   140  	logger = logger.WithOptions(zap.WrapCore(unwrapDynamicLevelCore))
   141  	_ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
   142  		if _, ok := core.(*dynamicLevelCore); ok {
   143  			panic("core is wrapped by dynamicLevelCore")
   144  		}
   145  		return core
   146  	}))
   147  	return logger
   148  }
   149  
   150  func newBenchmarkDynamicLevelCoreLogger() *zap.Logger {
   151  	logger, _, err := NewWithOutput(&Config{Development: false, Level: "warn"}, &discardWriter{})
   152  	if err != nil {
   153  		panic(err)
   154  	}
   155  
   156  	// Make sure we get a wrapped dynamic level core.
   157  	logger = B(nil).Base(logger).Level(DebugLevel).Build()
   158  	if err != nil {
   159  		panic(err)
   160  	}
   161  	_ = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
   162  		if _, ok := core.(*dynamicLevelCore); !ok {
   163  			panic("core is not wrapped by dynamicLevelCore")
   164  		}
   165  		return core
   166  	}))
   167  	return logger
   168  }