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

Remove generic argument from Histogram #103

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

fabianfett
Copy link
Member

In #92, we added a Histogram that is generic over the observed type. This means that each Histogram was also carrying a generic argument. To make it easier to deal with different Histogram types, we added two typealiases DurationHistogram and ValueHistogram.

The motivation behind using a generic argument was to preserve as much detailed information as possible. Duration can be more precise than Double. However in the grand scheme of things we now believe that this is overkill for a Histogram and a simpler to use Histogram type is more valuable than the lost precision. Thus this patch removes the generic argument from Histogram.

In swift-server#92, we added a Histogram that is generic over the observed type. This means that each Histogram was also carrying a generic argument. To work around this we created typealiases for `DurationHistogram` and `ValueHistogram`.

The motivation behind this was to preserve as much detailed information as possible. Duration can be more precise than Double. However in the grand scheme of things we now believe that this is overkill and a simpler to use Histogram type is more valuable. Thus this patch removes the generic argument from Histogram.
Copy link
Collaborator

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

I don't think this is the right direction.

I know doubles are "good enough" for time but but the API exposed as doubles always is really ugly.

We also now have an observe(Duration) on ANY histogram, even if it is actually e.g. sizes of things, which is rather ugly. The split was useful IMHO and I'm not sure why we should pull back on it - the PR doesn't really provide sufficient argument tbh.

If we just want to simplify implementation I'm sure we could just implement an underlying type over Double and expose two APIs for Double and specialized for Duration if that's the primary reason driving this change

@ktoso ktoso requested a review from tomerd September 26, 2023 13:07
@@ -67,20 +55,29 @@ public final class Histogram<Value: Bucketable>: Sendable {
state.count += 1
}
}

public func observe(_ value: Duration) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

So we could record durations into a histogram intended for values; this seems silly for our ecosystem in which we value type safety for such stuff.

.milliseconds(50),
.milliseconds(100),
factory.defaultTimerHistogramBuckets = [
0.005, 0.01, 0.025, 0.05, 0.1
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

This feels like a step backwards as well tbh

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that this feels like a step backwards

@fabianfett
Copy link
Member Author

@ktoso I should have stressed in my pr description more that I don't love this either and mainly want to drive a discussion here.

Copy link
Contributor

@FranzBusch FranzBusch left a comment

Choose a reason for hiding this comment

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

Sorry, I was a bit hasty with my previous approval and I mostly looked at the change for the metrics factory. I do agree that for the plain prometheus APIs this is a step backwards.
What pain did it cause that we want to drop the generic?

.milliseconds(50),
.milliseconds(100),
factory.defaultTimerHistogramBuckets = [
0.005, 0.01, 0.025, 0.05, 0.1
]
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that this feels like a step backwards

@fabianfett
Copy link
Member Author

@ktoso @FranzBusch @tomerd

What pain did it cause that we want to drop the generic?

Mostly requiring adopters to write generic code.

This feels like a step backwards as well tbh

I agree here as well. However, if we decide that Histogram should be generic, we should probably make Counter and Gauge generic as well. wdyt?

@FranzBusch
Copy link
Contributor

I agree here as well. However, if we decide that Histogram should be generic, we should probably make Counter and Gauge generic as well. wdyt?

Not sure. When would we use a Duration based Counter or Gauge? Maybe that's useful. From my understanding on this PR I thought we only had the generic abstractions to make the interop with Prometheus easier but not because of swift-metrics.

@fabianfett
Copy link
Member Author

fabianfett commented Sep 26, 2023

Not sure. When would we use a Duration based Counter or Gauge? Maybe that's useful. From my understanding on this PR I thought we only had the generic abstractions to make the interop with Prometheus easier but not because of swift-metrics.

@FranzBusch For Counter and Gauge generics would be more about Int64 vs UInt64 vs Double.

@fabianfett
Copy link
Member Author

@ktoso

Metric values in OpenMetrics MUST be either floating points or integers. Note that ingestors of the format MAY only support float64. The non-real values NaN, +Inf and -Inf MUST be supported. NaN MUST NOT be considered a missing value, but it MAY be used to signal a division by zero.

https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#values

@ktoso
Copy link
Collaborator

ktoso commented Sep 27, 2023

Yeah though that's about storage / emitting isn't it? so, maybe meet in the happy middle and keep the Duration histogram API but store in terms of Doubles if that's what you're after to simplify the implementation @fabianfett ?

Duration effectively "is" an integer.

I'm confused why the pushback to the language's default way of expressing duration. It'll be a pain to accept measurements from things which WILL express them as Duration.

What's the gain we're seeking by dropping support for Duration?

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