Skip to content

Added support for setting service name and version for a transaction via the public api #2451

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

Merged
merged 10 commits into from
Feb 16, 2022

Conversation

tobiasstadler
Copy link
Contributor

@tobiasstadler tobiasstadler commented Feb 7, 2022

What does this PR do?

Adds support for setting service name and version for a transaction via the public api

Checklist

  • This is an enhancement of existing features, or a new feature in existing plugins
    • I have updated CHANGELOG.asciidoc
    • I have added tests that prove my fix is effective or that my feature works
    • Added an API method or config option? Document in which version this will be introduced
    • I have made corresponding changes to the documentation

@github-actions github-actions bot added agent-java community Issues and PRs created by the community triage labels Feb 7, 2022
@github-actions
Copy link

github-actions bot commented Feb 7, 2022

👋 @tobiasstadler 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.

@tobiasstadler
Copy link
Contributor Author

I will add unit tests once you decide this is the way to go (Manuel testing looks good).

@ghost
Copy link

ghost commented Feb 7, 2022

💚 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 preview

Expand to view the summary

Build stats

  • Start Time: 2022-02-15T09:39:21.228+0000

  • Duration: 55 min 22 sec

Test stats 🧪

Test Results
Failed 0
Passed 2499
Skipped 16
Total 2515

💚 Flaky test report

Tests succeeded.

🤖 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!)

@tobiasstadler
Copy link
Contributor Author

@felixbarny @eyalkoren Are you both comfortable with this approach?

@tobiasstadler
Copy link
Contributor Author

I added tests in 9be1a8a

@tobiasstadler
Copy link
Contributor Author

I just saw you are already prepared the changeling for 1.29.0. So I guess this wont't make it into the release?

@tobiasstadler
Copy link
Contributor Author

tobiasstadler commented Feb 9, 2022

Ok, hopefully 1.29.1 or 1.30.0 then

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @tobiasstadler !

The API types are only known within the API itself and not elsewhere within the agent, including the API plugin. Let's keep it this way. We don't want version assumptions that may make the agent backwards incompatible. Even though it is protected within your implementation by the fact that the getServiceInfoForClassLoader and setServiceInfoForClassLoader methods won't be matched, allowing this dependency may bite us in the future.

There are ways to do that within the API (like we do with multiple APIs through usage of internal methods that use Object in their signature), but I think the simplest would be to lose the ServiceInfo type.

One option is to get the service name and version through two APIs. It is not as neat, but it avoids the object allocation and it would be required within the internal API anyway if we want to keep the complete separation between API types and agent types.
Another option is to get rid of getServiceInfoForClassLoader altogether.
The fact that you added setServiceInfoForClassLoader is enough if the co.elastic.apm.api.Transaction interface has a useServiceInfoOf(ClassLoader) (instead of what you did in #2444) . You can reference from the javadoc of each method
to the other to give users hints how they can be used. A co.elastic.apm.api.Transaction#setServiceInfo(String serviceName, String serviceVersion) is still useful as well.

public static class AdviceClass {
@Advice.OnMethodExit(suppress = Throwable.class, inline = false)
public static void setServiceInfoForClassLoader(@Advice.Argument(0) @Nullable ClassLoader classLoader, @Advice.Argument(1) String serviceName, @Advice.Argument(2) @Nullable String serviceVersion) {
tracer.setServiceInfoForClassLoader(classLoader, ServiceInfo.of(serviceName, serviceVersion));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if we should check for serviceName being null

Copy link
Contributor

Choose a reason for hiding this comment

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

A null service name will have no effect here - it won't be mapped and not even cause allocation of a ServiceInfo object.
However, I wonder if we should allow null service version going forward, now that #1726 is merged.
I think providing a service name without a version should be considered a bug, because it means we will use the global service version for a manually set service name, and there's no real reason why those would be related.
@felixbarny WDYT? Should we only allow overriding these two values together?

Copy link
Contributor Author

@tobiasstadler tobiasstadler Feb 14, 2022

Choose a reason for hiding this comment

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

I think its is fine to set a service name without a version. The global service version won't be used in such a case. But there service version won't be serialized and the apm-server also won't use the global service version.

Copy link
Contributor

Choose a reason for hiding this comment

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

You mean - currently APM Server ignores the global version when we use a service name in transaction/metric context?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, my bad. This logic is only implemented for metrics. I created elastic/apm-server#7281 to fix this for transactions also.

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Looks good, thanks!
Once we set our minds about how we handle null values, please update the tests accordingly to verify that.

public static class AdviceClass {
@Advice.OnMethodExit(suppress = Throwable.class, inline = false)
public static void setServiceInfoForClassLoader(@Advice.Argument(0) @Nullable ClassLoader classLoader, @Advice.Argument(1) String serviceName, @Advice.Argument(2) @Nullable String serviceVersion) {
tracer.setServiceInfoForClassLoader(classLoader, ServiceInfo.of(serviceName, serviceVersion));
Copy link
Contributor

Choose a reason for hiding this comment

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

A null service name will have no effect here - it won't be mapped and not even cause allocation of a ServiceInfo object.
However, I wonder if we should allow null service version going forward, now that #1726 is merged.
I think providing a service name without a version should be considered a bug, because it means we will use the global service version for a manually set service name, and there's no real reason why those would be related.
@felixbarny WDYT? Should we only allow overriding these two values together?

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Thanks for following up @tobiasstadler !
Please just add tests that reflect our decision on using null values (I am approving anyway).

@eyalkoren eyalkoren requested a review from felixbarny February 14, 2022 14:08
@eyalkoren
Copy link
Contributor

/test

Copy link
Member

@felixbarny felixbarny left a comment

Choose a reason for hiding this comment

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

One optional suggestion to bring in some of the improvements from #2444. Otherwise, LGTM.

@felixbarny
Copy link
Member

/run elasticsearch-ci/docs

@eyalkoren eyalkoren merged commit d48e1d6 into elastic:main Feb 16, 2022
@tobiasstadler
Copy link
Contributor Author

Thank You!

@tobiasstadler tobiasstadler deleted the public-api-setserviceinfo branch February 16, 2022 07:19
@eyalkoren
Copy link
Contributor

Thank you for your great collaboration ❤️

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 triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants