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

Add zipkin compatibility mode to open-tracing #18313

Merged
merged 1 commit into from
Jul 16, 2021

Conversation

raulvaldoleiros
Copy link

Issue: #18278

@quarkus-bot
Copy link

quarkus-bot bot commented Jul 1, 2021

Thanks for your pull request!

The title of your pull request does not follow our editorial rules. Could you have a look?

This message is automatically generated by a bot.

@quarkus-bot quarkus-bot bot added area/dependencies Pull requests that update a dependency file area/jaeger labels Jul 1, 2021
@raulvaldoleiros raulvaldoleiros changed the title Add zipkin compatibility mode #18278 Add zipkin compatibility mode to open-tracing Jul 1, 2021
Copy link
Member

@kenfinnigan kenfinnigan left a comment

Choose a reason for hiding this comment

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

Have you verified this extension works with native image build?

One concern I have is adding this into the Jaeger extension makes it difficult for dead code elimination to remove the Zipkin classes when Zipkin isn't used. If there was a way to have the Zipkin piece separate to QuarkusJaegerTracer it would be preferable, otherwise, it might need to be a whole separate extension.

What do you think @pavolloffay?

@raulvaldoleiros
Copy link
Author

Have you verified this extension works with native image build?

One concern I have is adding this into the Jaeger extension makes it difficult for dead code elimination to remove the Zipkin classes when Zipkin isn't used. If there was a way to have the Zipkin piece separate to QuarkusJaegerTracer it would be preferable, otherwise, it might need to be a whole separate extension.

What do you think @pavolloffay?

I added an integration test, it's just a simples rest with the opentracing and I executed this in native and it worked. The integration test combined with the unit test proves it works, from my analysis.

About the zipkin classes, if you want I can create a class ZipkinReporterFactory in a specific package and delegate the Report creation in that object. What do you think?

integration-tests/pom.xml Show resolved Hide resolved
@@ -32,6 +32,20 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
Copy link
Member

Choose a reason for hiding this comment

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

Can you measure the amount of additional RSS is present by introducing this dependency when running a native executable?

I'm concerned this approach to supporting Zipkin will add reasonable RSS weight to an application even when they're not using Zipkin compatibility

Copy link
Author

Choose a reason for hiding this comment

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

I made what you requested and the results are:
without my changes:

  • executable size: 43M
  • RSS on startup: 18908
  • RSS after first request: 22144

With my changes:

  • executable size: 44M
  • RSS on startup: 18960
  • RSS after first request: 24796

Copy link
Member

Choose a reason for hiding this comment

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

Thanks @raulvaldoleiros!

@n1hility, @ebullient what do you think of these numbers? Sufficiently small? I'm inclined to say yes, as adding tracing adds weight anyway, but would appreciate your thoughts

Copy link
Contributor

Choose a reason for hiding this comment

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

I would have add the dependency as optional, explain in the guide that to have zipkin capability you need to add the dependency to your pom.xml, and make a check at runtime that the class is present before enabling Zipkin.

OK, it's a small RSS increase, but still, if we have more and more of those addition we will ends up with a much bigger RSS.

Copy link
Member

Choose a reason for hiding this comment

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

I had thought about suggesting that, but wasn't sure if it could be done without causing an issue when it wasn't there.

If it can be done, that would be better.

@raulvaldoleiros can you try?

Copy link
Author

Choose a reason for hiding this comment

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

I tried to change the dependency scope to test or provided and it works fine in the quarkus build, but when I'm compiling an application it breaks without the dependency.

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.495 s
[INFO] Finished at: 2021-07-09T18:24:08+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project opentracing-quickstart: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.jaeger.deployment.JaegerProcessor#setupTracer threw an exception: java.lang.NoClassDefFoundError: zipkin2/reporter/Sender

To make the dependency optional the only way is to use java reflection or do you have an example that I can follow?

Copy link
Contributor

Choose a reason for hiding this comment

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

To make the dependency optional the only way is to use java reflection or do you have an example that I can follow?

Yes, you need to guard the usage of the Zipkin classes by a check that the class exist (Class.forName("") and if an exception occurs, do nothing).

The only other solution is to create a separate extension but it can be a lot of work so maybe it's not worth it.

Copy link
Author

Choose a reason for hiding this comment

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

I changed the code for zipkin be optional, and also I have updated the documentation. Native mode needs extra configuration but it works, I tried to put that configuration in the jaeger extension but I wasn't successful.

Copy link
Member

Choose a reason for hiding this comment

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

Is extra configuration for native mode still necessary? If so, what configuration?

@quarkus-bot quarkus-bot bot added the area/infra-automation anything related to CI, bots, etc. that are used to automated our infrastructure label Jul 7, 2021
@pavolloffay
Copy link
Contributor

@raulvaldoleiros why do you need this feature? To send data directly to Zipkin?

I am not maintaining Quarkus so it's hard to justify whether it is really needed. A workaround is to report data to OpenTelemetry collector with configured Jaeger receiver and Zipkin exporter.

@raulvaldoleiros
Copy link
Author

@raulvaldoleiros why do you need this feature? To send data directly to Zipkin?

I am not maintaining Quarkus so it's hard to justify whether it is really needed. A workaround is to report data to OpenTelemetry collector with configured Jaeger receiver and Zipkin exporter.

I need this feature because the solution we use is only zipkin compatible and not jaeger compatible.

@raulvaldoleiros
Copy link
Author

I didn't understand why the integration test failed. What makes sense to me is because I am validating some local endpoint data in the span, I removed it hopping that is the solution.
@kenfinnigan can you, please, approve the workflow again? Sorry to be this way :(

@quarkus-bot
Copy link

quarkus-bot bot commented Jul 7, 2021

This workflow status is outdated as a new workflow run has been triggered.

🚫 This workflow run has been cancelled.

Failing Jobs - Building 17d9873

⚠️ Artifacts of the workflow run were not available thus the report misses some details.

Status Name Step Test failures Logs Raw logs
JVM Tests - JDK 11 Build Test failures Logs Raw logs
JVM Tests - JDK 11 Windows Build ⚠️ Check → Logs Raw logs
JVM Tests - JDK 16 Build Test failures Logs Raw logs
Native Tests - Misc3 Build Test failures Logs Raw logs

Full information is available in the Build summary check run.

Test Failures

⚙️ JVM Tests - JDK 11 #

📦 integration-tests/smallrye-opentracing

io.quarkus.it.rest.client.ZipkinIntegrationTest.testZipkinIntegration line 43 - More details - Source on GitHub


⚙️ JVM Tests - JDK 16 #

📦 integration-tests/smallrye-opentracing

io.quarkus.it.rest.client.ZipkinIntegrationTest.testZipkinIntegration line 43 - More details - Source on GitHub


⚙️ Native Tests - Misc3 #

📦 integration-tests/smallrye-opentracing

io.quarkus.it.rest.client.ZipkinIntegrationTestIT.testZipkinIntegration - More details - Source on GitHub

@ebullient
Copy link
Member

ebullient commented Jul 12, 2021

Sorry for the back and forth in this PR. Regarding handling optionally/maybe present dependencies, you should be able to tuck all/most of this in a processor, which itself is guarded by zipkin compatibility classes. An example is here:
https://github.com/quarkusio/quarkus/blob/main/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/export/PrometheusRegistryProcessor.java

The PrometheusRegistryProcessor is packaged with the core micrometer extension (for a lot of reasons), but you'll notice that the BuildStep methods are guarded... they are only invoked if the required prometheus MeterRegistry class is present (which prevents construction of parameters, etc.) .. which means recorder methods that would reference that class are also only called if the required MeterRegistry class is present (they are further tucked away in a separate recorder that isn't touched if the Prometheus MeterRegistry isn't found.. )

@raulvaldoleiros
Copy link
Author

Sorry for the back and forth in this PR. Regarding handling optionally/maybe present dependencies, you should be able to tuck all/most of this in a processor, which itself is guarded by zipkin compatibility classes. An example is here:
https://github.com/quarkusio/quarkus/blob/main/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/export/PrometheusRegistryProcessor.java

The PrometheusRegistryProcessor is packaged with the core micrometer extension (for a lot of reasons), but you'll notice that the BuildStep methods are guarded... they are only invoked if the required prometheus MeterRegistry class is present (which prevents construction of parameters, etc.) .. which means recorder methods that would reference that class are also only called if the required MeterRegistry class is present (they are further tucked away in a separate recorder that isn't touched if the Prometheus MeterRegistry isn't found.. )

Hi @ebullient, thanks for pointing me in the right direction. I made the changes as you requested, I hope it's in the right way.

@quarkus-bot
Copy link

quarkus-bot bot commented Jul 13, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building 0a570b2

Status Name Step Test failures Logs Raw logs
Initial JDK 11 Build Build ⚠️ Check → Logs Raw logs

@raulvaldoleiros
Copy link
Author

raulvaldoleiros commented Jul 13, 2021

@ebullient can you approve the workflow again please? I don't know why but I don't get the same error on my machine when I execute "./mvnw install -f extensions/jaeger/", it seems I only need to add the arc dependency to the runtime project (micrometer has it :p )

@quarkus-bot
Copy link

quarkus-bot bot commented Jul 13, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building 16a28d2

Status Name Step Test failures Logs Raw logs
Native Tests - Misc3 Build Test failures Logs Raw logs

Full information is available in the Build summary check run.

Test Failures

⚙️ Native Tests - Misc3 #

📦 integration-tests/smallrye-opentracing

io.quarkus.it.rest.client.ZipkinIntegrationTestIT.testZipkinIntegration - More details - Source on GitHub

@raulvaldoleiros
Copy link
Author

@ebullient I forgot to run the integration tests in native mode, my bad. I did it now.

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.869 s - in io.quarkus.it.rest.client.ZipkinIntegrationTestIT
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default) @ quarkus-integration-test-smallrye-opentracing ---
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ quarkus-integration-test-smallrye-opentracing ---
[INFO] Installing /Users/raulvaldoleiros/git/quarkus/integration-tests/smallrye-opentracing/target/quarkus-integration-test-smallrye-opentracing-999-SNAPSHOT.jar to /Users/raulvaldoleiros/.m2/repository/io/quarkus/quarkus-integration-test-smallrye-opentracing/999-SNAPSHOT/quarkus-integration-test-smallrye-opentracing-999-SNAPSHOT.jar
[INFO] Installing /Users/raulvaldoleiros/git/quarkus/integration-tests/smallrye-opentracing/pom.xml to /Users/raulvaldoleiros/.m2/repository/io/quarkus/quarkus-integration-test-smallrye-opentracing/999-SNAPSHOT/quarkus-integration-test-smallrye-opentracing-999-SNAPSHOT.pom
[INFO] Installing /Users/raulvaldoleiros/git/quarkus/integration-tests/smallrye-opentracing/target/quarkus-integration-test-smallrye-opentracing-999-SNAPSHOT-sources.jar to /Users/raulvaldoleiros/.m2/repository/io/quarkus/quarkus-integration-test-smallrye-opentracing/999-SNAPSHOT/quarkus-integration-test-smallrye-opentracing-999-SNAPSHOT-sources.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:54 min
[INFO] Finished at: 2021-07-14T10:55:08+01:00
[INFO] ------------------------------------------------------------------------

Also I had to create a zipkinconfig to analyse only the compatibility mode property in build time and the remaining ones in runtime.

Can you approve the workflow again please?

@kenfinnigan
Copy link
Member

@raulvaldoleiros when the current CI finishes, if all is well does that mean everything works? JVM and Native work as expected with and without the jaeger-zipkin dependency?

@raulvaldoleiros
Copy link
Author

@raulvaldoleiros when the current CI finishes, if all is well does that mean everything works? JVM and Native work as expected with and without the jaeger-zipkin dependency?

