-
Notifications
You must be signed in to change notification settings - Fork 324
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
Add support for community supported plugins #937
Comments
Also, we currently have "incubating" features (currently JMS is one of them), those are disabled by default because There are two possible approaches:
Pros/cons
|
I would prefer the explicit opt-in via |
I've changed a bit my mind for the naming part, thus I feel now that
Also, we should probably start to have a distinction between +1 on using a single |
Let's discuss whether that would be a feasible option. It has the following advantages:
Downsides of the initial suggestion of creating a dedicated contrib folder within the main repo:
The challenges
What we currently recommend to users that want to add plugins for their custom frameworks, which should not be included in the main repo, is to fork the repo and add an additional plugin in the I think it makes sense to fold the two use cases of community plugins and custom plugins and improve the experience of developing them in the following ways:
The plugin development for Kibana and Elasticsearch is actually quite similar. Maybe the situation has changed since I had my last touchpoint with it but in Kibana, you had to explicitly declare for which version an external plugin works because the internal APIs can change without notice. |
I really like this proposal as it's definitely a "best of both worlds" option, without much extra complexity on agent architecture. We should probably add a way to check for agent/plugin compatibility, probably using jar manifest, that would allow us to still break things when needed, and then incompatible plugins would be disabled with a proper warning and an optional link to plugin github repository (if any). On a side note, that probably means publishing our internal APIs as regular jars, which might be a bit confusing when people are searching maven central (plugins outside of our codebase will depend on those). This is quite minor and if we make a good walkthrough/doc we can make this user-proof. |
I don’t think we’d be doing that. Users need to compile against the shaded version of Byte Buddy, for example. Do they’d just have a provided dependency on the |
I like this discussion and I agree that moving outside the repo is important in order to achieve what we want. I am not feeling comfortable doing that and relying on our internal APIs though. I just did two refactors lately that we wanted to do in our internal API. One would have practically break all community plugins and the other would have break those creating transactions (currently in progress are such for Ratpack, WebFlux, RocketMQ, Dubbo and probably Scala). We already know of a future refactor we have in mind that will practically break all in multiple places. I can easily see how having 30 plugins being affected by such changes affect our decisions, or the effort they take. Start breaking things for all the users of those plugins upon upgrade is unpleasant. What if we did what @felixbarny suggested but allow usage of the public API only?
True, but it is already reacher than the OpenTracing API that was proved useful for creation of custom plugins. Like we did so far, we can be attentive and adjust it to support future requirements.
I am pretty sure that wouldn't be the major performance concern for most community plugins that we are not involved in developing. The fact that these plugins are likely to be not-as-efficient is inherent and I believe acceptable. Going back to OpenTracing- it has the same (or worse) limitations and it got its adoption.
We can do the same as suggested above - loading plugins from the |
Definitely valid concerns.
Part of this would be educating users that things break at any time. It should not influence our decisions about refactoring the internal API, however. Also, note that we're already in this situation for users that are adding plugins for their internal frameworks. But I acknowledge that promoting public API-based community plugins would expose many more users to this problem.
Why not both 🙂 However, there are some technical complications with allowing the public API in auto-instrumentation plugins.
In the meantime, I'd suggest starting with internal API plugins and consider public API plugins after we have refactored the agent to allow for that. |
Right, although this is not agent code. They can rely on ByteBuddy and the build will shade those. Or other solution.
They don't need to ship with it, the API can be |
Update on the spec after today's discussion. Summary
Custom instrumentation ladder1st level
2cnd level
3rd level
4th level
Given there is a strong technical dependency on solving classloading/isolation, we will need to solve this first as it's a pre-requisite. |
@roncohen @alvarolobato As you raised some concerns with the previous plan to have community plugins within the main repo, could we get your opinion on the new plan? See #937 (comment) and #937 (comment) |
Thanks team for looking into this, this is a key initiative I read through the proposal and it looks good to me with the exception of allowing plugins to rely on the internal API. My concern is getting into a situation where plugins are hard to maintain because we break the internal API, maintainers take a long time to update and our users start feeling the pain. This also can happen with public API's, but that's the objective of public API's and that's why we are so careful when breaking them. I've lived this situation and is very painful and in the end, it tends to hamper your progress because you are conditioned to not break your own internal API. Having the plugins in an external repo is something we need, but it will make all this worse by making it very hard to do a breaking change that also fixes the plugin (we also don't want to do for community plugins we don't maintain). I don't fully understand why we want to allow internal API, what are the advantages over just allowing public API? |
The truth is that to develop an auto-instrumentation plugin, you not only rely on the tracer API (to create transactions/spans). You also need to define the instrumentation. Byte Buddy helps in that regard as it lets you define matchers (which methods to instrument) and advices (the code to be injected into methods). We have developed lots of glue code that helps to navigate the issues around class visibility. This glue code is subject to change as well. In fact, we have plans for a major overhaul of this in order to properly support runtime attachment. If we'd only allow access to the public API for external plugins, developers would be left without support when it comes to the hardest part of agent development: classloading/visibility. If we give them access to those helpers, we're basically allowing them to access the internals of the agent: any changes we make would be breaking ones. Maybe we could extract some of these helpers to a separate module which is guaranteed to be stable. Or even try to work towards getting some of those changes into Byte Buddy. But developing plugins only with the public API will always be quite limiting. There are a number of things you wouldn't be able to do like
While not all plugins may need that, for some the need will eventually arise. In that case, there's no way around relying on internal APIs |
I just had a chat with @roncohen about this. He also shared concerns around the implications of more people relying on the internal API. We would either break lots of plugins by making changes in the internal API or be forced to maintain backwards compatibility for our own internal API. Both don't sound like good options. We have discussed what we could have a plugin SDK, possibly in a separate repo, that allows people to write bytecode instrumentation plugins without relying on the internal API. The SDK would contain the public API (which could be made a bit more powerful in future versions) and an opinionated Byte Buddy setup, including things similar to Over time, we can make the SDK more powerful. For example, we could allow adding additional configuration options. But to start with it can be lightweight, even if it means it's not as powerful as the internal API. This has a dependency on #1085, as we are revising the class loading and HelperClassManager mechanism in the core agent. |
SGTM, thanks |
I've created a doc with the proposed changes in the module structure of the agent https://docs.google.com/document/d/1LFTBDLM3-Sj7cU1pHFxfgI3donyTMp8tvjFpyJM7dF8/edit TL;DR:
|
first iteration on external plugins support is completed |
Issue description
Community contributions are split in two broad categories
Plugins (2) are the easiest way to add features to the agent and are also the most common contribution type.
We (Elastic Java Agent team) currently take ownership of all those added features and merge them to the plugins, which means asking for changes in pull-requests to meet quality/style standards.
While doing so seems fair, it means that merging contributions takes a considerable effort and time, and that our team is often the bottleneck here, often with back and forth with contributors.
Also, keeping pull-requests open for a while makes them harder to merge.
Proposed solution
https://docs.google.com/document/d/1LFTBDLM3-Sj7cU1pHFxfgI3donyTMp8tvjFpyJM7dF8/edit
apm-agent-plugin-sdk
: used both by internal and external/community plugins$AGENT_HOME/plugins
AbstractInstrumentationTest
andMockReporter
Tasks
The text was updated successfully, but these errors were encountered: