-
Notifications
You must be signed in to change notification settings - Fork 549
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: remove trivial DEFAULT_CONFIG from instrumentation #2217
Conversation
I made sure to check every usage of such an property and verified it will handle |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2217 +/- ##
==========================================
- Coverage 90.97% 90.38% -0.60%
==========================================
Files 146 147 +1
Lines 7492 7497 +5
Branches 1502 1571 +69
==========================================
- Hits 6816 6776 -40
- Misses 676 721 +45
|
@@ -104,7 +95,7 @@ export class BunyanInstrumentation extends InstrumentationBase { | |||
} | |||
|
|||
override setConfig(config: BunyanInstrumentationConfig = {}) { | |||
this._config = Object.assign({}, DEFAULT_CONFIG, config); | |||
this._config = config; |
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.
One change here (and in the constructor above) is that the given config
object is no longer a copy. A subsequent change to that passed in config object could unexpectedly have an impact here.
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.
Nice catch. Fixed (in memcahed as well).
The constructor does not need to shallow copy the config, as it is already done in the constructor of InstrumentationBase
const DEFAULT_CONFIG: BunyanInstrumentationConfig = { | ||
disableLogSending: false, | ||
disableLogCorrelation: false, | ||
}; |
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.
There is some value in being explicit about the defaults. Instead of it clearly being a boolean value, the maintainer of the code needs to think about handling the undefined
value. That's reasonably easy for booleans. However, is the same true for the depth: -1
in instr-graphql? Is if (config.depth >= 0 && config.depth < depth)
immediately obvious to you when config.depth
is undefined?
I guess arguably the code already should have been handling undefined
values given the Config types all define the config vars as optional. Hrm.
In the Apache voting sense, I'm -0 on this change. I.e., I won't block this, but I'm not convinced of the value of the change.
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.
There is some value in being explicit about the defaults. Instead of it clearly being a boolean value, the maintainer of the code needs to think about handling the
undefined
value.
I think it's a style decision that we need to take and apply to all instrumentations. Should we explicitly state the defaults even in the trivial case (assuming undefined
is used as a Truty comparison that treats it as false
. Or should we omit the default values when trivial. I think we should keep the code lean and clean and avoid unnecessary complexity when possible. But I am open to changing that if there is a preference to be explicit about default values.
That's reasonably easy for booleans. However, is the same true for the
depth: -1
in instr-graphql? Isif (config.depth >= 0 && config.depth < depth)
immediately obvious to you whenconfig.depth
is undefined
The way I see it, is that the current code that says (config.depth >= 0 && config.depth < depth)
allows itself not to check for undefined
since we already made it a number with DEFAULT_CONFIG
. While it works, it's not immediate from reading this line why we do not check the undefined
case, and I think it's cleaner and more readable to verify empty values once when used instead of splitting the logic into 2 dependent parts.
This practice is also not type-safe (I think) as we access a property of type number | undefined
and treat if as a number
.
In the Apache voting sense, I'm -0 on this change. I.e., I won't block this, but I'm not convinced of the value of the change.
I hope the arguments above helped you be more convinced. I am happy to discuss any code style alternative and decide on the best convention, and then make all instrumentations consistent with the agreed-upon style.
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.
If I can have a pony :) what I'd want as an instrumentation maintainer is this._config
(or .getConfig()
or whatever API) to give me a config object that has a known type and valid value for every config var. In "type-speak", I'd want separate types for BunyanInstrumentationConfig (with disableLogSending: boolean
) and BunyanInstrumentationConstructorOptions (with disableLogSending?: boolean
, i.e. can be undefined).
At least that is the mental model I had when using DEFAULT_CONFIG
. It means that config is resolved at the API points where config can be provided, and the rest of the code does not need to worry about invalid values. In systems with more complex config, doing all the validation at these API points is the lean and clean path.
Here invalid
could mean more than an undefined or empty value. E.g. a JavaScript user of instrumentation-bunyan could pass in new BunyanInstrumentation({disableLogSending: "yes"})
.
However, I'm not advocating doing all that now. I expect instrumentation config code to have to adapt a bit for coming file-config work.
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.
If I can have a pony :) what I'd want as an instrumentation maintainer is
this._config
(or.getConfig()
or whatever API) to give me a config object that has a known type and valid value for every config var. In "type-speak", I'd want separate types for BunyanInstrumentationConfig (withdisableLogSending: boolean
) and BunyanInstrumentationConstructorOptions (withdisableLogSending?: boolean
, i.e. can be undefined).At least that is the mental model I had when using
DEFAULT_CONFIG
. It means that config is resolved at the API points where config can be provided, and the rest of the code does not need to worry about invalid values. In systems with more complex config, doing all the validation at these API points is the lean and clean path.
I appreciate and support your suggestions for enhancing how to manage configurations in our instrumentations, and think this can be awesome to have. Would love to contribute to this initiative, but my current goal with this PR is to eliminate redundant config values, aligning it with the practices of most other instrumentations.
In the future, we could certainly explore a better approach, such as differentiating between user-supplied and "resolved" default configurations, having 2 types, or reducing redundancy by resolving configurations in the base class. This can be added regardless of this change at anytime.
Here
invalid
could mean more than an undefined or empty value. E.g. a JavaScript user of instrumentation-bunyan could pass innew BunyanInstrumentation({disableLogSending: "yes"})
.
This can spawn a whole different discussion, on what values do we treat as turthy
and then make sure we use this pattern everywhere. We can address such cases potentially in a different PR that target these concerns. I personally think that we should stick with the boolean type, until the time we encounter a practical need. at least for booleans (as you can see I left controversial cases out of this PR and only addressed trivial cases.
However, I'm not advocating doing all that now. I expect instrumentation config code to have to adapt a bit for coming file-config work.
If it's ok with you, I propose we continue with this PR as it stands, since it already enhances the consistency of our instrumentation styles. If you have the time and motivation, I encourage you to develop a more comprehensive solution.
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.
This can spawn a whole different discussion, on what values do we treat as
turthy
My using "yes"
was a bad example. I did not mean to suggest it as a possible acceptable value for a boolean config var. Rather I was trying to show an example of a bogus invalid argument value given by the user.
I propose we continue with this PR as it stands
Okay. I disagree, but I don't object strongly.
This PR applies some cleanups regarding the use of DEFAULT_CONFIG in 5 instrumentations.
It only targets cases where the unset (
undefined
) values are already the "safe" default values, and adding aDEFAULT_CONFIG
adds no real value.There are other places where
DEFAULT_CONFIG
is used such that the default values are numbers, ortrue
, thus they are not trivial and need more considerations.These are:
amqplib:
runtime-node:
ioredis:
knex:
This PR is not breaking any public API or behavior and is internal refactor only.