Currently TiDB CI reports contain a large number of logs redundant, see this example.
Such large number of logs is unnecessary burden for CI. Most open source projects turn off logging in test environment and retain only the failed cases info. One can turn on logging locally, debug and push a fix. CI only verifies whether the case is recovered.
I’m unfamiliar with TiDB log configuration, but notice a log refactor is happening. Maybe we can join force and enable turning off redundant logging in TiDB tests.
TiDB CI calls make to run test. And logging is configured in makefile under gotest command.
There are many hack code in TiDB tests. These tests read env directly then pass to log initializer. Just search the whole project with “os.Getenv(“log_level”)”.
Attention: These hack code won’t affect production logging logic. Users config TiDB log with config file and cmd parameter, but not env variables.
To fix too-many-log issue in CI, simply modify these two line:
This is because there are non-deterministic tests in TiDB: some developers using sleep or random number in unit tests. When these tests failed, it may not be easy to reproduce. The log is useful to analyze the problem.
also passthrough logger is not easy in go(compare with java’s MDC )…we tried context.Context but it often lost in some logic(e.g. some ddl code) which make zaptest like solution hard to work
Instead of logging everything and search for the problem when some non-deterministic test case fails, can we do things smarter, like only preserve those logs of failed test cases?
type testingWriter struct {
t TestingT
markFailed bool
}
func newTestingWriter(t TestingT) testingWriter {
return testingWriter{t: t}
}
// WithMarkFailed returns a copy of this testingWriter with markFailed set to
// the provided value.
func (w testingWriter) WithMarkFailed(v bool) testingWriter {
w.markFailed = v
return w
}
func (w testingWriter) Write(p []byte) (n int, err error) {
n = len(p)
// Strip trailing newline because t.Log always adds one.
p = bytes.TrimRight(p, "\n")
// Note: t.Log is safe for concurrent use.
w.t.Logf("%s", p)
if w.markFailed {
w.t.Fail()
}
return n, nil
}
func (w testingWriter) Sync() error {
return nil
}
we’d better factor out WriteSyncer parameter of InitLoggerWithWriteSyncer and expose builder for both
Yep. We use log.ReplaceGlobals to modify global logger. It is really brittle. But we can first export the customize ability to WriteSyncer so that we can prevent unnecessary logging for successful tests.