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

Migrate Metrics SDK "data' package to Attributes #3352

Merged
merged 8 commits into from
Jul 1, 2021

Conversation

jsuereth
Copy link
Contributor

With the Labels removal in the new Metrics API, this is a first cut at changing the existing implementation in preparation for the new SDK.

What this PR brings:

  • The io.opentelmetry.sdk.metrics.data package now uses the io.opentelemetry.api.common.Attributes type instead of the old Labels type.
  • An AssertJ testing DSL for all the various types in the *.metrics.data package. This is designed to:
    • Solve floating-point equality precision-in-testing concerns in one locations
    • Be resilient to order-concerns of points / attributes
    • Have easily readable expectations and error messages
  • Update all existing tests that either used Labels or relied on ordering/equality of Labels instances to use new Assertj library for metrics.

Note: Summary is effectively deprecated in the OTel Data model (for backwards compat primarily), so it remains for OpenCensus Shims (Summary is also deprecated in OpenCensus) and I did not provide convenience APIs for summary. In the new SDK no instrument will output a summary by default.

jsuereth and others added 2 commits June 23, 2021 20:21
- Finish wiring through changes to all code/tests.
- DOES NOT touch API
- Update existing tests to use new testing library to be sensitive to attribute vs. label hashing alterations + equality of the metrics.data package types.
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.

Just some small comments, no blockers. Thanks!

labelNames.add(sanitizedLabelName);
// TODO: We want to create an error-log if there is overlap in toString of attribute
// values for the same key name.
labelValues.add(value == null ? "" : value.toString());
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't believe we support null values anymore, think we may have at some point before

Copy link
Contributor Author

Choose a reason for hiding this comment

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

should I remove the check or keep it for safety?

assertThat(pointData.getLabels().size()).isEqualTo(0);

assertThat(metric)
.hasName("double_gauge")
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice

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!

.hasDescription("double gauge")
.hasUnit("ms")
.hasDoubleGauge()
.points()
Copy link
Contributor

Choose a reason for hiding this comment

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

Tend to like not switching gears in an assertion (i.e., allowing a further assertion on the metric after this one) with something like pointsSatisfyExactly(...). One reason is for the indentation to match the structure. I guess it's mostly just personal preference though so don't mind too much

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 hear you. I chose the methods to match existing patterns in Assertj, particularly around Iterables/Collections.

The TL;DR: is this matches Assertj even if I'm more of a hamcrest fan myself (primarily for composability).

Want to call out two things:

  1. The goal of this library is folks STOP using exact ordering where it's not important (you can choose when, but prefer inAnyOrder if you don't know whether order matters). If you look at examples there's a lot of .points().satisfiesExactlyInAnyOrder.
  2. There's a lot of Iterable matches I don't want to do a combinatorial explosion on providing, similar for Attributes. I could take an approach here (similar to what I did for Attribtues) where you can go into a .points or use a hasPoints that implicitly uses "containsInAnyOrder".

}

description = "OpenTelemetry SDK Testing utilities"
otelJava.moduleName.set("io.opentelemetry.sdk.metrics-testing")
Copy link
Contributor

Choose a reason for hiding this comment

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

We've generally suffixed with metrics in all our packages (even had a gradle hack that matched the suffix before the more declarative gradle.properties :P). Since alpha and eventually will be merged into testing doesn't matter too much though

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If possible, I'd like to avoid chaning the module name (and directory) because I have a slew of PRs lined up behind this one for the new metrics implementation and the least amount of major rebasing I need to do, the better.

If this were a fundamental naming issue (or something that wouldn't be resolved when metrics goes stable) I'd be happy to change it, but as things are my commits are starting to get unwieldy if I leave this two long (hence trying to piece out components like this one for review).

Copy link
Contributor

Choose a reason for hiding this comment

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

we can always go back and change module names at the end of the PR chain, if anyone feels strongly about it.

}

/** Ensures the {@link Resource} associated with a metric matches the expected value. */
public MetricDataAssert hasResource(Resource resource) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about just hasResourceAttributes and hasResourceAttributesSatisfying? Resource only has one field, attributes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While I half-agree, in practice almost all the tests (and code) just pass Resource wholesale, and check for the one static instance that was given to an SDK. Very rarely are folks checking resource detection/attribute scenarios in Metrics code.

I imagine you could add those two methods, but I don't think I'd wind up using them for most of the metrics tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

just FYI, Resource also has schemaUrl now; not sure if that alters the fundamentals, though.

sdk/metrics/build.gradle.kts Outdated Show resolved Hide resolved
sdk/metrics/build.gradle.kts Show resolved Hide resolved
Copy link
Member

@pirgeo pirgeo left a comment

Choose a reason for hiding this comment

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

There seems to be an empty file named point.getAttributes()) in the repo root. Is this intentional?

@jsuereth
Copy link
Contributor Author

There seems to be an empty file named point.getAttributes()) in the repo root. Is this intentional?

@pirgeo No, that was a botched commit from windows on my part. Must have done something dumb w/ copy-paste on the terminal. Fixed.


/** Test assertions for {@link PointData}. */
public class AbstractPointDataAssert<
PointAssertT extends AbstractPointDataAssert<PointAssertT, PointT>,
Copy link
Contributor

Choose a reason for hiding this comment

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

this style of type declaration isn't something we've used in the project up until now. I'm not fundamentally opposed to it, but it's definitely more verbose. @anuraaga any thoughts on this? Otherwise, I would think we'd want to go with <A,P> or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you think A/P is more readable, happy to change. I chose what I did because I kept messing up the letters, otherwise.

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 not block this PR on it. It's a simple thing to change in the future.

@jkwatson
Copy link
Contributor

I will admit I did not look at every single converted assertion, but this looks pretty good. Thanks for all the effort! Just a couple tiny nits and one question about generic type naming.

@jkwatson jkwatson merged commit b12a57e into open-telemetry:main Jul 1, 2021
@sullis sullis mentioned this pull request 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.

4 participants