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

fix: Make building without client feature work again #416

Merged
merged 2 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"sentry",
"sentry-actix",
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ check-default-features:

check-no-default-features:
@echo 'NO DEFAULT FEATURES'
@cd sentry && RUSTFLAGS=-Dwarnings cargo check --no-default-features
@cd sentry-core && RUSTFLAGS=-Dwarnings cargo check --no-default-features
.PHONY: check-no-default-features

check-panic:
Expand Down
2 changes: 1 addition & 1 deletion sentry-actix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Sentry client extension for actix-web 3.
edition = "2018"

[dependencies]
sentry-core = { version = "0.24.1", path = "../sentry-core", default-features = false }
sentry-core = { version = "0.24.1", path = "../sentry-core", default-features = false, features = ["client"] }
actix-web = { version = "3", default-features = false }
futures-util = { version = "0.3.5", default-features = false }

Expand Down
134 changes: 99 additions & 35 deletions sentry-core/src/performance.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use std::sync::Arc;
use std::sync::Mutex;

use crate::{protocol, Client, Hub};
use crate::{protocol, Hub};

#[cfg(feature = "client")]
use crate::Client;

#[cfg(feature = "client")]
const MAX_SPANS: usize = 1_000;

// global API:
Expand All @@ -14,8 +18,15 @@ const MAX_SPANS: usize = 1_000;
/// The transaction itself also represents the root span in the span hierarchy.
/// Child spans can be started with the [`Transaction::start_child`] method.
pub fn start_transaction(ctx: TransactionContext) -> Transaction {
let client = Hub::with_active(|hub| hub.client());
Transaction::new(client, ctx)
#[cfg(feature = "client")]
{
let client = Hub::with_active(|hub| hub.client());
Transaction::new(client, ctx)
}
#[cfg(not(feature = "client"))]
{
Transaction::new_noop(ctx)
}
}

// Hub API:
Expand All @@ -25,7 +36,14 @@ impl Hub {
///
/// See the global [`start_transaction`] for more documentation.
pub fn start_transaction(&self, ctx: TransactionContext) -> Transaction {
Transaction::new(self.client(), ctx)
#[cfg(feature = "client")]
{
Transaction::new(self.client(), ctx)
}
#[cfg(not(feature = "client"))]
{
Transaction::new_noop(ctx)
}
}
}

Expand All @@ -37,6 +55,7 @@ impl Hub {
/// Transaction, and also the connection point for distributed tracing.
#[derive(Debug)]
pub struct TransactionContext {
#[cfg_attr(not(feature = "client"), allow(dead_code))]
name: String,
op: String,
trace_id: protocol::TraceId,
Expand Down Expand Up @@ -203,6 +222,7 @@ impl TransactionOrSpan {
}
}

#[cfg(feature = "client")]
pub(crate) fn apply_to_event(&self, event: &mut protocol::Event<'_>) {
if event.contexts.contains_key("trace") {
return;
Expand Down Expand Up @@ -238,6 +258,7 @@ impl TransactionOrSpan {

#[derive(Debug)]
struct TransactionInner {
#[cfg(feature = "client")]
client: Option<Arc<Client>>,
sampled: bool,
context: protocol::TraceContext,
Expand All @@ -257,6 +278,7 @@ pub struct Transaction {
}

impl Transaction {
#[cfg(feature = "client")]
fn new(mut client: Option<Arc<Client>>, ctx: TransactionContext) -> Self {
let context = protocol::TraceContext {
trace_id: ctx.trace_id,
Expand Down Expand Up @@ -294,6 +316,25 @@ impl Transaction {
}
}

#[cfg(not(feature = "client"))]
fn new_noop(ctx: TransactionContext) -> Self {
let context = protocol::TraceContext {
trace_id: ctx.trace_id,
parent_span_id: ctx.parent_span_id,
op: Some(ctx.op),
..Default::default()
};
let sampled = ctx.sampled.unwrap_or(false);

Self {
inner: Arc::new(Mutex::new(TransactionInner {
sampled,
context,
transaction: None,
})),
}
}

/// Set some extra information to be sent with this Transaction.
pub fn set_data(&self, key: &str, value: protocol::Value) {
let mut inner = self.inner.lock().unwrap();
Expand Down Expand Up @@ -332,26 +373,28 @@ impl Transaction {
/// This records the end timestamp and sends the transaction together with
/// all finished child spans to Sentry.
pub fn finish(self) {
let mut inner = self.inner.lock().unwrap();
if let Some(mut transaction) = inner.transaction.take() {
if let Some(client) = inner.client.take() {
transaction.finish();
transaction
.contexts
.insert("trace".into(), inner.context.clone().into());

// TODO: apply the scope to the transaction, whatever that means
let opts = client.options();
transaction.release = opts.release.clone();
transaction.environment = opts.environment.clone();
transaction.sdk = Some(std::borrow::Cow::Owned(client.sdk_info.clone()));

let mut envelope = protocol::Envelope::new();
envelope.add_item(transaction);

client.send_envelope(envelope)
with_client_impl! {{
let mut inner = self.inner.lock().unwrap();
if let Some(mut transaction) = inner.transaction.take() {
if let Some(client) = inner.client.take() {
transaction.finish();
transaction
.contexts
.insert("trace".into(), inner.context.clone().into());

// TODO: apply the scope to the transaction, whatever that means
let opts = client.options();
transaction.release = opts.release.clone();
transaction.environment = opts.environment.clone();
transaction.sdk = Some(std::borrow::Cow::Owned(client.sdk_info.clone()));

let mut envelope = protocol::Envelope::new();
envelope.add_item(transaction);

client.send_envelope(envelope)
}
}
}
}}
}

/// Starts a new child Span with the given `op` and `description`.
Expand Down Expand Up @@ -425,18 +468,20 @@ impl Span {
/// This will record the end timestamp and add the span to the transaction
/// in which it was started.
pub fn finish(self) {
let mut span = self.span.lock().unwrap();
if span.timestamp.is_some() {
// the span was already finished
return;
}
span.finish();
let mut inner = self.transaction.lock().unwrap();
if let Some(transaction) = inner.transaction.as_mut() {
if transaction.spans.len() <= MAX_SPANS {
transaction.spans.push(span.clone());
with_client_impl! {{
let mut span = self.span.lock().unwrap();
if span.timestamp.is_some() {
// the span was already finished
return;
}
}
span.finish();
let mut inner = self.transaction.lock().unwrap();
if let Some(transaction) = inner.transaction.as_mut() {
if transaction.spans.len() <= MAX_SPANS {
transaction.spans.push(span.clone());
}
}
}}
}

/// Starts a new child Span with the given `op` and `description`.
Expand Down Expand Up @@ -510,11 +555,12 @@ impl std::fmt::Display for SentryTrace {

#[cfg(test)]
mod tests {
use std::str::FromStr;

use super::*;

#[test]
fn parses_sentry_trace() {
use std::str::FromStr;
let trace_id = protocol::TraceId::from_str("09e04486820349518ac7b5d2adbf6ba5").unwrap();
let parent_trace_id = protocol::SpanId::from_str("9cf635fa5b870b3a").unwrap();

Expand All @@ -528,4 +574,22 @@ mod tests {
let parsed = parse_sentry_trace(&format!("{}", trace));
assert_eq!(parsed, Some(trace));
}

#[test]
fn disabled_forwards_trace_id() {
let headers = [(
"SenTrY-TRAce",
"09e04486820349518ac7b5d2adbf6ba5-9cf635fa5b870b3a-1",
)];
let ctx = TransactionContext::continue_from_headers("noop", "noop", headers);
let trx = start_transaction(ctx);

let span = trx.start_child("noop", "noop");

let header = span.iter_headers().next().unwrap().1;
let parsed = parse_sentry_trace(&header).unwrap();

assert_eq!(&parsed.0.to_string(), "09e04486820349518ac7b5d2adbf6ba5");
assert_eq!(parsed.2, Some(true));
}
}
2 changes: 2 additions & 0 deletions sentry-core/src/scope/noop.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fmt;

use crate::protocol::{Context, Event, Level, User, Value};
use crate::TransactionOrSpan;

/// A minimal API scope guard.
///
Expand Down Expand Up @@ -111,6 +112,7 @@ impl Scope {

/// Set the given [`TransactionOrSpan`] as the active span for this scope.
pub fn set_span(&mut self, span: Option<TransactionOrSpan>) {
let _ = span;
minimal_unreachable!();
}

Expand Down