Skip to content
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

auto convert :auto to :prepend/:chain in config #1930

Merged
merged 7 commits into from
Apr 21, 2023
Merged

auto convert :auto to :prepend/:chain in config #1930

merged 7 commits into from
Apr 21, 2023

Conversation

fallwith
Copy link
Contributor

@fallwith fallwith commented Apr 7, 2023

For :'instrumentation.*' configuration parameters that are set to :auto (the default), the agent will automatically determine whether to use method prepending or chaining. The agent will now update its in-memory configuration to give each relevant parameter a value of either :prepend or :chain so that the result of the determination can be introspected. This is intended to help 3rd party libraries that wish to further enhance the agent's instrumentation capabilities by prepending or chaining additional logic. Environment variable, YAML file, and server-side configuration based values are not impacted.

resolves #1924

For `:'instrumentation.*'` configuration parameters that are set to
:auto (the default), the agent will automatically determine whether to
use method prepending or chaining. The agent will now update its
in-memory configuration to give each relevant parameter a value of
either :prepend or :chain so that the result of the determination can be
introspected. This is intended to help 3rd party libraries that wish to
further enhance the agent's instrumentation capabilities by prepending
or chaining additional logic. Environment variable, YAML file, and
server-side configuration based values are not impacted.
@prateeksen
Copy link
Contributor

@fallwith There is a bug in the replace_or_add_config method which updates the config when there is any new config is received from server source or any other source.
evaluate_and_apply_transformations method always updates from Default source and hence the changes made in between(in this case the instrumentation config) are lost once the server source is applied.
For the instrumentation config either we will need to create a new Map or need to fix this issue.
Probable fix can be, update only those parameters in config which are supposed to be updated by server source configuration.

CHANGELOG.md Outdated Show resolved Hide resolved
add missing ** closing style

Co-authored-by: Kayla Reopelle (she/her) <87386821+kaylareopelle@users.noreply.github.com>
when resetting the configuration manager's cache, do not allow
already determined dependency detection params to be reverted back to
either `nil` or `'auto'`.
@fallwith
Copy link
Contributor Author

@fallwith There is a bug in the replace_or_add_config method which updates the config when there is any new config is received from server source or any other source. evaluate_and_apply_transformations method always updates from Default source and hence the changes made in between(in this case the instrumentation config) are lost once the server source is applied. For the instrumentation config either we will need to create a new Map or need to fix this issue. Probable fix can be, update only those parameters in config which are supposed to be updated by server source configuration.

Hi @prateek-ap. The dependency detection based parameters can't be configured server-side so we should be okay to simply preserve them after auto-detection. I have updated the cache resetting logic with 7735f92.

for each default source test, make sure the config cache is reset
@prateeksen
Copy link
Contributor

Hi @fallwith The cache data is now preserving, Thanks.
But, I have observation that few instrumentation.<module> parameter values are enabled, while the VALID_CONFIG_VALUES are only [:auto, :disabled, :prepend, :chain].
This makes discrepancies for few module instrumentation, example:
:"instrumentation.mongo"=>"enabled"
:"instrumentation.excon"=>"enabled"
How to resolve instrumentation mechanism used(alias or prepend) by Dependency detection for these cases?

(for the sake of older Rubies) don't attempt to reference `@cache`, even
for an evaluation of truthiness, without making sure it is defined first
@fallwith
Copy link
Contributor Author

fallwith commented Apr 21, 2023

Hi @fallwith The cache data is now preserving, Thanks. But, I have observation that few instrumentation.<module> parameter values are enabled, while the VALID_CONFIG_VALUES are only [:auto, :disabled, :prepend, :chain]. This makes discrepancies for few module instrumentation, example: :"instrumentation.mongo"=>"enabled" :"instrumentation.excon"=>"enabled" How to resolve instrumentation mechanism used(alias or prepend) by Dependency detection for these cases?

@prateek-ap this is a great point! The Mongo and Excon instrumentation config parameters are definitely odd. As you point out, they are not set to auto|disabled|prepend|chain like the others, but enabled|disabled instead. And I think there might also be a bug preventing them from respecting disabled. I will use a separate PR to address that issue. [UPDATE: nope, not an issue]

