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

ref(spans): JSON Kafka message with metadata #2556

Merged
merged 27 commits into from
Oct 4, 2023
Merged

Conversation

jjbayer
Copy link
Member

@jjbayer jjbayer commented Sep 29, 2023

This PR makes the following changes to the relay -> sentry kafka schema for spans:

  • [breaking change] Encode the payload as JSON, not msgpack. Msgpack should only be used for payloads that contain (partial) binary data.
  • Add the fields organization_id and retention_days so the consumer does not have to look them up.
  • [through ref(spans): Write sentry tags to dedicated field #2555] New field span.sentry_tags can be used instead of span.data. It now contains the same keys as expected by snuba. The values are guaranteed to be strings.
  • Some extra validation to make sure we do not send corrupted data.

Sentry counterpart: getsentry/sentry#57284

Copy link
Contributor

@phacops phacops left a comment

Choose a reason for hiding this comment

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

Can you add profile_id as well? Only filled if the profile context contains a profile_id key. Should be filled for every spans generated by the transaction (and the segment as well).

relay-server/src/actors/store.rs Outdated Show resolved Hide resolved
relay-server/src/actors/store.rs Outdated Show resolved Hide resolved
relay-server/src/actors/store.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@phacops phacops left a comment

Choose a reason for hiding this comment

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

I noticed some values missing from before or which could be added to help:

  • description
  • start_timestamp_ms

Is group in the sentry_tags guaranteed to be a good value (convertible to an hex value)?

And regarding tags and sentry_tags, can we make sure we don't add a None value?

@jjbayer jjbayer changed the title ref(spans): Kafka spans schema V1 ref(spans): JSON Kafka message with metadata Oct 3, 2023
Comment on lines 2392 to 2412
exclusive_time
.value()
.ok_or(anyhow::anyhow!("missing exclusive_time"))?;

if let Some(sentry_tags) = sentry_tags.value_mut() {
sentry_tags.retain(|key, value| match value.value() {
Some(s) => {
if key == "group" {
// Only allow 16-char hex strings in group.
s.len() == 16 && s.chars().all(|c| c.is_ascii_hexdigit())
} else {
true
}
}
// Drop empty string values.
None => false,
});
}
if let Some(tags) = tags.value_mut() {
tags.retain(|_, value| !value.is_empty())
}
Copy link
Member Author

Choose a reason for hiding this comment

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

@phacops this should give some additional guarantees about the data.

Copy link
Contributor

Choose a reason for hiding this comment

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

If tags is not None but it's empty, is it forwarded as an empty object?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably. The consumer should be able to handle that though.

@jjbayer jjbayer marked this pull request as ready for review October 3, 2023 14:01
@jjbayer jjbayer requested review from a team and phacops October 3, 2023 14:01
Copy link
Contributor

@olksdr olksdr left a comment

Choose a reason for hiding this comment

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

Please, fix the changelog. Otherwise lgtm

CHANGELOG.md Outdated
- Exclude more spans fron metrics extraction. ([#2522](https://github.com/getsentry/relay/pull/2522), [#2525](https://github.com/getsentry/relay/pull/2525), [#2545](https://github.com/getsentry/relay/pull/2545))
pull/2522), [#2525](https://github.com/getsentry/relay/pull/2525), [#2545](https://github.com/getsentry/relay/pull/2545))
Copy link
Contributor

Choose a reason for hiding this comment

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

Something strange here, looks like it got broken, maybe on master merge?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 fixed now

Copy link
Contributor

@iker-barriocanal iker-barriocanal left a comment

Choose a reason for hiding this comment

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

Is a new release of the sentry kafka schemas library required before deploying this?

Comment on lines 2400 to 2401
// Only allow 16-char hex strings in group.
s.len() == 16 && s.chars().all(|c| c.is_ascii_hexdigit())
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: why not longer/shorter strings?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think this is a mistake. We are converting from an hex string into a u64 but the length of the hex string can be 8 I believe.

Copy link
Member Author

Choose a reason for hiding this comment

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

The group hash is a 64-bit hash, i.e. 8 bytes, but it takes two hex characters to encode a byte. So the group hash must always be 16 characters long. I'm fine with relaxing the condition to <= 16 though.

let mut span_group = format!("{:?}", md5::compute(scrubbed_desc));
span_group.truncate(16);
span_tags.insert(SpanTagKey::Group, span_group);

Copy link
Contributor

Choose a reason for hiding this comment

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

String::len returns bytes, so 16 bytes * 2 chars / byte = 32 chars?

Copy link
Member Author

Choose a reason for hiding this comment

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

16 is the length of the hexidecimal representation, e.g. 0123456789abcdef. But it still only encodes 8 bytes of data: 01 23 45 67 89 ab cd ef.

relay-server/src/actors/store.rs Show resolved Hide resolved
Comment on lines +432 to +433
def get_span(self):
message = self.poll()
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 use the timeout here? Calling the spans_consumer with a timeout and it not being used may generate some confusion.

Copy link
Member Author

Choose a reason for hiding this comment

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

See

def poll(self, timeout=None):
if timeout is None:
timeout = self.timeout

Copy link
Contributor

@phacops phacops left a comment

Choose a reason for hiding this comment

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

Is there still a possibility for status and op to be in sentry_tags and at the span top-level and have a different value? Would be good to clean this up and have only 1 value, wherever it's easier to read from.

Comment on lines 2400 to 2401
// Only allow 16-char hex strings in group.
s.len() == 16 && s.chars().all(|c| c.is_ascii_hexdigit())
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think this is a mistake. We are converting from an hex string into a u64 but the length of the hex string can be 8 I believe.

@phacops
Copy link
Contributor

phacops commented Oct 3, 2023

Is a new release of the sentry kafka schemas library required before deploying this?

No, we haven't written one yet for ingest-spans. When this schema is stabilized (after this PR), I'll write one and start using it in the Sentry consumer.

@phacops
Copy link
Contributor

phacops commented Oct 3, 2023

Can you also validate span.status_code is a valid integer even if we're going to send it as a string?

Base automatically changed from ref/span-sentry-tags to master October 4, 2023 10:17
@jjbayer
Copy link
Member Author

jjbayer commented Oct 4, 2023

@phacops

Can you also validate span.status_code is a valid integer even if we're going to send it as a string?

Done.

Is there still a possibility for status and op to be in sentry_tags and at the span top-level and have a different value? Would be good to clean this up and have only 1 value, wherever it's easier to read from.

Removed status from sentry_tags now because it's an exact copy of the top-level status. Keeping op for now because it does a lowercase transform:

if let Some(unsanitized_span_op) = span.op.value() {
let span_op = unsanitized_span_op.to_owned().to_lowercase();
span_tags.insert(SpanTagKey::SpanOp, span_op.to_owned());

@jjbayer jjbayer merged commit 600efba into master Oct 4, 2023
@jjbayer jjbayer deleted the ref/spans-kafka-schema branch October 4, 2023 14:19
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.

4 participants