-
-
Notifications
You must be signed in to change notification settings - Fork 209
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
refactor: config.Duration
, and config use and printing
#920
refactor: config.Duration
, and config use and printing
#920
Conversation
Allows directly calling `time.Duration` methods.
The idea is to make adding configuration options easier, and searching for references straight forward.
Using a logger allows using multiple levels so the whole configuration can be printed in trace/verbose mode, but only important parts are shown by default.
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #920 +/- ##
==========================================
- Coverage 92.87% 92.85% -0.03%
==========================================
Files 49 63 +14
Lines 5378 5389 +11
==========================================
+ Hits 4995 5004 +9
Misses 311 311
- Partials 72 74 +2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
server/server.go
Outdated
@@ -443,8 +443,17 @@ func (s *Server) printConfiguration() { | |||
for res != nil { | |||
logger().Infof("-> resolver: '%s'", resolver.Name(res)) | |||
|
|||
for _, c := range res.Configuration() { | |||
logger().Infof(" %s", c) | |||
if resCfg, ok := res.(resolver.ConfigGetter); ok { |
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 the idea here is to replace "Configuration" with new "LogValues" method in all resolvers?
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.
Yeah exactly, just did it to a single resolver as a proof of concept for now.
The ConfigGetter
interface would not exist, and we'd have the Cfg
method directly in Resolver
instead of the current Configuration
.
I could also rename Cfg
to Configuration
since that name would be free.
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 removed ConfigGetter
and just went with config.Configurable
(which is the new name for ValueLogger
).
With that rename, I added IsEnabled() bool
to the interface.
Cfg()
was replaced by LogConfig(*logrus.Entry)
. That allows having a single interface that covers both the config types, and the resolvers.
server/server.go
Outdated
if resCfg, ok := res.(resolver.ConfigGetter); ok { | ||
func() { | ||
undo := log.PrefixMessages(" ", logger().Logger) | ||
defer undo() |
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.
Is it possible to create a new logger instance with prefix formatter? I mean a new instance only for configuration logging. I think, it is a bit "dangerous" to modify the existing instance and to rollback this change after usage. Later someone can use this logic somewhere else and forget to call the undo function.
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.
Yeah I can do that too, this was just a bit easier with the existing log
code!
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.
So I tried changing this, but using a new logger loses stuff like fields that were added.
I changed the API to be impossible to misuse though, so hopefully that solves the issue with another approach!
Edit: also using the existing logger allows nesting the prefixes, which I've used in config/blocking.go
.
Good job, thank you 👍 🤝
I think, we should unify all resolver implementation (like config printing etc).
Please see my review comments.
In your case, it is absolutely ok to use the host configuration directly. We should avoid to pass a reference to the whole configuration to a resolver to avoid some side effects (for example a resolver A changes a value directly in the config and resolver B uses it). The configuration handling must be reworked completely for dynamic reloading. I though we need something like a service which provides the configuration and notifies about changes. That means each resolver calls something like "configService.getConfiguration" and receives current configuraiton...
That looks reasonable, please check my comment regarding the logger instance. Please also keep in mind, the "old" Configuration function in each resolver has not only printed the configuration, but also the internal state (like count of elements in cache).
👍 |
Thanks for taking a look so fast, I'll make the changes you proposed and do more resolvers! |
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.
Updated all resolvers, their configs and all tests!
server/server.go
Outdated
if resCfg, ok := res.(resolver.ConfigGetter); ok { | ||
func() { | ||
undo := log.PrefixMessages(" ", logger().Logger) | ||
defer undo() |
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.
So I tried changing this, but using a new logger loses stuff like fields that were added.
I changed the API to be impossible to misuse though, so hopefully that solves the issue with another approach!
Edit: also using the existing logger allows nesting the prefixes, which I've used in config/blocking.go
.
061c2a5
to
5943434
Compare
5943434
to
47de06b
Compare
I'm in favor of the new structure. 👍 |
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.
Enhances readability & streamlines functionality 👍
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.
Great Job! Looks very clean 🚀 👍
I started these changes while working the hosts file resolver, and wanted to make a PR before I do the same to other resolvers, if there's interest.
The
config.Duration
change is to try and make using the type easier: with an embed all original methods are available.The tradeoffs are:
struct { x Duration `default:"\"1h\""` }
time.Duration
is a bit less explicit:x.Cast()
vstime.Duration(x)
. That could bex.Duration
, but I thought that was awkward to read (ex:cfg.ConnectionCooldown.Duration
).That first change allowed me to not copy the values out of the
config.HostsFileConfig
into theHostsFileResolver
since using theconfig.Duration
directly is easy.I think this is nice because it makes adding config options faster. And finding all references to an option/renaming it is instant. Depending on how we end up doing config reloading, it could help too: update a single field and trigger a refresh.
The config printing I moved to the config struct itself, instead of the resolver. And changed it to print via a logger instead of returning an array.
I think that's valuable so we can make what's shown more or less verbose depending on the log level.
Let me know if what's of interest, if any, and I can adapt the PR.
The first change can be merged as is. The other two, I'd apply the idea to more resolvers.
I also didn't take the time to fix the tests for the third change.