The good news is that you don't not have to worry about the newrelic_rpm Mongo and Excon instrumentations because they do not touch any module code. The Mongo instrumentation calls Mongo::Monitoring::Global.subscribe and the Excon instrumentation calls << on Excon.defaults[:middlewares]. Because the newrelic_rpm agent is not performing any module prepending or chaining for the Mongo and Excon libraries, you won't have to worry about matching the same approach. You can either follow the same patterns used with subscribe and << or perform module prepending/chaining if you prefer. And optionally you can skip the instrumentation entirely if you find the agent's config value is set to 'disabled'.

@prateeksen
Copy link
Contributor

Hi @fallwith I understand that APM doesn't doing alias or prepend on mongo and excon library and that's why, by default have enabled, but In case of Security agent I will need a deterministic decision, otherwise, I will instrument using default approach (i.e. prepend) and that can conflict with other library instrumenting mongo or excon may be using chaining.

if config_key && auto_configured?
NewRelic::Agent.config.instance_variable_get(:@cache)[config_key] = use_prepend ? :prepend : :chain
end
use_prepend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this saying we are always returning true or false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Precisely. We hook into this existing method that returns a boolean, so here we make sure we still always return a boolean.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it I see what is happening now. Thank you :)

'becames' -> 'becomes' comment spelling fix
@github-actions
Copy link

SimpleCov Report

Coverage Threshold
Line 93.97% 93%
Branch 85.47% 85%

kaylareopelle
kaylareopelle previously approved these changes Apr 21, 2023
Copy link
Contributor

@kaylareopelle kaylareopelle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great as-is, take or leave the CHANGELOG rec.

CHANGELOG.md Outdated
@@ -2,6 +2,10 @@

## dev

- **Feature: The agent configuration will now reflect whether method prepending or chaining was used per instrumentation**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be up for changing "method prepending or chaining" to "module prepending or method chaining" in the title and the body copy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly! Addressed with bf3b5ee

hannahramadan
hannahramadan previously approved these changes Apr 21, 2023
@fallwith
Copy link
Contributor Author

Hi @fallwith I understand that APM doesn't doing alias or prepend on mongo and excon library and that's why, by default have enabled, but In case of Security agent I will need a deterministic decision, otherwise, I will instrument using default approach (i.e. prepend) and that can conflict with other library instrumenting mongo or excon may be using chaining.

Hi @prateek-ap. With this PR/branch, for all config parameters that start with instrumentation., you can rely on the following for their values:

  • prepend: Agent used the prepend approach to provide instrumentation
  • chain: Agent used the chain approach to provide instrumentation
  • disabled: Agent did not provide instrumentation
  • enabled: Agent provided instrumentation, but did not perform monkeypatching (no chain, no prepend)

So if you see 'enabled', feel free to use a default desired approach (prepend) without any worry of conflicting. For all instrumentation. parameters that have a value of 'enabled', the agent used neither prepend nor chain, so there won't be a conflict.

For Mongo and Excon in particular, you are welcome to follow the same pattern that we use for working with those libraries (for Mongo we subscribe, and for Excon we add to the middleware array) or if you prefer you can use prepend. Either way, you should not conflict with the agent for those two.

Update PR 1930's CHANGELOG entry to use the correct "module prepending"
and "method chaining" verbiage. Also replace the potentially confusing
"per" with "for".
@fallwith fallwith merged commit 4bec6de into dev Apr 21, 2023
@fallwith fallwith deleted the eritrea_okra branch April 21, 2023 20:02
@fallwith
Copy link
Contributor Author

@prateek-ap these changes are in the dev branch now.

fallwith added a commit that referenced this pull request May 13, 2023
With [1930](#1930)
the agent will now automatically convert any configured instrumentation
value of `:auto` into either `:prepend` or `:chain` once the
determination of which approach to take has been dynamically determined.

This will allow the agent's config to be inspected after the
`:prepend` / `:chain` determination is made to see what `:auto` actually
becomes under the hood.

But 1930 left an edge case gap open in the form of not allowing the
configuration to convey instrumentation with unsatisfied dependencies.
If a config value is set to `:prepend` or `:chain` in the configuration
(overriding the default `:auto` value) and a dependency is unsatisfied
(the library to instrument is not found on the system, it is of an
unsupported version, etc.) then the value would end up staying as
`:prepend` or `:chain` and incorrectly convey to anyone inspecting the
config that a certain method of instrumentation was used when in
actuality no instrumentation was performed at all.

Now, if an instrumentation's dependencies are unsatisfied, the
corresponding configuration value will be updated with a value of
`:unsatisfied`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants