-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix new writer in logx #4311
base: master
Are you sure you want to change the base?
fix new writer in logx #4311
Conversation
Thanks for your contribution! But this is a breaking change. And please add unit tests. |
Add NewAsyncWriter function to avoid affecting previous code. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files
|
Merge this PR later. Let's figure out if it's possible to fix the problem with the same method Would you please give a simple example to reproduce the problem? |
NewWriter has two main issues.
1. NewWriter uses log.New to wrap the original writer, and use log.Print to write data, log package use a sync.Pool to get *[]byte when write data. If the original writer does not write the data immediately, but processes it asynchronously, this can result in duplicate ([]byte reuse) or no write ([]byte reset) of the data actually written.
2. Ignores the Close() method of raw writer, If raw writer has asynchronous processing, the cleanup logic in the Close() method will not be executed properly, which may result in data loss.
Simply replacing NewAyncWriter with NewWriter for the unit test in this commit will reproduce the problem and the test will fail.
… 2024年8月27日 22:19,Kevin Wan ***@***.***> 写道:
Merge this PR later. Let's figure out if it's possible to fix the problem with the same method NewWriter.
Would you please give a simple example to reproduce the problem?
—
Reply to this email directly, view it on GitHub <#4311 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAJTM3GB677YQ62CZRWJSHLZTSDHHAVCNFSM6AAAAABMH5YMHKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJSG4YDOOBRHA>.
You are receiving this because you authored the thread.
|
NewWriter 方法用于自定义 logx 的 Writer,例如:
NewWriter method is used to customize logx's Writer, e.g.:
但当前的 logx.NewWriter 使用 log.New 和 logx.newLogWriter 对传入的自定义 writer 进行了包装;
实际调用时,调用路径为,log.Print -> log.output -> writer.Write;
这会导致一系列问题,因为 log 库中使用了 sync.Pool 产生 *[]byte 用于拼接字符串;
如果自定义 writer 是同步写入,则可能不会出现问题;
如果自定义 writer 是异步写入,如使用 chan 来实现并发安全,这时实际传入 writer.Write 的 []byte 可能具有同一地址,造成写入重复内容;
并且 logx.newLogWriter 函数还忽略了自定义 writer 的 Close 方法;
通过修改 logx.NewWriter 方法,直接传入 io.WriteCloser,可以避免这些问题;
在实际测试中也是符合预期的;
When it is actually called, the path is log.Print -> log.output -> writer.Write;
This will lead to some problems, the std log library uses sync.Pool to generate *[]byte for string splicing;
If the custom writer writes synchronously, there may not be a problem;
But if the custom writer writes asynchronously, e.g., using chan for concurrency safety, the []byte that is actually passed to writer.Write may have the same address, resulting in duplicate content being written;
And logx.newLogWriter function also ignores the Close method of the custom writer;
These problems can be avoided by modifying the logx.NewWriter method and passing in io.WriteCloser directly;
It also meets the expectation in the actual test;