Skip to content

Conversation

avolokhov
Copy link
Contributor

This PR removes labels parametrisation which fixes a leaking bucket/quantile serialisation detail that may have led to a problem if quantile/bucket is unintentionally set from the outside code as well as optimises metric emission performance.
This is a breaking change since custom labels will not be supported any more, however there's an argument that labels are indeed just a list of key value pairs, any customisation on top of it can as well be done as a wrapper to PrometheusClient. The part of the api that serves as swift-metrics backend remained fully compatible.

Checklist

  • [ + ] The provided tests still run.
  • [ N/A ] I've created new tests where needed.
  • [ N/A ] I've updated the documentation if necessary.

Motivation and Context

  • leaking abstraction in DimensionHistogramLabels and DimensionSummaryLabels
  • simplifying PrometheusClient api surface, removing unnecessary overloads
  • optimising performance by reducing a number of virtual table lookups

Description

This PR brings a few optimisations to how SwiftPrometheus handle labels:

  • previously the library was leaking a confusing le in DimensionHistogramLabels and quantile in DimensionSummaryLabels: these fields were never supposed to be set and are never used in an actual computations. In this PR I leveraged the fact that these fields are only used during serialisation and made corresponding EncodableDimensions- types internal. This allowed me to make all metric types to accept plain DimensionLabels, which resulted in less code and less fluffy PrometheusClient api. From the performance point of view this change is beneficial because it removes a generic and reduces a number of virtual lookups on metric emission flow.

@avolokhov
Copy link
Contributor Author

cc @tomerd

@avolokhov
Copy link
Contributor Author

Hi @MrLotU! Thanks for considering this PR. This PR has a few assumptions in mind, just wanted to check if I got the idea right. I keep looking at the library performance and the biggest culprit for metric emission flow is virtual table lookups when figuring out parametrisation on PromMetric types. Since swift-metric api is generic and only expose <metricType>Handler protocols, removing the parametrisation is the only way to have big performance gains. It breaks a may break a few things for those who try using PrometheusClient directly, however I failed to see a lot (any) use cases where someone might want anything other that provided DimensionLabels for labels implementation. Please let me know if I missed something and there's a use case that won't be possible with the above changes. My main reasoning was that most of the users would use the library as a backend to swift-metrics and won't be exposed to this customisation anyway and that using swift-metrics is an encouraged way to use this library as well.


self.quantiles = quantiles

self.labels = labels
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Parent Summary was always created with empty labels. subHistogram labels were stored twice: as a key in subSummaries and as a field in corresponding subSummary value. I just removed the duplication.

@MrLotU
Copy link
Collaborator

MrLotU commented Jun 3, 2022

Hey @avolokhov,

Thanks for your PR, and my apologies it took me so long to respond to it. Your point about performance makes a lot of sense, and I agree there will probably not be many people interacting with the current label structs directly, and I also see no reason people would not be able to move to the new dimension based approach.

I've added 2 (minor) commits to your PR, mostly addressing documentation & examples, but also changing somefunctional aspects:

  • Since MetricLabels was not used directly anymore anywhere, I opted to remove it entirely.
  • I conformed DimensionLabels to ExpressibleByArrayLiteral to allow for a cleaner end-user API, more in line with swift-metrics.
  • I removed the two deprecations you added. Since we're still in alpha, breaking changes are allowed. The goal is to push a SwiftPrometheus 1.0 release relatively soon, and at that point it'd make little sense to leave these deprecations in.

Please let me know what you think!

@avolokhov
Copy link
Contributor Author

Perfect, thanks for the cleanup, @MrLotU. Sorry I was careless about the documentation.

@MrLotU MrLotU requested a review from ktoso June 5, 2022 10:17
@MrLotU MrLotU changed the base branch from master to release_1 June 17, 2022 13:53
@MrLotU MrLotU merged commit d39c127 into swift-server:release_1 Jun 17, 2022
MrLotU added a commit that referenced this pull request Jun 20, 2022
* Sanitize Dimensions (#68)

* Add failing test for sanitising dimension

* Fix test

* Add new DimensionsSanitizer

* Remove labels parametrisation (#63)

* Stop leaking 'le', 'quantile' in Summary/Histogram labels, remove labels parametrisation

* chore: Remove base labels protocol and add ExpressibleByArrayLiteral

* chore: Cleanup documentation. Remove deprecations

Co-authored-by: Jari (LotU) <[email protected]>

* Add async/await APIs (#67)

* Add async/await APIs

* Revert unrelated change

* Add #if swift for 5.2

* Fix Swift version number check

* Add task API

Co-authored-by: Tim Condon <[email protected]>
Co-authored-by: Anton <[email protected]>
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.

2 participants