@kenfinnigan yes, I tested in jvm and native the following scenarios:

  • no dependency and zipkin mode disabled -> the span was delivered in jaeger
  • no dependency and zipkin mode enabled -> the span was delivered in jaeger ( i didn't changed the endpoint)
  • with dependency and zipkin mode enabled -> the span was delivered in zipkin
  • with dependency and zipkin mode disabled -> the span was delivered in jaeger

@quarkus-bot
Copy link

quarkus-bot bot commented Jul 14, 2021

This workflow status is outdated as a new workflow run has been triggered.

Failing Jobs - Building 3d409ce

Status Name Step Test failures Logs Raw logs
✔️ JVM Tests - JDK 11
JVM Tests - JDK 16 Build Test failures Logs Raw logs

Full information is available in the Build summary check run.

Test Failures

⚙️ JVM Tests - JDK 16 #

📦 integration-tests/mailer

io.quarkus.it.mailer.MailerTest. - More details - Source on GitHub

@raulvaldoleiros
Copy link
Author

@kenfinnigan I don't think, this time, the error is related with my changes. In the log i found this ": org.testcontainers.containers.ContainerFetchException: Failed to pull image: reachfive/fake-smtp-server:latest" and I didn't change the project with the error and it doesn't have relation with jaeger extension. What should be done in this scenario?

@kenfinnigan
Copy link
Member

@raulvaldoleiros confirmed it was just the mailer integration test that failed because it couldn't pull an image, nothing to do with this change.

----

It contains the dependencies to convert the request to zipkin format.
The zipkin compatibility mode will be activate defining the config property as follows:
Copy link
Member

Choose a reason for hiding this comment

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

Minor comment on the wording, is it clearer if its "compatibility mode will be activated after defining the config property as follows"?

Copy link
Author

Choose a reason for hiding this comment

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

yes, i changed to that

@Produces
@Singleton
@UnlessBuildProperty(name = "quarkus.jaeger.zipkin.compatibility-mode", stringValue = "false", enableIfMissing = false)
@AlternativePriority(Interceptor.Priority.APPLICATION + 100)
Copy link
Member

Choose a reason for hiding this comment

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

Is the @AlternativePriority needed? Are we expecting users to overload this with their own version?

Copy link
Author

Choose a reason for hiding this comment

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

We don't need it, i removed.

public class ZipkinReporterProvider {
@Produces
@Singleton
@UnlessBuildProperty(name = "quarkus.jaeger.zipkin.compatibility-mode", stringValue = "false", enableIfMissing = false)
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed, or is the processor guard to make it unremovable enough?

Copy link
Author

Choose a reason for hiding this comment

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

its enough the processor guard, I removed it.
After all the changes I tested in a new application (jvm and native mode) the following scenarios:

  • no dependency and zipkin mode disabled -> the span was delivered in jaeger
  • no dependency and zipkin mode enabled -> the span was delivered in jaeger
  • with dependency and zipkin mode enabled -> the span was delivered in zipkin
  • with dependency and zipkin mode disabled -> the span was delivered in jaeger

@kenfinnigan
Copy link
Member

Ah, one thing @raulvaldoleiros. Could you squash the commits into one commit?

@raulvaldoleiros
Copy link
Author

raulvaldoleiros commented Jul 16, 2021

Ah, one thing @raulvaldoleiros. Could you squash the commits into one commit?

yes @kenfinnigan , it's done :)

@kenfinnigan kenfinnigan added this to the 2.2 - main milestone Jul 16, 2021
@kenfinnigan kenfinnigan added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Jul 16, 2021
@kenfinnigan kenfinnigan merged commit 9ef5c49 into quarkusio:main Jul 16, 2021
@quarkus-bot quarkus-bot bot removed the triage/waiting-for-ci Ready to merge when CI successfully finishes label Jul 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dependencies Pull requests that update a dependency file area/documentation area/infra-automation anything related to CI, bots, etc. that are used to automated our infrastructure area/jaeger
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants