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

Prototype histogram advice API (i.e. Hints) #5217

Merged
merged 8 commits into from
Apr 11, 2023

Conversation

jack-berg
Copy link
Member

@jack-berg jack-berg commented Feb 15, 2023

A prototype extension to the metric API to allow instrumentation authors to optionally provide advice on histogram bucket boundaries. Advice only applies if there are no matching views and if the reader has no preference for the histogram bucket boundaries.

Here's a code snippet that demonstrates usage and behavior:

    InMemoryMetricReader reader = InMemoryMetricReader.create();
    meterProvider = SdkMeterProvider.builder().registerMetricReader(reader).build();
    DoubleHistogram doubleHistogram =
        ((ExtendedDoubleHistogramBuilder) meterProvider
            .get("meter")
            .histogramBuilder("histogram"))
            .setAdvice(
                advice -> advice.setExplicitBucketBoundaries(Arrays.asList(10.0, 20.0, 30.0)))
            .build();

    doubleHistogram.record(5.0);
    doubleHistogram.record(15.0);
    doubleHistogram.record(25.0);
    doubleHistogram.record(35.0);

    // Bucket bounds from advice should be used
    assertThat(reader.collectAllMetrics())
        .satisfiesExactly(
            metric ->
                assertThat(metric)
                    .hasName("histogram")
                    .hasHistogramSatisfying(
                        histogram ->
                            histogram.hasPointsSatisfying(
                                point ->
                                    point
                                        .hasBucketCounts(1, 1, 1, 1)
                                        .hasBucketBoundaries(10.0, 20.0, 30.0))));

@codecov
Copy link

codecov bot commented Feb 15, 2023

Codecov Report

Patch coverage: 95.12% and project coverage change: -0.03 ⚠️

Comparison is base (2babc69) 90.98% compared to head (34b6a73) 90.96%.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #5217      +/-   ##
============================================
- Coverage     90.98%   90.96%   -0.03%     
- Complexity     4908     4918      +10     
============================================
  Files           552      555       +3     
  Lines         14489    14518      +29     
  Branches       1372     1373       +1     
============================================
+ Hits          13183    13206      +23     
- Misses          906      911       +5     
- Partials        400      401       +1     
Impacted Files Coverage Δ
...ubator/metrics/ExtendedDoubleHistogramBuilder.java 0.00% <0.00%> (ø)
...ncubator/metrics/ExtendedLongHistogramBuilder.java 0.00% <0.00%> (ø)
...io/opentelemetry/sdk/metrics/SdkDoubleCounter.java 100.00% <ø> (ø)
...ntelemetry/sdk/metrics/SdkDoubleUpDownCounter.java 100.00% <ø> (ø)
...opentelemetry/sdk/metrics/SdkLongGaugeBuilder.java 100.00% <ø> (ø)
...lemetry/sdk/metrics/AbstractInstrumentBuilder.java 98.14% <100.00%> (+0.23%) ⬆️
.../opentelemetry/sdk/metrics/SdkDoubleHistogram.java 100.00% <100.00%> (ø)
...io/opentelemetry/sdk/metrics/SdkLongHistogram.java 100.00% <100.00%> (ø)
...emetry/sdk/metrics/internal/descriptor/Advice.java 100.00% <100.00%> (ø)
...rics/internal/descriptor/InstrumentDescriptor.java 100.00% <100.00%> (ø)
... and 3 more

... and 3 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@jack-berg jack-berg changed the title Prototype histogram advice API Prototype histogram advice API (i.e. Hints) Feb 15, 2023
Copy link
Member

@mateuszrzeszutek mateuszrzeszutek left a comment

Choose a reason for hiding this comment

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

Awesome!


class AdviceTest {

private SdkMeterProvider meterProvider = SdkMeterProvider.builder().build();
Copy link
Member

Choose a reason for hiding this comment

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

Nit: this value does not seem to be used anywhere

@@ -32,6 +34,11 @@ public interface DoubleHistogramBuilder {
*/
DoubleHistogramBuilder setUnit(String unit);

/** Specify advice for histogram implementations. */
default DoubleHistogramBuilder setAdvice(Consumer<HistogramAdviceConfigurer> adviceConsumer) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: are we planning to add this to the API right away? Or perhaps introduce it in an internal interface first?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm open to different options. Could make it an internal interface, or add it to the api incubator, or wait on merging until the spec is marked stable.

I think I like the idea of an internal interface the best.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've split out the interfaces to :extensions:incubator.

To use, add a dependency on opentelemetry-extension-incubator, and cast the histogram builder to the extended version of the interface:
-((ExtendedDoubleHistogramBuilder) meter.histogramBuilder("histogram")).setAdvice(...)
-((ExtendedLongHistogramBuilder) meter.histogramBuilder("histogram").ofLongs()).setAdvice(...)

import java.util.List;

/** Configure advice for implementations of {@link LongHistogram} and {@link DoubleHistogram}. */
public interface HistogramAdviceConfigurer {
Copy link
Contributor

Choose a reason for hiding this comment

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

do you envision this having more methods added, or could we add @FunctionalInterface to it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think more methods will be added. One that seems likely is a set of attribute keys to retain by default (spec Issue #3061). The idea being that instrumentation can record a wider set of attributes while only retaining a smaller set by default. Users can then opt into additional attributes via views.

@jack-berg jack-berg marked this pull request as ready for review March 9, 2023 21:16
@jack-berg jack-berg requested a review from a team March 9, 2023 21:16
@jack-berg
Copy link
Member Author

Marked this PR as ready for review. The idea has reasonable support in the specification, and I will continue to drive it. In the meantime, I've adjusted the PR to move the advice APIs to opentelemetry-extension-incubator, so its actually in a reasonable state to merge.

Copy link
Member

@mateuszrzeszutek mateuszrzeszutek left a comment

Choose a reason for hiding this comment

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

This is awesome 💯🚀

@jack-berg
Copy link
Member Author

Hey @open-telemetry/java-instrumentation-maintainers if the advice API were to be merged in this form, in which its exposed in the extensions API component, would we be able to use it in instrumentation? Also, would we be comfortable using an experimental API in instrumentation?

I think it would be really useful in cases like the gc duration histogram metric, which would benefit a lot from tuning the buckets to match the duration we typically expect for garbage collection events.

jack-berg added a commit to open-telemetry/opentelemetry-specification that referenced this pull request Apr 8, 2023
Fixes #2229.
Related to #3061 (lays groundwork but does not resolve).
Related to #2977, which may use this new API to have
`http.server.duration` report in seconds instead of ms without changing
/ breaking default bucket boundaries.

Summary of the change:
- Proposes a new parameter to optionally include when creating
instruments, called "advice".
- For the moment, advice only has one parameter for specifying the
bucket boundaries of explicit bucket histogram.
- Advice can be expanded with additional parameters in the future (e.g.
default attributes to retain). The parameters may be general (aka
applicable to all instruments) or specific to a particular instrument
kind, like bucket boundaries.
- Advice parameters can influence the [default
aggregation](https:/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#default-aggregation),
which is used if there is no matching view and if the reader does not
specify a preferred aggregation.
- Not clear that all advice will be oriented towards configuring
aggregation, so I've intentionally left the scope of what they can
influence open ended.

I've prototyped this in java
[here](open-telemetry/opentelemetry-java#5217).
Example usage:
```
DoubleHistogram doubleHistogram =
        meterProvider
            .get("meter")
            .histogramBuilder("histogram")
            .setUnit("foo")
            .setDescription("bar")
            .setAdvice(
                advice -> advice.setBoundaries(Arrays.asList(10.0, 20.0, 30.0)))
            .build();
```

Advice could easily be changed to "hint" with everything else being
equal. I thought "advice" clearly described what we're trying to
accomplish, which is advice / recommend the implementation in providing
useful output with minimal configuration.

---------

Co-authored-by: Reiley Yang <[email protected]>
@mateuszrzeszutek
Copy link
Member

would we be able to use it in instrumentation?

I think so; we'll just have to put extensions on the bootstrap classpath.

Also, would we be comfortable using an experimental API in instrumentation?

Personally: as long as we're not exposing this in any public API, sure 💯. I've been hoping to use the advice API in the micrometer bridge for a while.

@jack-berg
Copy link
Member Author

That's great @mateuszrzeszutek.

@jkwatson can you take a look at this when you have a chance? The spec PR proposing this change has been merged.

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.

3 participants