-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
grpclog: change logger to avoid Printf when the logger is io.Discard #7471
base: master
Are you sure you want to change the base?
Conversation
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #7471 +/- ##
==========================================
+ Coverage 81.73% 81.83% +0.10%
==========================================
Files 361 361
Lines 27817 27833 +16
==========================================
+ Hits 22735 22776 +41
+ Misses 3871 3850 -21
+ Partials 1211 1207 -4
|
463f9b1
to
ae6fd53
Compare
bf693df
to
bd9603c
Compare
bd9603c
to
2da6dee
Compare
2242738
to
1184eb7
Compare
Adding @dfawley as 2nd reviewer |
0da4704
to
7bb19d4
Compare
Changes the logger to not call Printf when the logger is io.Discard. Also changes the logger constructor to use io.Discard instead of io.MultiWriter(io.Discard, io.Discard), which is necessary to detect all levels being discarded. Fixes grpc#7463
7bb19d4
to
2bf7f34
Compare
Ok, I think I addressed all the comments again. Let me know if I missed anything. Also, the PR started failing a new Github check for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Is there anything else I need to do for this to be merged? |
Doug is reviewing it. Nothing is needed from you right now. |
Apologies; I have a lot on my plate right now, but will try to get to this in the next week or so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR and sorry again for the delay.
func (g *loggerT) output(severity int, s string) { | ||
// printFunc prints the output of fn to the logger of the given severity. | ||
// If the logger at given severity is io.Discard, fn is not called. | ||
func (g *loggerT) printFunc(severity int, fn func() string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The closure here seems unfortunate, and I think this approach has performance impacts for non-Discard use cases (creating the closure and the call to concatenate the strings inside if !g.jsonFormat
).
Can we keep output
and add an outputf
that duplicates the io.Discard
check, and avoids the closure and different formatting?
warnLogW := io.Discard | ||
if warningW != io.Discard || infoW != io.Discard { | ||
warnLogW = io.MultiWriter(infoW, warningW) | ||
} | ||
|
||
errLogW := io.Discard | ||
if errorW != io.Discard || warningW != io.Discard || infoW != io.Discard { | ||
errLogW = io.MultiWriter(infoW, warningW, errorW) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could optimize this a bit, and make it easier to read as well?
// Returns a combined logger for both higher & lower severity logs, or higher only if lower is io.Discard.
func combineLoggers(lower, higher io.Writer) io.Writer {
if lower == io.Discard || higher == io.Discard {
return higher
}
return io.MultiWriter(lower, higher)
}
func NewLoggerV2(..) {
// ...
// Just overwrite instead of creating new locals with different names:
warningW = combineLoggers(infoW, warningW)
errorW = combineLoggers(warningW, errorW)
}
This ends up with 2 nested multiwriters if you have 3 different loggers, but that's probably fairly uncommon, and would be no worse than the behavior this PR adds of creating a multiwriter for (warningW, io.Discard)
if infoW
is io.Discard
.
This PR is labeled as requiring an update from the reporter, and no update has been received after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed. |
Sorry, I was on vacation last week. I'll try to address the comments sometime this week |
Changes the logger to not call Printf when the logger is io.Discard.
Also changes the logger constructor to use
io.Discard
instead ofio.MultiWriter(io.Discard, io.Discard)
, which is necessary to detect all levels being discarded.This is a significant performance improvement for disabled logs, see #7463 for details.
Notes:
log.Printf
itself, but I don't think that's possible, because the JSON option needs to Printf and then escape the result after interpolating, which I don't think is possible with what's exposed by the std (possibly sans some overly complex io.Writer interceptors).log.Printf
for the non-JSON, but there's not much point if we can't use it for the JSON, and it would incur an unnecessary atomic call.io.Discard
logic could be made faster (e.g. with more nested if's), and could do smarter things around the discard/multiwriter. I wrote it this way for readability, and because I don't think the performance is significant. But I'm happy to change it.Fixes #7463
RELEASE NOTES: