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

     1  package log_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"regexp"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/line/ostracon/libs/log"
    14  )
    15  
    16  func TestZeroLogLoggerLogsItsErrors(t *testing.T) {
    17  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	filepath := dir + "/app.log"
    22  
    23  	var buf bytes.Buffer
    24  	config := log.NewZeroLogConfig(true, "*:info", filepath, 0, 100, 0)
    25  	logger, err := log.NewZeroLogLogger(config, &buf)
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  	logger.Info("foo", "baz baz", "bar")
    30  
    31  	msg := strings.TrimSpace(buf.String())
    32  	if !strings.Contains(msg, "foo") {
    33  		t.Errorf("expected logger msg to contain ErrInvalidKey, got %s", msg)
    34  	}
    35  
    36  	str, err := ioutil.ReadFile(filepath)
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	if !strings.Contains(string(str), "foo") {
    41  		t.Errorf("expected file logger msg to contain ErrInvalidKey, got %s", msg)
    42  	}
    43  }
    44  
    45  func TestZeroLogInfo(t *testing.T) {
    46  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  	filepath := dir + "/app.log"
    51  
    52  	var buf bytes.Buffer
    53  	config := log.NewZeroLogConfig(true, "*:info", filepath, 0, 100, 0)
    54  	logger, err := log.NewZeroLogLogger(config, &buf)
    55  	if err != nil {
    56  		t.Fatal(err)
    57  	}
    58  	logger.Info("Client initialized with old header (trusted is more recent)",
    59  		"old", 42,
    60  		"trustedHeight", "forty two",
    61  		"trustedHash", fmt.Sprintf("%x", []byte("test me")))
    62  
    63  	msg := strings.TrimSpace(buf.String())
    64  	msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
    65  	const expectedMsg = `Client initialized with old header (trusted is more recent) old=42 trustedHash=74657374206d65 trustedHeight="forty two"`
    66  	if !strings.Contains(msg, expectedMsg) {
    67  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
    68  	}
    69  
    70  	str, err := ioutil.ReadFile(filepath)
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	msg = strings.TrimSpace(string(str))
    75  	if !strings.Contains(msg, expectedMsg) {
    76  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
    77  	}
    78  }
    79  
    80  func TestZeroLogDebug(t *testing.T) {
    81  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	filepath := dir + "/app.log"
    86  
    87  	var buf bytes.Buffer
    88  	config := log.NewZeroLogConfig(true, "*:debug", filepath, 0, 100, 0)
    89  	logger, err := log.NewZeroLogLogger(config, &buf)
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  	logger.Debug("Client initialized with old header (trusted is more recent)",
    94  		"old", 42,
    95  		"trustedHeight", "forty two",
    96  		"trustedHash", fmt.Sprintf("%x", []byte("test me")))
    97  
    98  	msg := strings.TrimSpace(buf.String())
    99  	msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   100  	const expectedMsg = `Client initialized with old header (trusted is more recent) old=42 trustedHash=74657374206d65 trustedHeight="forty two"`
   101  	if !strings.Contains(msg, expectedMsg) {
   102  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
   103  	}
   104  
   105  	str, err := ioutil.ReadFile(filepath)
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	msg = strings.TrimSpace(string(str))
   110  	if !strings.Contains(msg, expectedMsg) {
   111  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
   112  	}
   113  }
   114  
   115  func TestZeroLogError(t *testing.T) {
   116  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	filepath := dir + "/app.log"
   121  
   122  	var buf bytes.Buffer
   123  	config := log.NewZeroLogConfig(true, "*:error", filepath, 0, 100, 0)
   124  	logger, err := log.NewZeroLogLogger(config, &buf)
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	logger.Error("Client initialized with old header (trusted is more recent)",
   129  		"old", 42,
   130  		"trustedHeight", "forty two",
   131  		"trustedHash", fmt.Sprintf("%x", []byte("test me")))
   132  
   133  	msg := strings.TrimSpace(buf.String())
   134  	msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   135  	const expectedMsg = `Client initialized with old header (trusted is more recent) old=42 trustedHash=74657374206d65 trustedHeight="forty two"`
   136  	if !strings.Contains(msg, expectedMsg) {
   137  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
   138  	}
   139  
   140  	str, err := ioutil.ReadFile(filepath)
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	msg = strings.TrimSpace(string(str))
   145  	if !strings.Contains(msg, expectedMsg) {
   146  		t.Fatalf("received %s, expected %s", msg, expectedMsg)
   147  	}
   148  }
   149  
   150  func TestZeroLogLevelForModules(t *testing.T) {
   151  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	filepath := dir + "/app.log"
   156  
   157  	var buf bytes.Buffer
   158  	config := log.NewZeroLogConfig(true, "module1:debug,module2:info,*:error", filepath, 0, 100, 0)
   159  	logger, err := log.NewZeroLogLogger(config, &buf)
   160  	if err != nil {
   161  		t.Fatal(err)
   162  	}
   163  
   164  	// logger level = debug
   165  	// debug O, info O, error O
   166  	{
   167  		loggerForModule1 := logger.With("module", "module1")
   168  
   169  		// debug O
   170  		loggerForModule1.Debug("a1", "b1", "c1")
   171  		msg := strings.TrimSpace(buf.String())
   172  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   173  		expectedMsg := "a1 b1=c1"
   174  		if !strings.Contains(msg, expectedMsg) {
   175  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   176  		}
   177  		str, err := ioutil.ReadFile(filepath)
   178  		if err != nil {
   179  			t.Fatal(err)
   180  		}
   181  		msg = strings.TrimSpace(string(str))
   182  		if !strings.Contains(msg, expectedMsg) {
   183  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   184  		}
   185  
   186  		// info O
   187  		loggerForModule1.Info("a2", "b2", "c2")
   188  		msg = strings.TrimSpace(buf.String())
   189  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   190  		expectedMsg = "a2 b2=c2"
   191  		if !strings.Contains(msg, expectedMsg) {
   192  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   193  		}
   194  		str, err = ioutil.ReadFile(filepath)
   195  		if err != nil {
   196  			t.Fatal(err)
   197  		}
   198  		msg = strings.TrimSpace(string(str))
   199  		if !strings.Contains(msg, expectedMsg) {
   200  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   201  		}
   202  
   203  		// error O
   204  		loggerForModule1.Error("a3", "b3", "c3")
   205  		msg = strings.TrimSpace(buf.String())
   206  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   207  		expectedMsg = "a3 b3=c3"
   208  		if !strings.Contains(msg, expectedMsg) {
   209  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   210  		}
   211  		str, err = ioutil.ReadFile(filepath)
   212  		if err != nil {
   213  			t.Fatal(err)
   214  		}
   215  		msg = strings.TrimSpace(string(str))
   216  		if !strings.Contains(msg, expectedMsg) {
   217  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   218  		}
   219  	}
   220  
   221  	// logger level = info
   222  	// debug X, info O, error O
   223  	{
   224  		loggerForModule2 := logger.With("module", "module2")
   225  
   226  		// debug X
   227  		loggerForModule2.Debug("a4", "b4", "c4")
   228  		msg := strings.TrimSpace(buf.String())
   229  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   230  		expectedMsg := "a4 b4=c4"
   231  		if strings.Contains(msg, expectedMsg) {
   232  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   233  		}
   234  		str, err := ioutil.ReadFile(filepath)
   235  		if err != nil {
   236  			t.Fatal(err)
   237  		}
   238  		msg = strings.TrimSpace(string(str))
   239  		if strings.Contains(msg, expectedMsg) {
   240  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   241  		}
   242  
   243  		// info O
   244  		loggerForModule2.Info("a5", "b5", "c5")
   245  		msg = strings.TrimSpace(buf.String())
   246  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   247  		expectedMsg = "a5 b5=c5"
   248  		if !strings.Contains(msg, expectedMsg) {
   249  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   250  		}
   251  		str, err = ioutil.ReadFile(filepath)
   252  		if err != nil {
   253  			t.Fatal(err)
   254  		}
   255  		msg = strings.TrimSpace(string(str))
   256  		if !strings.Contains(msg, expectedMsg) {
   257  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   258  		}
   259  
   260  		// error O
   261  		loggerForModule2.Error("a6", "b6", "c6")
   262  		msg = strings.TrimSpace(buf.String())
   263  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   264  		expectedMsg = "a6 b6=c6"
   265  		if !strings.Contains(msg, expectedMsg) {
   266  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   267  		}
   268  		str, err = ioutil.ReadFile(filepath)
   269  		if err != nil {
   270  			t.Fatal(err)
   271  		}
   272  		msg = strings.TrimSpace(string(str))
   273  		if !strings.Contains(msg, expectedMsg) {
   274  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   275  		}
   276  	}
   277  
   278  	// logger level = error
   279  	// debug X, info X, error O
   280  	{
   281  		loggerForModule3 := logger.With("module", "module3")
   282  
   283  		// debug X
   284  		loggerForModule3.Debug("a7", "b7", "c7")
   285  		msg := strings.TrimSpace(buf.String())
   286  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   287  		expectedMsg := "a7 b7=c7"
   288  		if strings.Contains(msg, expectedMsg) {
   289  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   290  		}
   291  		str, err := ioutil.ReadFile(filepath)
   292  		if err != nil {
   293  			t.Fatal(err)
   294  		}
   295  		msg = strings.TrimSpace(string(str))
   296  		if strings.Contains(msg, expectedMsg) {
   297  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   298  		}
   299  
   300  		// info X
   301  		loggerForModule3.Info("a8", "b8", "c8")
   302  		msg = strings.TrimSpace(buf.String())
   303  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   304  		expectedMsg = "a8 b8=c8"
   305  		if strings.Contains(msg, expectedMsg) {
   306  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   307  		}
   308  		str, err = ioutil.ReadFile(filepath)
   309  		if err != nil {
   310  			t.Fatal(err)
   311  		}
   312  		msg = strings.TrimSpace(string(str))
   313  		if strings.Contains(msg, expectedMsg) {
   314  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   315  		}
   316  
   317  		// error O
   318  		loggerForModule3.Error("a9", "b9", "c9")
   319  		msg = strings.TrimSpace(buf.String())
   320  		msg = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`).ReplaceAllString(msg, "")
   321  		expectedMsg = "a9 b9=c9"
   322  		if !strings.Contains(msg, expectedMsg) {
   323  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   324  		}
   325  		str, err = ioutil.ReadFile(filepath)
   326  		if err != nil {
   327  			t.Fatal(err)
   328  		}
   329  		msg = strings.TrimSpace(string(str))
   330  		if !strings.Contains(msg, expectedMsg) {
   331  			t.Fatalf("received %s, expected %s", msg, expectedMsg)
   332  		}
   333  	}
   334  }
   335  
   336  func TestZeroLogRotateFiles(t *testing.T) {
   337  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  	filepath := dir + "/app.log"
   342  
   343  	var buf bytes.Buffer
   344  	config := log.NewZeroLogConfig(true, "*:info", filepath, 1, 1, 2)
   345  	logger, err := log.NewZeroLogLogger(config, &buf)
   346  	if err != nil {
   347  		t.Fatal(err)
   348  	}
   349  
   350  	// it writes more than 1M logs so that two log files are created
   351  	msg := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
   352  	for i := 0; i < 6000; i++ {
   353  		logger.Info(msg)
   354  	}
   355  
   356  	// check if only two log files is created
   357  	// ex) app.log, app-2022-12-16T10-21-41.295.log
   358  	files, err := ioutil.ReadDir(dir)
   359  	if err != nil {
   360  		t.Fatal(err)
   361  	}
   362  	if len(files) != 2 {
   363  		t.Fatalf("file count created %d, expected %d", len(files), 2)
   364  	}
   365  
   366  	// change the filename of the backed up log file to one created 2 days ago
   367  	// ex) app-2022-12-16T10-21-41.295.log -> app-2022-12-14T10-21-41.295.log
   368  	now := time.Now().Add(-time.Hour * 48)
   369  	filename2 := fmt.Sprintf("app-%d-%02d-%02dT%02d-%02d-%02d.000.log", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
   370  	for _, f := range files {
   371  		if f.Name() == "app.log" {
   372  			continue
   373  		}
   374  
   375  		err = os.Rename(dir+"/"+f.Name(), dir+"/"+filename2)
   376  		if err != nil {
   377  			t.Fatalf("file rename failed old filename: %s, new filename: %s", dir+"/"+f.Name(), dir+"/"+filename2)
   378  		}
   379  	}
   380  
   381  	// write new logs for rotating log file(remove old log file)
   382  	// ex) app.log, app-2022-12-16T10-21-43.374.log
   383  	for i := 0; i < 6000; i++ {
   384  		logger.Info(msg)
   385  	}
   386  
   387  	// check if old log file is removed
   388  	files, err = ioutil.ReadDir(dir)
   389  	if err != nil {
   390  		t.Fatal(err)
   391  	}
   392  	if len(files) != 2 {
   393  		t.Fatalf("created %d, expected %d", len(files), 2)
   394  	}
   395  	for _, f := range files {
   396  		if f.Name() == filename2 {
   397  			t.Fatalf("The log file has not been removed yet")
   398  		}
   399  	}
   400  }
   401  
   402  func BenchmarkZeroLogLoggerSimple(b *testing.B) {
   403  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
   404  	if err != nil {
   405  		b.Fatal(err)
   406  	}
   407  	filepath := dir + "/app.log"
   408  
   409  	var buf bytes.Buffer
   410  	config := log.NewZeroLogConfig(true, "*:info", filepath, 0, 100, 0)
   411  	logger, err := log.NewZeroLogLogger(config, &buf)
   412  	if err != nil {
   413  		b.Fatal(err)
   414  	}
   415  
   416  	benchmarkRunner(b, logger, baseInfoMessage)
   417  }
   418  
   419  func BenchmarkZeroLogLoggerContextual(b *testing.B) {
   420  	dir, err := ioutil.TempDir("/tmp", "zerolog-test")
   421  	if err != nil {
   422  		b.Fatal(err)
   423  	}
   424  	filepath := dir + "/app.log"
   425  
   426  	var buf bytes.Buffer
   427  	config := log.NewZeroLogConfig(true, "*:info", filepath, 0, 100, 0)
   428  	logger, err := log.NewZeroLogLogger(config, &buf)
   429  	if err != nil {
   430  		b.Fatal(err)
   431  	}
   432  
   433  	benchmarkRunner(b, logger, withInfoMessage)
   434  }