-
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
Improve Logger Performance When Disabled #7463
Comments
This particular log should probably just be moved behind V(2). @zasweq can you take care of it? |
I'm fine with this idea as well, but that won't solve all our problems, either. We have had other cases recently where the logged data needs to be computed from a function call that is expensive for whatever reason. We should be very careful about what we log by default (verbosity 0). |
Sent #7467 to wrap in a verbosity check. |
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
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
@rob05c If you are still at all interested in creating a PR to make |
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Use case(s) - what problem will this feature solve?
We're seeing a large memory increase when enabling
grpc-go/xds
on a service, of a sustained ~100mb or about double the previous usage.We tracked it down to this log line: https://github.com/grpc/grpc-go/blob/8bf2b3ee/balancer/leastrequest/leastrequest.go#L115
Which, for our environment, is creating a single 48kb line.
We don't have Info logging enabled. We have traces indicating the memory usage is from
Printf
, and is being called by the log library regardless if logging is enabled, here: https://github.com/grpc/grpc-go/blob/fbff2abb/grpclog/loggerv2.go#L194Proposed Solution
I propose changing
grpc-go/grpclog
to not callPrintf
if the logger isio.Discard
. I believe this can be done safely and without changing the interface, in manner similar to how the standardlog
package does it here.For what it's worth, I've personally seen this problem in the past, and saw a large performance improvement at scale, both memory and CPU, doing a very similar fix in a similar log library in Apache Traffic Control here. Unlike C, Go
Printf
is quite expensive because it uses Reflection. Simple benchmarking showsPrintf
is about 20x slower thanstrconv.Atoi
for an int, and can be enormous for structs.If you agree, I'm happy to make a PR.
Alternatives Considered
We might also consider removing that log line. I don't have context for why it was added, or how useful it is. If the consensus is to remove it, I'm happy to make that PR as well. But I believe the issue will likely just recur elsewhere, and the deeper issue is incurring the
Printf
cost for disabled logs, and would very much like to fix it there.Additional Context
The text was updated successfully, but these errors were encountered: