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

[4.x] - MicroProfile Telemetry Support #6493

Merged
merged 25 commits into from
May 11, 2023

Conversation

dalexandrov
Copy link
Contributor

Resolves #5817

Currently depends on opentelemetry-sdk-extension-autoconfigure 1.22.0-alpha.
This should be fixed with OTEL MP Telemetry committee.

@dalexandrov dalexandrov added MP 4.x Version 4.x TCK labels Mar 27, 2023
@dalexandrov dalexandrov self-assigned this Mar 27, 2023
@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Mar 27, 2023
WithSpan annotation = context.getMethod().getAnnotation(WithSpan.class);

Context parentContext = Context.current();
Scope scope = null;
Copy link
Member

Choose a reason for hiding this comment

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

There is no point in making this variable here and setting it to null, since it is not used till line 80 and set to value directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep

Copy link
Member

Choose a reason for hiding this comment

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

I am missing the change.

@dalexandrov dalexandrov changed the base branch from main to helidon-3.x April 8, 2023 08:51
@oracle-contributor-agreement oracle-contributor-agreement bot added OCA Required At least one contributor does not have an approved Oracle Contributor Agreement. and removed OCA Verified All contributors have signed the Oracle Contributor Agreement. labels Apr 8, 2023
@dalexandrov dalexandrov changed the base branch from helidon-3.x to main April 8, 2023 08:51
@oracle-contributor-agreement oracle-contributor-agreement bot added OCA Verified All contributors have signed the Oracle Contributor Agreement. and removed OCA Required At least one contributor does not have an approved Oracle Contributor Agreement. labels Apr 8, 2023
@dalexandrov dalexandrov marked this pull request as draft April 8, 2023 08:52
@dalexandrov dalexandrov marked this pull request as ready for review April 10, 2023 12:08
@dalexandrov dalexandrov force-pushed the 5817_MP_Telemetry branch 2 times, most recently from 02f4f91 to f5ef39c Compare April 19, 2023 13:30
@dalexandrov
Copy link
Contributor Author

Had to fallback to:

HashMap<String, String> telemetryProperties = new HashMap<>();
for (String propertyName : mpConfig.getPropertyNames()) {
          if (propertyName.startsWith("otel.")) {
              mpConfig.getOptionalValue(propertyName, String.class).ifPresent(
                      value -> telemetryProperties.put(propertyName, value));
     }
}

Otherwise fails with:

Caused by: java.util.NoSuchElementException: Property "env.GITHUB_BASE_REF" is not available in configuration
	at io.helidon.config.mp.MpConfigImpl.lambda$getValue$5(MpConfigImpl.java:122)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at io.helidon.config.mp.MpConfigImpl.getValue(MpConfigImpl.java:122)
	at io.helidon.config.mp.SeConfig.asMap(SeConfig.java:257)
	at io.helidon.config.mp.MpConfigProviderResolver$ConfigDelegate.asMap(MpConfigProviderResolver.java:341)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
	at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
	at io.helidon.config.Config$Config$_$$_WeldClientProxy.asMap(Unknown Source)

if using:

HashMap<String, String> telemetryProperties = new HashMap<>(config
                .asMap()
                .orElseGet(Map::of)
                .entrySet()
                .stream()
                .filter(k -> k.getKey().contains("otel"))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
);

if (LOGGER.isLoggable(System.Logger.Level.TRACE)) {
LOGGER.log(System.Logger.Level.TRACE, "Telemetry Disabled");
}
openTelemetry = LazyValue.create(() -> OpenTelemetry.noop());
Copy link
Member

Choose a reason for hiding this comment

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

Not fixed.

@PostConstruct
private void init() {

telemetryProperties = getTelemetryProperties();
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 intentional to use mutable Map here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wrapped into Collections.unmodifiableMap

private static final String REST_RESOURCE_CLASS = "rest.resource.class";
private static final String REST_RESOURCE_METHOD = "rest.resource.method";
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure why did you mark this as resolved without any response. Are these values stored in ContainerRequestContext actually used anywhere?

/**
* Provides an instance of the current OpenTelemetry Tracer.
*
* @param openTelemetry
Copy link
Member

Choose a reason for hiding this comment

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

missing description

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Redundant items deleted

* Used to register {@code HelidonTelemetryContainerFilter} and {@code HelidonTelemetryClientFilter}
* filers.
*
* @param ctx
Copy link
Member

Choose a reason for hiding this comment

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

missing description

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@dalexandrov dalexandrov requested a review from Verdent April 27, 2023 13:48
@dalexandrov dalexandrov force-pushed the 5817_MP_Telemetry branch from 85d6dc8 to 4c84dac Compare May 3, 2023 13:01
@dalexandrov dalexandrov force-pushed the 5817_MP_Telemetry branch from 4c84dac to 63fbd1f Compare May 3, 2023 13:08
Comment on lines 57 to 59
private Config config;

private org.eclipse.microprofile.config.Config mpConfig;
Copy link
Member

Choose a reason for hiding this comment

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

these two could be final.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

made final

Comment on lines +60 to +74
static {
CONTEXT_HEADER_INJECTOR =
new TextMapGetter<>() {
@Override
public String get(ContainerRequestContext containerRequestContext, String s) {
Objects.requireNonNull(containerRequestContext);
return containerRequestContext.getHeaderString(s);
}

@Override
public Iterable<String> keys(ContainerRequestContext containerRequestContext) {
return List.copyOf(containerRequestContext.getHeaders().keySet());
}
};
}
Copy link
Member

Choose a reason for hiding this comment

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

Would not this static block be better placed under the constant line it initializes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 41 to 43
private static final String HTTP_STATUS_CODE = "http.status_code";
private static final String HTTP_METHOD = "http.method";
private static final String HTTP_SCHEME = "http.scheme";
Copy link
Member

Choose a reason for hiding this comment

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

These constants are also created in HelidonTelemetryContainerFilter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

LOGGER.log(System.Logger.Level.TRACE, "Starting Span in a Client Request");
}

Context parentContext = Context.current();
Copy link
Member

Choose a reason for hiding this comment

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

Since this is not used on other places, the only usage could be replaced with Context.current() directly. This would make sense only it it was used in other places. But since on all places in this method, where Context is used, Context.current() is used instead, this is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

return context.proceed();
} catch (Exception e) {
span.recordException(e);
return context.proceed();
Copy link
Member

Choose a reason for hiding this comment

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

This line should be throw e

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed


@Test
@AddConfig(key = HelidonOpenTelemetry.OTEL_AGENT_PRESENT_PROPERTY, value = "true")
void shouldBeNoOpTelemetry(){
Copy link
Member

Choose a reason for hiding this comment

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

between ) and { should be space

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok


@Test
@AddConfig(key = HelidonOpenTelemetry.OTEL_AGENT_PRESENT_PROPERTY, value = "false")
void shouldNotBeNoOpTelemetry(){
Copy link
Member

Choose a reason for hiding this comment

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

between ) and { should be space

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

}

@Test
void checkEnvVariable(){
Copy link
Member

Choose a reason for hiding this comment

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

between ) and { should be space

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

* If the value is not explicitly set, the detector does best effort to estimate indirect means if the agent is present.
* This detector may stop working if OTEL changes the indirect indicators.
*/
public static class AgentDetector {
Copy link
Member

Choose a reason for hiding this comment

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

this is basically just a util class. It has to have private constructor and it should probably be final as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

}

private static boolean checkContext() {
return io.opentelemetry.context.Context.current().getClass().getName().contains("agent");
Copy link
Member

Choose a reason for hiding this comment

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

Context should be imported and used without fully qualified package.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@dalexandrov dalexandrov requested a review from Verdent May 4, 2023 12:34
Copy link
Member

@Verdent Verdent left a comment

Choose a reason for hiding this comment

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

Two more additional findings.

@dalexandrov dalexandrov requested a review from Verdent May 11, 2023 09:12
@dalexandrov dalexandrov dismissed tomas-langer’s stale review May 11, 2023 10:31

Approved by David

@dalexandrov dalexandrov merged commit 5f9eb47 into helidon-io:main May 11, 2023
@dalexandrov dalexandrov deleted the 5817_MP_Telemetry branch May 11, 2023 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.x Version 4.x MP OCA Verified All contributors have signed the Oracle Contributor Agreement. TCK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4.x: Add MP Telemetry 1.0
3 participants