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

Introduce tracer API within isolated module. #3043

Merged
merged 6 commits into from
Mar 10, 2023

Conversation

raphw
Copy link
Contributor

@raphw raphw commented Mar 1, 2023

What does this PR do?

This PR introduces a minimal, zero-dependency Tracer API. This API is a superset of the current Tracer API which is part of the core module. The API was identified to be the minimal subset of API that is required by the majority of plugins. As a result, plugins can be moved away from depending upon the apm-agent-core module but only rely on this API module. This decouples the plugins from the agents implementation what allows for a cleaner modularization, and it opens for the reuse of the Elastic agent plugins outside of the current implementation of the agent.

A large fraction of the changes of this PR are IDE generated. The changes were generated by creating necessary interfaces, and by later pulling members upwards. At the same time, javadoc was moved upwards the interface hierarchy.

Checklist

@github-actions github-actions bot added agent-java community Issues and PRs created by the community triage labels Mar 1, 2023
@github-actions
Copy link

github-actions bot commented Mar 1, 2023

👋 @raphw Thanks a lot for your contribution!

It may take some time before we review a PR, so even if you don’t see activity for some time, it does not mean that we have forgotten about it.

Every once in a while we go through a process of prioritization, after which we are focussing on the tasks that were planned for the upcoming milestone. The prioritization status is typically reflected through the PR labels. It could be pending triage, a candidate for a future milestone, or have a target milestone set to it.

@apmmachine
Copy link
Contributor

apmmachine commented Mar 1, 2023

💚 Build Succeeded

the below badges are clickable and redirect to their specific view in the CI or DOCS
Pipeline View Test View Changes Artifacts preview previewSnapshots

Expand to view the summary

Build stats

  • Start Time: 2023-03-09T14:39:14.640+0000

  • Duration: 54 min 11 sec

Test stats 🧪

Test Results
Failed 0
Passed 3559
Skipped 121
Total 3680

💚 Flaky test report

Tests succeeded.

🤖 GitHub comments

Expand to view the GitHub comments

To re-run your PR in the CI, just comment with:

  • /test : Re-trigger the build.

  • run benchmark tests : Run the benchmark tests.

  • run jdk compatibility tests : Run the JDK Compatibility tests.

  • run integration tests : Run the Agent Integration tests.

  • run end-to-end tests : Run the APM-ITs.

  • run windows tests : Build & tests on windows.

  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

@raphw raphw force-pushed the tracer-api branch 2 times, most recently from 3314cbc to 652b540 Compare March 1, 2023 21:10
@SylvainJuge SylvainJuge removed the triage label Mar 7, 2023
Copy link
Member

@SylvainJuge SylvainJuge left a comment

Choose a reason for hiding this comment

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

This looks great, I only have a few comments/questions.

I think the biggest question here is "do we want to use this API+Impl naming style", because this is not something that we have done so far, so it's a bit new and might need a bit of thought before committing to it.

I think the name duplication is fine as this is an "internal API", there is little ambiguity between the interfaces and their implementations and there is always a 1:1 relationship between them. For very simple types like Scope or Outcome we can even avoid creating types outside of the tracer-api.

CHANGELOG.asciidoc Outdated Show resolved Hide resolved
Comment on lines +32 to +35
@Nullable
<T extends Tracer> T probe(Class<T> type);

<T extends Tracer> T require(Class<T> type);
Copy link
Member

Choose a reason for hiding this comment

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

[question] I'm guessing the use-case for those methods might come from next steps in this refactoring, but do we need to have this kind of cast directly available in the Tracer API ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could be added in a next step, but I wanted to add it as part of the minimal API. The idea is to allow for casting the internal tracer of a global tracer to a specific implementation without the global tracer needing to know about a specific implementation.

This way it will still be possible to receive the ElasticApmTracer, or any other specific tracer implementation from a global tracer.

@@ -148,13 +147,13 @@ void testAutomaticAndManualTransactions() {
void testGetId_distributedTracingEnabled() {

co.elastic.apm.agent.impl.transaction.Transaction transaction = tracer.startRootTransaction(null).withType(Transaction.TYPE_REQUEST);
try (Scope scope = transaction.activateInScope()) {
try (co.elastic.apm.agent.tracer.Scope scope = transaction.activateInScope()) {
Copy link
Member

Choose a reason for hiding this comment

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

[minor] If I understand this correctly, in this case we can just change the original import and not use the FQN, and we will do the same when modifying all the plugins to use the newly created tracer API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

apm-agent-api does not currently depend on the new tracer module, so I wanted to avoid the additional refactoring in the first round.

@raphw
Copy link
Contributor Author

raphw commented Mar 7, 2023

As for the naming convention: I think it is a good way to evolve the code base as it does not leave any doubt about what APIs are migrated. At some late point, I think it is fair to remove all current interfaces as they are made redundant by the API module. But I would leave this last refactoring to one of the last stages.

@SylvainJuge
Copy link
Member

You were faster to push than me, I only have a few tests to add here :-).
I will approve this PR so it can run on CI now, which is a requirement for external contributions.

Copy link
Member

@SylvainJuge SylvainJuge left a comment

Choose a reason for hiding this comment

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

Approve to allow running on CI.

@SylvainJuge
Copy link
Member

As for the naming convention: I think it is a good way to evolve the code base as it does not leave any doubt about what APIs are migrated. At some late point, I think it is fair to remove all current interfaces as they are made redundant by the API module. But I would leave this last refactoring to one of the last stages.

So, if I understand this correctly:

  • the usage of duplicating names by adding interfaces is just an intermediate step and not a desired final state.
  • the short-term benefit for now is that it helps to migrate in steps and mostly require changing imports for now (which is trivial to review and has no impact).
  • Later, implementation of those interfaces will be moved to the tracer-api, replacing the interfaces. As a result there won't be duplicated class names anymore.

@raphw
Copy link
Contributor Author

raphw commented Mar 8, 2023

Some of the current interfaces contain methods that are only required by internal components, but not by the plugins itself. It would make sense to make the distinction clear, for example by naming it ElasticTransaction vs Transaction, similar to the Tracer API compared to the already existing ElasticApmTracer. I would expect that use of the latter would only be required from within apm-agent-core itself in a final migration, when this dependency is removed from the internal plugins.

@raphw
Copy link
Contributor Author

raphw commented Mar 8, 2023

The failing unit test struggles with Caused by: java.lang.ClassNotFoundException: io.vertx.core.impl.logging.LoggerFactory. I do not see that this can be related to these changes. Is this a known issue?

@SylvainJuge
Copy link
Member

The failing unit test struggles with Caused by: java.lang.ClassNotFoundException: io.vertx.core.impl.logging.LoggerFactory. I do not see that this can be related to these changes. Is this a known issue?

Yes, this was fixed with #3044.
Updating this PR from main branch should make those errors go away.

@raphw
Copy link
Contributor Author

raphw commented Mar 8, 2023

Alright, I rebased upon main, let's give it another try. Should I squash the commits or are you happy to keep the change set the way it is?

@SylvainJuge
Copy link
Member

No need to squash the commits nor rewrite the history, we squash when merging, so it's easier to revert if needed and keeps the main history simple and clean. Personally, I usually just merge main to update dev branches without rebasing.

@SylvainJuge
Copy link
Member

@elasticmachine run elasticsearch-ci/docs

@jackshirazi jackshirazi merged commit 05efbe9 into elastic:main Mar 10, 2023
@SylvainJuge SylvainJuge mentioned this pull request Apr 12, 2023
19 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agent-java community Issues and PRs created by the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants