Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat(metrics): Extract transaction metrics in external relays [INGEST-1477] #1344

Merged
merged 19 commits into from
Jul 25, 2022

Conversation

iker-barriocanal
Copy link
Contributor

@iker-barriocanal iker-barriocanal commented Jul 19, 2022

Currently, transaction metrics are only extracted in processing relays (the function call to extract metrics is surrounded by an if_processing!). Even if we extract metrics in external relays, we don't want to extract metrics multiple times from a transaction, causing metric (and billing) duplication.

The implemented approach in this PR is to extract metrics in the very first relay in the chain, mark the transaction as extracted, and not extract metrics from that transaction in subsequent relays. The simplest way to accomplish that is using the existing metrics_extracted header in items that had metrics extracted. The approach and the header are reused from the metric extraction from sessions, there's nothing new here.

Implementation-wise, removing that if_processing triggers a lot of changes to make current processing-only features non-processing too. On the other hand, we store a new flag transaction_metrics_extracted on ProcessEnvelopeState to make it available to the whole state processing function and transfer it to the outgoing event. Ideally, process_state is refactored not to throw every piece of data we need to the envelope state object, but that's out of the scope of this PR.

Move all non-processing imports out of the processing cfg config in the
envelopes actor.
The `metrics_extracted` header must only be used on items that had
transactions extracted. This means that relay must not extract metrics
from items with such header, to not duplicate metrics.
Use the function to get the config, instead of accessing the struct's
property directly.
The transaction item was reused to keep the item's headers. However, no
additional payload was being set and this was causing missing data such
as missing breakdowns.
@iker-barriocanal iker-barriocanal requested a review from a team July 19, 2022 23:32
@iker-barriocanal iker-barriocanal self-assigned this Jul 19, 2022
.metric_conditional_tagging
.as_slice();

let (event, _) = self.event_from_json_payload(item, Some(EventType::Transaction))?;
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 should be necessary. Don't you have access to state.event here?

@@ -346,6 +346,8 @@ struct ProcessEnvelopeState {
/// extracted.
event: Annotated<Event>,

transaction_item: Option<Item>,
Copy link
Member

Choose a reason for hiding this comment

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

you can probably store item headers only here, not sure if it's feasible though

.metric_conditional_tagging
.as_slice();

let (event, _) = self.event_from_json_payload(item, Some(EventType::Transaction))?;
Copy link
Member

Choose a reason for hiding this comment

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

Why parse the event again here?

let event_type = state.event_type().unwrap_or_default();
let mut event_item = Item::new(ItemType::from_event_type(event_type));
let mut event_item = match state.event_type().unwrap_or_default() {
EventType::Transaction => state.transaction_item.take().unwrap(),
Copy link
Member

Choose a reason for hiding this comment

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

There's usually a better way than unwrap(). E.g. store event_item on the state instead of event_type and transaction_item, and then get the type from the item.

#[cfg(feature = "processing")]
impl TransactionMetricsConfig {
pub fn is_enabled(&self) -> bool {
self.version > 0 && self.version <= EXTRACT_MAX_VERSION
Copy link
Member

Choose a reason for hiding this comment

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

Quick thought: We could actually remove the self.version > 0 check and set EXTRACT_MAX_VERSION = 0. That way, we would not need any changes on the sentry side. Or am I missing something crucial?

Copy link
Member

Choose a reason for hiding this comment

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

Actually, let's keep it as-is to be consistent with session metrics extraction.

let mut event_item = match state.event_type().unwrap_or_default() {
EventType::Transaction => state.transaction_item.take().unwrap(),
ty => Item::new(ItemType::from_event_type(ty)),
};
Copy link
Member

Choose a reason for hiding this comment

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

I assume we reuse the item here because we do not want to lose the metrics_extracted information. But this could have side effects (I don't know what else is in that item header). So it might be safer to explicitly transfer the metrics_extracted information to the new item, as we do with sample_rates a few lines below.

Two minor tweaks to #1344, based on comments on that PR:

- Do not parse the event payload twice.
- Store a boolean on the envelope state, rather than the full event
  item.
jjbayer added a commit to getsentry/sentry that referenced this pull request Jul 25, 2022
Just like we did for session metrics extraction, add a version to the
project config protocol such that older Relays will stop extracting
metrics when the version supplied by Sentry is too high.

This is a prerequisite for getsentry/relay#1344.
@jjbayer jjbayer requested a review from a team July 25, 2022 09:08
@jjbayer jjbayer self-assigned this Jul 25, 2022
@jjbayer jjbayer requested a review from untitaker July 25, 2022 09:09
@jjbayer jjbayer merged commit 5f9dc2b into master Jul 25, 2022
@jjbayer jjbayer deleted the iker/feat/mep-support-ext-relays branch July 25, 2022 11:45
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants