Skip to content
This repository has been archived by the owner on Aug 13, 2019. It is now read-only.

Correctly handle empty labels. #594

Merged
merged 1 commit into from
May 7, 2019
Merged

Correctly handle empty labels. #594

merged 1 commit into from
May 7, 2019

Conversation

brian-brazil
Copy link
Contributor

Currently a time series with empty labels is not treated the same
as one with missing labels. Currently this can only come from
ALERTS&ALERT_FOR_STATE so it's unlikely anyone has actually hit it.

@beorn7 FYI

labels/labels.go Outdated
@@ -103,6 +103,23 @@ func (ls Labels) Map() map[string]string {
return m
}

// WithoutEmpty returns the labelset without empty labels.
// May return the same the same labelset..
Copy link
Contributor

Choose a reason for hiding this comment

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

"the same the same"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the same

Copy link
Contributor

@beorn7 beorn7 left a comment

Choose a reason for hiding this comment

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

Potentially dumb questions (I'm not very familiar with prometheus/tsdb):

  • Should the behavior be documented in the Appender interface? (e.g. "labels with empty values are discarded during append")
  • Does the querier follow the same semantics? (if I query for labels with empty values, it means the same as not querying for that label)

labels/labels.go Outdated
func (ls Labels) WithoutEmpty() Labels {
for _, v := range ls {
if v.Value == "" {
els := make(Labels, 0, len(ls))
Copy link
Contributor

Choose a reason for hiding this comment

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

els will be at least one shorter than ls. Thus, len(ls)-1 should be strictly better than len(ls).

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree, but potentially does not matter as there might be even more empty values in set.

Copy link
Contributor

Choose a reason for hiding this comment

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

Even then we waste one less element if using len(ls)-1. That's what I mean by “strictly better”.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not that it matters a lot, of course. Performance-wise, that is.

In my way of viewing things, doing len(ls)-1 is actually a readability improvement. As the code reader, I start to think about possible reasons why len(ls) was used and why my understanding of the code (which suggests that at most len(ls)-1 will be needed) might be wrong.

If performance wouldn't matter at all, I would not pre-allocate anything for maximum readability.
In this case, I think len(ls)-1 > no pre-allocation > len(ls)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for clarification, we are definitely on the same page @beorn7 (:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

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

Small nit, otherwise LGTM

@@ -103,6 +103,23 @@ func (ls Labels) Map() map[string]string {
return m
}

// WithoutEmpty returns the labelset without empty labels.
// May return the same labelset.
func (ls Labels) WithoutEmpty() Labels {
Copy link
Contributor

@bwplotka bwplotka Apr 26, 2019

Choose a reason for hiding this comment

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

Maybe my personal opinion, but I would say just function is better here as it has to be done only once at certain code logic.

Having this as Labels method indicates you need to do it a lot... but we don't want unnecceary run through all labels if not needed.

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 this turns out to be a bigger problem than I think, we'll need to sprinkle this across the codebase.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't feel strongly either way.

labels/labels.go Outdated
func (ls Labels) WithoutEmpty() Labels {
for _, v := range ls {
if v.Value == "" {
els := make(Labels, 0, len(ls))
Copy link
Contributor

Choose a reason for hiding this comment

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

We might be able to do it in less indent (more verbose), but not a blocker.

@brian-brazil
Copy link
Contributor Author

Does the querier follow the same semantics?

Yes, we go to a good bit of effort to do so. These are the general semantics of PromQL.

Currently a time series with empty labels is not treated the same
as one with missing labels. Currently this can only come from
ALERTS&ALERT_FOR_STATE so it's unlikely anyone has actually hit it.

Signed-off-by: Brian Brazil <[email protected]>
@brian-brazil
Copy link
Contributor Author

Are there any other comments on this?

@brian-brazil brian-brazil merged commit 6ac81cc into master May 7, 2019
@brian-brazil brian-brazil deleted the empty-labels branch May 7, 2019 10:00
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants