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

OTLP HTTP trace exporter #3418

Merged
merged 10 commits into from
Aug 4, 2021
Merged

Conversation

jack-berg
Copy link
Member

@jack-berg jack-berg commented Jul 21, 2021

OTLP HTTP trace exporter implementation.

@jack-berg
Copy link
Member Author

I added the OtlpHttpSpanExporter to the :exporters:otlp:trace to defer thinking about where to put it, but it will have to be addressed.

Keeping it in :exporter:otlp:trace avoids extra modules / artifacts. It also removes the need to rename or think about renaming existing modules / packages / artifacts to disambiguate between otlp/grpc and otlp/http. The current naming conventions imply that otlp = otlp/grpc. We can keep that, and have new modules / packages / artifacts use otlp-http to disambiguate, but this asymmetry isn't ideal. Keeping the exporter in :expoter:otlp:trace sidesteps this whole conversation. This doesn't feel wrong to me, since otlp/grpc and otlp/http with JSON format and Protobuf format are all different flavors of otlp.

Another thing to think is whether to shade the new dependencies on okhttp, and whether it matters based on where the exporter lives.

@jkwatson
Copy link
Contributor

I think it would be unfortunate if otlp grpc users suddenly got an okhttp dependency thrust upon them, forcing them to exclude it to keep their artifact smaller (and avoid version clashes). so, if we want to put them in the same module, we should definitely shade-in okhttp.

@anuraaga
Copy link
Contributor

Let's use a different module - I expect a very small minority of users to need this module so want to reduce it's discoveribility vs our "standard recommendation" grpc.

@@ -28,6 +28,10 @@ dependencies {
implementation("io.grpc:grpc-stub")
implementation("com.google.protobuf:protobuf-java")

implementation("com.squareup.okhttp3:okhttp:4.9.0")
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's target okhttp3 to not pull in kotlin stdlib. This will be especially important if we shade (let's not worry about it in the first PR)

Any thoughts on publishing both shaded and not shaded (the one use case made easy by Gradle shadow plugin : 😹)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok! I'm inclined to keep the surface area smaller and choosing to either shade or not shade. Can always publish additional artifacts later, but it's harder to stop publishing.

Copy link
Member Author

Choose a reason for hiding this comment

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

On second thought, maybe okhttp3 isn't such a great idea. Its only getting critical fixes through December 31st, 2021. And since we're going with the separate module route, it doesn't seem as critical that the kotlin stdlib is included.

Copy link
Contributor

Choose a reason for hiding this comment

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

3.12.x isn't getting updates, but the 4.x will be.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I didn't know about the EoL then seems ok (indeed especially with the separate module)

@Override
public RequestBody build(ExportTraceServiceRequest exportTraceServiceRequest) {
return RequestBody.create(
exportTraceServiceRequest.toByteArray(), MediaType.parse("application/x-protobuf"));
Copy link
Contributor

Choose a reason for hiding this comment

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

It can and probably should be a future PR but would definitely be good to use okio buffer and codedinputstream to skip the intermediate unpooled buffer

@jack-berg
Copy link
Member Author

Let's use a different module - I expect a very small minority of users to need this module so want to reduce it's discoveribility vs our "standard recommendation" grpc.

@anuraaga thanks for the great feedback! Very helpful. For the separate modules, how about:
:exporters:otlp:trace-http and :exporters:otlp:metrics-http (metrics to be added in a future PR)?

@codecov
Copy link

codecov bot commented Jul 23, 2021

Codecov Report

Merging #3418 (6ea11f4) into main (614668a) will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff              @@
##               main    #3418      +/-   ##
============================================
- Coverage     90.84%   90.83%   -0.02%     
  Complexity     3228     3228              
============================================
  Files           368      368              
  Lines          9941     9941              
  Branches       1003     1003              
============================================
- Hits           9031     9030       -1     
  Misses          598      598              
- Partials        312      313       +1     
Impacted Files Coverage Δ
...telemetry/sdk/trace/export/BatchSpanProcessor.java 88.18% <0.00%> (-0.79%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 60c3c5c...6ea11f4. Read the comment docs.

@jack-berg jack-berg marked this pull request as ready for review July 25, 2021 18:43
@jack-berg jack-berg requested a review from a user July 25, 2021 18:43
@jack-berg jack-berg requested a review from tylerbenson as a code owner July 25, 2021 18:43

private static final MediaType APPLICATION_PROTOBUF =
MediaType.create("application", "x-protobuf");
private static final HeldCertificate HELD_CERTIFICATE;
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: I've used the the certificate utility from okhttp-tls instead of the SelfSignedCertificateExtension seen in other tests. I did this because the certificate from SelfSignedCertificateExtension doesn't include a subject alternative name and the okhttp client fails TLS validation without this field.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yeah I noticed this too separately - quite bizarre okhttp restriction

Copy link
Contributor

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Thanks a lot, almost there


private static final MediaType APPLICATION_PROTOBUF =
MediaType.create("application", "x-protobuf");
private static final HeldCertificate HELD_CERTIFICATE;
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yeah I noticed this too separately - quite bizarre okhttp restriction

exporters/otlp-http/trace/build.gradle.kts Outdated Show resolved Hide resolved
exporters/otlp-http/trace/build.gradle.kts Outdated Show resolved Hide resolved
Copy link
Contributor

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Thanks, just found one small point left. @jkwatson is on vacation but let's give him a chance to review before merging.

@jkwatson
Copy link
Contributor

jkwatson commented Aug 3, 2021

Since this is a new module that isn't marked alpha, shouldn't there be apidiffs for it?

@jack-berg
Copy link
Member Author

@jkwatson actually could use a pointer on that. There's no apidiffs because I've commented out the id("otel.publish-conventions") in build.gradle.kts. And I've commented it out because I get the following error trying to run :build if its enabled:

Could not determine the dependencies of task ':exporters:otlp-http:trace:check'.
> Could not create task ':exporters:otlp-http:trace:jApiCmp'.
   > Could not resolve all files for configuration ':exporters:otlp-http:trace:detachedConfiguration1'.
      > Could not find io.opentelemetry:opentelemetry-exporter-otlp-http-trace:1.4.1.
        Searched in the following locations:
          - https://repo.maven.apache.org/maven2/io/opentelemetry/opentelemetry-exporter-otlp-http-trace/1.4.1/opentelemetry-exporter-otlp-http-trace-1.4.1.pom

Seems like a chicken and the egg issue: can't add publish conventions until there's an artifact out there that can be used as a comparison point for the apidiffs.

I know the apidiff stuff is fairly new - is there a playbook on how to proceed adding a new module?

@jkwatson
Copy link
Contributor

jkwatson commented Aug 3, 2021

I know the apidiff stuff is fairly new - is there a playbook on how to proceed adding a new module?

I thought @anuraaga had fixed this issue so that it would generate a new file for a new module.

Curious why you commented out publishing, though... shouldn't this be published?

@jack-berg
Copy link
Member Author

It should be published. I commented out publishing because the build fails with this error when publishing is enabled.

Let me see if I can't dig into it a bit more and get to the bottom of why new modules are causing this issue.

@jkwatson
Copy link
Contributor

jkwatson commented Aug 3, 2021

It should be published. I commented out publishing because the build fails with this error when publishing is enabled.

Let me see if I can't dig into it a bit more and get to the bottom of why new modules are causing this issue.

hmm. interesting. If you can't sort this out, I can try to take a look (or perhaps @anuraaga will know the problem right away).

@jack-berg
Copy link
Member Author

Looking closer at the otel.japicmp-conventions.gradle.kts config, I don't think this is actually a solved problem:

  • The jApiCmp task is added if the project does not have otel.release and does not start with bom. Because otel.release is reserved for alpha projects and this new project will not be alpha, it will get the jApiCmp task.
  • If we have to have this task, then we need to configure it to compare the latest jar to nothing, since no previous version exists. I can't find a way to configure jApiCmp to do a "compare to nothing". The oldClasspath property is what specifies what your comparing the new jar against, and its required.
  • The jApiCmp code was initially added on May 6th, 2021 in PR Add a task to compare public APIs for every stable module. #3183. If you look at the blame history of settings.gradle.kts, only one new project has been added since May 6th, :sdk:metrics-testing, and its exempt from the jApiCmp task because its marked as otel.release=alpha.

One way we could solve this is by adding another property to new projects that haven't been published yet, such as otel.initial-release. Then configure jApiCmp task to skip projects with this flag, and remove the flag after the first publication.

@jkwatson
Copy link
Contributor

jkwatson commented Aug 3, 2021

One way we could solve this is by adding another property to new projects that haven't been published yet, such as otel.initial-release. Then configure jApiCmp task to skip projects with this flag, and remove the flag after the first publication.

Something like this seems totally reasonable to me. Or, we institute a policy where every new module has to go through at least one alpha release before it is made non-alpha, which would also solve the problem. What do you think about that, @anuraaga ?

@anuraaga
Copy link
Contributor

anuraaga commented Aug 4, 2021

Do we need a new flag? I guess we can disable the task if oldClasspath is invalid, so that'd be pretty easy. If it's not obvious how to do it I can look into that. Let's merge this first though.

Copy link
Contributor

@jkwatson jkwatson left a comment

Choose a reason for hiding this comment

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

Thanks!

@jkwatson jkwatson merged commit 956912d into open-telemetry:main Aug 4, 2021
@sumitm-iiit
Copy link

Can someone please specify this change is part of which open telemetry java agent? I have tried with Open Telemetry Java Agent 1.5.3 but it seems this change is not present.

@Oberon00
Copy link
Member

Oberon00 commented Sep 7, 2021

I think you should ask that in https://github.com/open-telemetry/opentelemetry-java-instrumentation. As displayed by GitHub, this change is included in version 1.5.0 of "core" opentelemetry-java.

@sumitm-iiit
Copy link

@Oberon00 : Thank you for your quick response. Sure I will ask this question in htts://github.com/open-telemetry/opentelemetry-java-instrumentation..

@Oberon00
Copy link
Member

Oberon00 commented Sep 7, 2021

@sumitm-iiit BTW, under https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#otlp-exporter-both-span-and-metric-exporters there is otel.experimental.exporter.otlp.traces.protocol, maybe that is what you are looking for?

@sumitm-iiit
Copy link

sumitm-iiit commented Sep 7, 2021 via email

This was referenced Dec 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants