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

metrics.Sample.Metadata: Data structure for high cardinality tags #2726

Merged
merged 3 commits into from
Oct 17, 2022

Conversation

codebien
Copy link
Contributor

@codebien codebien commented Oct 13, 2022

This is built on top of #2654 and #2594 with a more limited scope and it closes #2584.

One of the main use cases for this support of high-cardinality metric tags/metadata is to allow k6 to support traces and to export the trace_id and span_id values it generated to something external like Tempo and Jaeger. The goal is to eventually have this with the new k6 HTTP API. However, this PR does not add a direct JavaScript API so the direct use of this feature will be only available from an extension.

One change from the original issue description has been the decision to not have a raw_url non-indexable url metadata and have a separate issue for tracking feedback and ideas.

@codebien codebien self-assigned this Oct 13, 2022
@codebien codebien requested a review from na-- October 13, 2022 08:52
@github-actions github-actions bot requested a review from oleiade October 13, 2022 08:52
@codebien codebien changed the title metrics: Sample.Metadata - Data structure for high cardinality tags metrics.Sample.Metadata: Data structure for high cardinality tags Oct 13, 2022
js/modules/k6/execution/execution.go Show resolved Hide resolved
lib/netext/httpext/transport.go Outdated Show resolved Hide resolved
metrics/tags.go Show resolved Hide resolved
mstoykov
mstoykov previously approved these changes Oct 13, 2022
Copy link
Contributor

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

LGTM!

I did a really fast pass over it, so might've have missed something.

Some things that we might want to fix (later):

  1. It is a bit inconsistant between using metadata and non-indexable. Both in the code and in the messaging to the user. Some of those likely can be mass changed now.
  2. I find state.Tags (and if we rename it to state.TagsAndMetadata) a bit ... strange. As it is combined in the state, but then we edit the separate parts and put it separately in the final samples.
  3. Emitting samples with the current tags never was ... nice as you needed to get the tags from one place add yours and then set the whole thing in the samples. I guess now that you need to get tags object from somewhere it will guide users to actuallyt get it from the lib.State. But it still clunky IMO. This is even more clunky with metadata - I would expect in most cases code will jsut not set metadata. Arguably having it combined in state.TagsAndMetadata guides to this as well 🤷 . I just find the whole thing not nice and not intuitive and not so hard to get wrong.

All of those though should likely be done in separate PRs ... likely after we have used the new code for a bit. And have discussed the js API for editing metadata/non-indexable nontags

me.logger.Warnf("Thresholds like '%s', based on the high-cardinality 'vu' metric tag, "+
"are deprecated and will not be supported in future k6 releases.", name,
me.logger.Warnf(
"The high-cardinality 'vu' metric tag was made non-indexable in k6 v0.41.0, so thresholds"+
Copy link
Contributor

Choose a reason for hiding this comment

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

nit; maybe change this message to not use non-indexable - I am not certain we should use metadata yet 🤷

maybe non-indexable is correct enough 🤷

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 don't think replacing non-indexable with metadata is better. If we can find something clearer I'm ok with it, otherwise, I would prefer to let as-is. I haven't a better suggestion at the moment.

@@ -58,7 +58,7 @@ func (j *JSTest) Foo(arg float64) (bool, error) {

ctx := j.vu.Context()

tags := state.Tags.GetCurrentValues().With("foo", "bar")
tags := state.Tags.GetCurrentValues().Tags.With("foo", "bar")
Copy link
Contributor

Choose a reason for hiding this comment

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

this seems bad .... Maybe just rename Tags to TagsAndMetadata for now?

I feel like it will be better if they are separate fields in state but this might take longer to do and I can see benefits for both, so I am for renaming and opening an issue to discuss the internal API and maybe make changes for the next release.

Copy link
Member

Choose a reason for hiding this comment

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

One of the big reasons for TagsAndMetadata to be packaged together like this was because, in the original PR, we treated them as 2 flavors of tags on the user-facing side, but internally we were saving them in completely different data structures.

We needed to lock them at the same time and we needed to remove corresponding tags when adding metadata and vice-versa:

k6/metrics/tags.go

Lines 176 to 180 in cd1e21d

func (tm *TagsAndMeta) SetTag(key, value string) {
tm.Tags = tm.Tags.With(key, value)
if tm.Metadata != nil {
delete(tm.Metadata, key)
}

k6/metrics/tags.go

Lines 185 to 186 in cd1e21d

func (tm *TagsAndMeta) SetMetadata(key, value string) {
tm.Tags = tm.Tags.Without(key)

Now that it's most likely we won't need to have differently-flavored (indexed / non-indexed) tags, a lot of this feels unnecessary 🤔 I guess the common locking and helper methods are still good to have, as well as the internal "accumulator" for the final atlas Tags value, and we don't have a lot of time to rewrite this now... 😞 But 👍 for renaming state.Tags to state.TagsAndMeta

Copy link
Contributor Author

@codebien codebien Oct 13, 2022

Choose a reason for hiding this comment

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

Considering we are going to open an issue I'm for not renaming now, and including the refactor as the first thing in the next release (v0.42.0). @na-- WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

👍 I am also fine with tackling this in next release, with maybe just a TODO in lib.State for now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added #2733 for tracking this

metrics/tags.go Outdated Show resolved Hide resolved
metrics/tags.go Outdated Show resolved Hide resolved
metrics/tags.go Outdated Show resolved Hide resolved
combinedLogFields[k] = v
}
}
for k, v := range preq.TagsAndMeta.Metadata {
Copy link
Member

Choose a reason for hiding this comment

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

Just in case, we should probably reverse the order here - first add the Metadata entries and then the Tags. That way, if there is a duplicate key, the tag value will be shown (which is probably more important 🤔

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 we split them into two sub-json-objects? I think could be relevant to see both, especially in debugging phases.

{
  // ...
  "iter": 10,
  "tags": {"key1":"val1",...},
  "meta": {"meta1":"val1"}
}

Copy link
Member

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 possible, and even if it is, it won't look nice with logrus. Since it's such a minor concern and only matters for --http-debug, I think we'd be fine with the current solution, just flipping the tags.

na--
na-- previously approved these changes Oct 16, 2022
Copy link
Member

@na-- na-- left a comment

Choose a reason for hiding this comment

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

Thank you! 🙇

olegbespalov
olegbespalov previously approved these changes Oct 17, 2022
Copy link
Contributor

@olegbespalov olegbespalov left a comment

Choose a reason for hiding this comment

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

In general, LGTM 👍 💪 Left a small non-blocking comment.

@@ -109,6 +109,8 @@ func TestTagSetContains(t *testing.T) {
assert.False(t, st.Contains(outer))
}

// TODO: Add TagsAndMeta tests
Copy link
Contributor

Choose a reason for hiding this comment

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

👀 should we add them with this PR?

mstoykov
mstoykov previously approved these changes Oct 17, 2022
@codebien codebien dismissed stale reviews from mstoykov, olegbespalov, and na-- via 0b07133 October 17, 2022 10:27
na--
na-- previously approved these changes Oct 17, 2022
@codebien
Copy link
Contributor Author

codebien commented Oct 17, 2022

@olegbespalov @na-- I added the tests and reversed the order of inserting tagsAndMeta for the logs.
If you will approve I will rebase and go through the process of pinning the right experimental version for the xk6-websockets.

na--
na-- previously approved these changes Oct 17, 2022
mstoykov
mstoykov previously approved these changes Oct 17, 2022
na-- and others added 2 commits October 17, 2022 12:44
Remove for a temporary commit the experimental module to allow bumping
the k6 dependency in the extension's repository.
@codebien codebien dismissed stale reviews from mstoykov and na-- via 3c97ec7 October 17, 2022 11:00
Uses the [email protected] version that is now migrated to the
new metadata for non-indexable tags.
@codebien codebien merged commit 0568f27 into master Oct 17, 2022
@codebien codebien deleted the metrics-metadata branch October 17, 2022 13:04
@codebien codebien added this to the v0.41.0 milestone Oct 17, 2022
@na-- na-- added the breaking change for PRs that need to be mentioned in the breaking changes section of the release notes label Oct 28, 2022
sid-maddy pushed a commit to sid-maddy/k6 that referenced this pull request Oct 23, 2023
See grafana#2950 and grafana#2726 (comment) for more information.

Signed-off-by: Siddhesh Mhadnak <[email protected]>
sid-maddy added a commit to sid-maddy/k6 that referenced this pull request Oct 25, 2023
See grafana#2950 and grafana#2726 (comment) for more
information.

Signed-off-by: Siddhesh Mhadnak <[email protected]>
@mstoykov mstoykov mentioned this pull request Mar 14, 2024
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change for PRs that need to be mentioned in the breaking changes section of the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support non-indexable high-cardinality metric tags / metadata
4 participants