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

Thread count and classes loaded handlers #571

Conversation

roberttoyonaga
Copy link
Contributor

Description:
Add handlers for thread count and loaded classes count metrics. These are derived from jdk.ClassLoadingStatistics and jdk.JavaThreadStatistics JFR events

Testing:
A new unit test was added to test these handlers in jfr-streaming/src/test/java/io/opentelemetry/contrib/jfr/metrics.

@roberttoyonaga roberttoyonaga requested a review from a team November 7, 2022 15:14
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Nov 7, 2022

CLA Signed

The committers listed above are authorized under a signed CLA.

Copy link
Contributor

@breedx-splk breedx-splk left a comment

Choose a reason for hiding this comment

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

Hi @roberttoyonaga. Thanks for this contribution. I made a few suggestions, but it looks pretty good overall. Appreciate it.

@Override
public void initializeMeter(Meter meter) {
meter
.gaugeBuilder(METRIC_NAME)
Copy link
Contributor

Choose a reason for hiding this comment

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

This event has unloadedClassCount and loadedClassCount, both of which seem like they would be better modeled by monotonically increasing counters instead of a gauge. While unloads may be uncommon, they do happen, and if one of the goals of this class is to give an idea of the total classes currently loaded, both values should be tracked and the delta reported in the callback.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, please take a look at the OpenTelemetry JVM Metrics specification, which currently lists these metrics, which you should conform to:

  • process.runtime.jvm.classes.loaded
  • process.runtime.jvm.classes.unloaded
  • process.runtime.jvm.classes.current_loaded

I think this handler can probably provide all 3, but if you wanted to wait an do current_loaded in another implementation/PR that would be fine too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the review! I've changed it to use monotonically increasing counters and also added an implementation for process.runtime.jvm.classes.current_loaded with an upDownCounter. I've corrected the instrument, unit, and descriptions so that they now should conform to the specification.

public Optional<Duration> getPollingDuration() {
return Optional.of(Duration.ofSeconds(1));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would appreciate a unit test that covers the behavior of this class in isolation.

public Optional<Duration> getPollingDuration() {
return Optional.of(Duration.ofSeconds(1));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would like to see a unit test that covers this class in isolation as well.

}

@Test
public void shouldHaveJfrPeriodicEvents() throws Exception {
Copy link
Contributor

@breedx-splk breedx-splk Nov 8, 2022

Choose a reason for hiding this comment

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

I think there's bad precedent elsewhere in this repo, but with JUnit5 you shouldn't need the test class nor test method to be public I think. Preference is to just make them package to save chars and improve readability. :)

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!

import jdk.jfr.consumer.RecordedEvent;

public final class ThreadCountHandler implements RecordedEventHandler {
private static final String METRIC_NAME = "process.runtime.jvm.cpu.active_threads";
Copy link
Member

Choose a reason for hiding this comment

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

The OpenTelemetry spec defines process.runtime.jvm.threads.count, can you make sure that this implementation of JVM metrics conforms to it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review! I've changed the thread count handler so that it now properly implements the specification.

Copy link
Contributor

@breedx-splk breedx-splk 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 with these changes! Looking good to me.

It's a slight bummer that the tests currently have these sleeps in them. That approach tends not to scale well as the size of the codebase grows, but we can circle back on that another time. I still would have liked to see unit tests for the handlers and not just integration style tests, but that too can be added later.

Copy link
Contributor

@kittylyst kittylyst left a comment

Choose a reason for hiding this comment

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

LGTM. I +1 @breedx-splk comments about not using sleep() in tests, but I don't think that should hold up a merge of this.

public final class ClassesLoadedHandler implements RecordedEventHandler {
private static final String METRIC_NAME_LOADED = "process.runtime.jvm.classes.loaded";
private static final String METRIC_NAME_UNLOADED = "process.runtime.jvm.classes.unloaded";
private static final String METRIC_NAME_CURRENT = "process.runtime.jvm.classes.current_loaded";
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we document somewhere what the difference is between classes.loaded and classes.current_loaded? Maybe link to that definition here?

Copy link
Member

Choose a reason for hiding this comment

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

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 added some comments for further clarity. The metric descriptions also add some information.

public final class ClassesLoadedHandler implements RecordedEventHandler {
private static final String METRIC_NAME_LOADED = "process.runtime.jvm.classes.loaded";
private static final String METRIC_NAME_UNLOADED = "process.runtime.jvm.classes.unloaded";
private static final String METRIC_NAME_CURRENT = "process.runtime.jvm.classes.current_loaded";
Copy link
Member

Choose a reason for hiding this comment

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

…cs/internal/threads/ThreadCountHandler.java

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
…:roberttoyonaga/opentelemetry-java-contrib into thread-count-and-classes-loaded-handlers
…cs/JfrThreadCountTest.java

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
@trask trask merged commit ab64bfd into open-telemetry:main Nov 11, 2022
@trask
Copy link
Member

trask commented Nov 11, 2022

thx @roberttoyonaga!

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.

6 participants