Skip to content

Add support for native histograms in OM parser - #1040

Merged
csmarchbanks merged 11 commits into
prometheus:masterfrom
vesari:native-histogram-support
Sep 20, 2024
Merged

Add support for native histograms in OM parser#1040
csmarchbanks merged 11 commits into
prometheus:masterfrom
vesari:native-histogram-support

Conversation

@vesari

@vesarivesari commented Jun 18, 2024

Copy link
Copy Markdown
Contributor

This PR adds an OM parser for native histograms, as a first step towards the implementation of the following proposal prometheus/proposals#32 . The next steps (as far as this repo is concerned) would be the OM exposition and then obviously the implementation of native histograms generation/writing logic.

vesari added 7 commits June 15, 2024 18:12
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
…abel set
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>

@csmarchbankscsmarchbanks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a quick read through, but I was thinking maybe we limit the changes in the initial PR to just the parser changes? We could get that in and start iterating on it, and it will then be useful for testing the exposition changes.

Comment threadprometheus_client/metrics.py Outdated
registry: Optional[CollectorRegistry] = REGISTRY,
_labelvalues: Optional[Sequence[str]] = None,
buckets: Sequence[Union[float, str]] = DEFAULT_BUCKETS,
# native_hist_schema: Optional[int] = None, # create this dynamically?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe the internal code should create the schema, and may even change the schema value on occassion.

Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
@vesari

Copy link
Copy Markdown
ContributorAuthor

Just a quick read through, but I was thinking maybe we limit the changes in the initial PR to just the parser changes? We could get that in and start iterating on it, and it will then be useful for testing the exposition changes.

I totally agree!

…nd adapt logic accordigly
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>
@vesari
vesari marked this pull request as ready for review July 8, 2024 13:17
@vesari
vesari requested a review from csmarchbanksJuly 8, 2024 13:17
@vesarivesari changed the title WIP: Native histogram supportAdd support for native histograms in OM parserJul 9, 2024

@csmarchbankscsmarchbanks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! I left a handful of comments, they probably don't all need to be addressed in this PR, but could be refactorings in future PRs as well.

Mainly I would like to see as few changes to other files, and especially function signatures, as possible. Even if that means we do some things like skipping values that are histograms for now. That way hopefully no one depends on some code/type changes we might update soon.

Comment threadprometheus_client/bridge/graphite.py Outdated
Comment on lines +92 to +94
# using a safe float convert on s.value as a temporary workaround while figuring out what to do
# in case value is a native histogram structured value, if that's ever a possibility
output.append(f'{prefixstr}{_sanitize(s.name)}{labelstr} {safe_float_convert(s.value)} {now}\n')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Graphite doesn't have support for native histograms, if for some reason one shows up in a registry we would probably need to drop it with a warning. For now I would say let's not make any changes here as native histograms will be experimental anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

You're absolutely right. The thing is the mypy linter fails without this change. That's due to the native histogram value being a union. I noticed that only when I pushed the PR for the first time

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Solved after separating fields

Comment threadprometheus_client/openmetrics/parser.py
Comment on lines +422 to +426
else:
elems = pos_spans_text.split(',')
arg1 = [int(x) for x in elems[0].split(':')]
arg2 = [int(x) for x in elems[1].split(':')]
pos_spans = (BucketSpan(arg1[0], arg1[1]), BucketSpan(arg2[0], arg2[1]))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would avoid the else block and move these into the try block. That keeps all the happy path/text parsing code together.

Comment threadprometheus_client/registry.py Outdated
return m

def get_sample_value(self, name: str, labels: Optional[Dict[str, str]] = None) -> Optional[float]:
def get_sample_value(self, name: str, labels: Optional[Dict[str, str]] = None) -> Optional[Union[float, NativeHistStructValue]]:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this need to change yet? It would be nice to have no/minimal public interface changes since we won't be using these in the registry quite yet.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Same as for the Graphite bridge file. mypy linting fails otherwise.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Solved after separating fields

Comment threadprometheus_client/samples.py Outdated
name: str
labels: Dict[str, str]
value: float
value: Union[float, NativeHistStructValue]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Trying to decide if this should be a union or if we should have a separate field for histogram_value or something like that.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Given the union's "side-effects" in files like registry etc, maybe it should be a separate field? My initial thinking with the union was to possibly avoid function signature changes I guess, but maybe it wouldn't be that problematic?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, let's try having a separate Optional field for the native histogram and see what it looks like. It also makes it nice to just check if the value is none or not for if a value is a native histogram.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I separated them, and added a field for native histogram. I added it for last to minimize the risk of breaking something.

has_gsum = True
if s.value < 0:
has_negative_gsum = True
if len(suffix) != 0:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rather than nesting everything further in what about a continue if len(suffix) is 0?

Comment threadprometheus_client/openmetrics/parser.py
Comment threadprometheus_client/metrics.py Outdated
Comment on lines +598 to +605
# native_hist_schema: Optional[int] = None,
# native_hist_bucket_fact: Optional[float] = None,
# native_hist_zero_threshold: Optional[float] = None,
# native_hist_max_bucket_num: Optional[int] = None,
# native_hist_min_reset_dur: Optional[timedelta] = None,
# native_hist_max_zero_threshold: Optional[float] = None,
# native_hist_max_exemplars: Optional[int] = None,
# native_hist_exemplar_TTL: Optional[timedelta] = None,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's remove these commented out lines until they are actually used.

@vesari

Copy link
Copy Markdown
ContributorAuthor

Thanks for the suggested changes, I'll be working on it :)

Comment threadprometheus_client/samples.py Outdated
length: int


class NativeHistStructValue(NamedTuple):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a thought, we could probably just call this NativeHistogram rather than adding StructValue. For initial implementation we might want to prefix with _ as well to these new types to make it clear they are internal only and may change. Or add a comment to that effect.

…locks
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>

@csmarchbankscsmarchbanks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a couple of nits/removals and then I think this iteration is ready to merge! Thanks a bunch!

Comment threadprometheus_client/bridge/graphite.py Outdated
t = _RegularPush(self, interval, prefix)
t.daemon = True
t.start()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit, could you just remove this line so we don't have a needless diff/history entry?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done!

Comment threadprometheus_client/metrics_core.py Outdated
sum_value: Optional[float] = None,
labels: Optional[Sequence[str]] = None,
unit: str = '',
native_hist_bucket_factor: Optional[float] = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🤔 Not sure if we need this here at all (it will need to be in metrics.py). This function is for custom collectors, and I think if someone is creating a native histogram for that case they will end up needing to define all the spans themself. For now I would say just leave it out.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, I deleted it.

Comment threadprometheus_client/openmetrics/parser.py
# check if it's a native histogram with labels
re_nh_without_labels = re.compile(r'^[^{} ]+ {[^{}]+}$')
re_nh_with_labels = re.compile(r'[^{} ]+{[^{}]+} {[^{}]+}$')
print('we are matching \'{}\''.format(text))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should remove the debug printing before merging, there are a couple other lines in this function as well.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I could see just another one, I hope I removed them all now XD

Comment threadprometheus_client/openmetrics/parser.py
Comment threadprometheus_client/samples.py
Signed-off-by: Arianna Vespri <arianna.vespri@yahoo.it>

@csmarchbankscsmarchbanks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for all the work on this!

Sign up for freeto 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

@vesari@csmarchbanks