-
-
Notifications
You must be signed in to change notification settings - Fork 164
Preliminary work to integrate Performance Monitoring #276
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
Conversation
be8043f
to
ad62e49
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate you taking first steps here! Tracing is on our radar, we just wanted to gather more experience with our other SDKs before integrating it into Rust together will all the learnings from the other SDKs. That being said, I haven’t really looked at the implementation from other SDKs, or how it would best fit into Rust.
Nevertheless, looking at your draft and the Guidelines, I think that the Transaction
type should rather live in sentry-core
, as it should be able to "submit itself" to the client/transport. So it needs to have at least an Arc<Client>
on itself.
Instead of "extending" the existing Event
type, it should rather use composition, as in:
struct Transaction {
event: Event,
span: Span,
client: Arc<Client>,
}
It can then flatten all the event/span properties when serializing.
It can also have a DerefMut
impl for both Event
and Span
.
I would also give it its own EnvelopeItem
type.
Roping in @HazAT and @rhcarvalho as they should have more experience with the tracing API.
Glad to help! I understand that this may not have been on your team's roadmap in the immediate future. Nevertheless we'll try to contribute as much as possible. Since This seems more like the sort of thing that could use a trait and // In `sentry-types`
#[derive(Clone, Debug, Serialize)]
pub struct Transaction<'a> {
event: Event<'a>,
span: Span,
} // In `sentry-core`
// Trait in case other types of envelopes can 'submit themselves'
pub trait Sendable { // [or another name]
pub fn send();
}
impl<'a> Sendable for Transaction<'a> {
fn send(&self) {
Hub::current().send_transaction(&self)
}
} Evidently, apps would have to import the I'm a bit flakey on the terminology (finishing, dispatching, sending, etc.) so feel free to correct me. |
* Added EnvelopeItem entry for Transaction * Revert changes to Event type and add Transaction type as a combination of Span and Event
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks much better now.
Ah yes, I moved all the Envelope
-related things into sentry-types
. We had a similar case with Session
, and decided to split the POD-bits into the types crate, and a small wrapper into core. See #251
I think something similar can be done here as well.
This PR on its own looks very promising already, and I would be happy to land this incrementally, meaning landing the bits from types even if they are not yet fully usable.
Sounds good! How about I finish this PR by:
|
Yes that sounds very good |
FWIW we've updated the developer docs to include the https://develop.sentry.dev/sdk/unified-api/tracing#sdk-configuration (might be easier to read the diff -- getsentry/develop#165) |
@rhcarvalho Thanks for the update! I went through it and it's much clearer than before. Just to double-check that this is essentially what the JSON structure of the envelope looks like for a Transcation event: // Envelope Headers
{"event_id": "...", "sent_at": "..."}
// Item Headers
{"type": "transaction", ...}
// Item payload
{
// Transaction struct
"type": "transaction",
"event_id": "...",
"sdk": "...",
"platform": "...",
"transaction": "...",
"tags": { ... },
"timestamp": "...",
"start_timestamp": "...",
"spans": [
{ // Span struct
"trace_id": "...",
"span_id": "...",
"parent_span_id": "...",
"op": "...",
"description": "...",
"timestamp": "...",
"start_timestamp": "...",
"same_process_as_parent": false,
"status": "...", // Optional
"tags": { ... }, // Optional
"data": { ... }, // Optional
},
// ...
],
"contexts": {
"trace": { // TraceContext struct
"trace_id": "...",
"span_id": "...",
"parent_span_id": "...",
"op": "...",
"description": "...",
"status": "..." // Optional
}
}
} This makes the Makes me think Transaction, Event, Span, and TraceContext should just be their own struct instead of merging types together. Another approach, with inheriting Event (although initialising this type could be a bit awkward): pub struct Transaction<'a> {
#[serde(flatten)]
event: Event<'a>,
type: Option<String>, // Always `"transaction"` -- possibly an enum and move into `Event`
spans: Vec<Span>,
start_timestamp: DateTime<Utc>,
} In that case, there's a complication because |
I’m actually not sure if that is supposed to live on the transaction type itself, or if its meant to be just the envelope header. |
I'll exclude it, but it does appear to be sent in other SDKs. It is used to identity the type of event in SDKs that don't have strict typing, e.g. in Python 'Event' is just a Dict, so this field is used to send the envelope differently. It wouldn't be necessary in Rust since Transaction has a different struct. It's possible that it gets ignored on the server-side however. |
* Reverted change in Scope. * Added fields for Transaction, Span, and TraceContext with documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after talking to @rhcarvalho, it looks like we need a type
on the transaction object after all (at least when its serialized to json) I will research this myself to know how this should look like
* Removed unnecessary Span into_owned() method. * Renamed Transaction 'transaction' to 'name'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay here. Please rebase this on master again, the clippy error should be gone then.
This looks good from my perspective, I will ask @rhcarvalho for another review however, as he should know all the data structures related to tracing a bit better than me.
Thanks a lot for doing this! I’m wondering if we should maybe gate all of this behind an |
* master: (59 commits) fix: Correctly apply environment from env (#293) fix: Make Rust 1.48 clippy happy (#294) docs: Document integrations and the Hub better (#291) ref: Remove deprecated error-chain and failure crates (#290) release: 0.21.0 meta: Update Changelog feat: End sessions with explicit status (#289) fix: Scope transaction name can be overriden in sentry-actix (#287) fix: sentry-actix should not capture client errors (#286) fix: Clean up sentry-actix toml (#285) ref: Remove empty integrations (#283) feat: Add support for actix-web 3 (#282) feat: Preliminary work to integrate Performance Monitoring (#276) ref: Introduce a SessionFlusher (#279) fix: Set a default environment based on debug_assertions (#280) ref: Rearchitect the log and slog Integrations (#268) ref: Deprecate public fields on Integrations (#267) ci: Make testfast actually fast (#273) fix: Update surf and unbreak CI (#274) ci: Use smarter cache action (#272) ...
Hello! I'm the lead developer at Wavy Labs Inc. We're integrating Rust more and more into our stack and we've been using Sentry for over a year. We'd love to start integrating Performance Monitoring, but it seems this SDK doesn't support it yet.
I'd like to kickstart the discussion on this and contribute some developer time for this. I've been reading the Guidelines for Tracing Support and peeking into the Python SDK for reference. I've started some preliminary work on adding the new types (Span and Transaction), but I'll need some guidance on integrating with Hub. Feel free to start reviewing at any time!