Skip to content
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
9 changes: 9 additions & 0 deletions Sources/Sentry/PrivateSentrySDKOnly.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "SentryInternalDefines.h"
#import "SentryMeta.h"
#import "SentryOptions+Private.h"
#import "SentryPropagationContext.h"
#import "SentrySDK+Private.h"
#import "SentrySerialization.h"
#import "SentrySessionReplayIntegration+Private.h"
Expand Down Expand Up @@ -199,6 +200,14 @@
return [SentryDependencyContainer.sharedInstance.extraContextProvider getExtraContext];
}

+ (void)setTrace:(SentryId *)traceId spanId:(SentrySpanId *)spanId
{
[SentrySDK.currentHub configureScope:^(SentryScope *scope) {
scope.propagationContext = [[SentryPropagationContext alloc] initWithTraceId:traceId
spanId:spanId];

Check warning on line 207 in Sources/Sentry/PrivateSentrySDKOnly.mm

View check run for this annotation

Codecov / codecov/patch

Sources/Sentry/PrivateSentrySDKOnly.mm#L206-L207

Added lines #L206 - L207 were not covered by tests
}];
}

Check warning on line 209 in Sources/Sentry/PrivateSentrySDKOnly.mm

View check run for this annotation

Codecov / codecov/patch

Sources/Sentry/PrivateSentrySDKOnly.mm#L209

Added line #L209 was not covered by tests

#if SENTRY_TARGET_PROFILING_SUPPORTED
+ (uint64_t)startProfilerForTrace:(SentryId *)traceId;
{
Expand Down
2 changes: 2 additions & 0 deletions Sources/Sentry/SentryPropagationContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, readonly) SentrySpanId *spanId;
@property (nonatomic, readonly) SentryTraceHeader *traceHeader;

- (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId;

- (NSDictionary<NSString *, NSString *> *)traceContextForEvent;

@end
Expand Down
9 changes: 9 additions & 0 deletions Sources/Sentry/SentryPropagationContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ - (instancetype)init
return self;
}

- (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId
{
if (self = [super init]) {
_traceId = traceId;
_spanId = spanId;
}
return self;
}

- (SentryTraceHeader *)traceHeader
{
return [[SentryTraceHeader alloc] initWithTraceId:self.traceId
Expand Down
14 changes: 14 additions & 0 deletions Sources/Sentry/SentryScope.m
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ - (void)setSpan:(nullable id<SentrySpan>)span
}
}

- (void)setPropagationContext:(SentryPropagationContext *)propagationContext
{
@synchronized(_propagationContext) {
_propagationContext = propagationContext;

if (self.observers.count > 0) {
NSDictionary *traceContext = [self.propagationContext traceContextForEvent];
for (id<SentryScopeObserver> observer in self.observers) {
[observer setTraceContext:traceContext];
}
}
}
}

- (nullable id<SentrySpan>)span
{
@synchronized(_spanLock) {
Expand Down
6 changes: 6 additions & 0 deletions Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
@class SentryUser;
@class SentryEnvelope;
@class SentryId;
@class SentrySpanId;
@class SentrySessionReplayIntegration;
@class UIView;

Expand Down Expand Up @@ -103,6 +104,11 @@ typedef void (^SentryOnAppStartMeasurementAvailable)(
*/
+ (NSDictionary *)getExtraContext;

/**
* Allows Hybrids SDKs to thread-safe set the current trace.
*/
+ (void)setTrace:(SentryId *)traceId spanId:(SentrySpanId *)spanId;

#if SENTRY_TARGET_PROFILING_SUPPORTED
/**
* Start a profiler session associated with the given @c SentryId.
Expand Down
5 changes: 4 additions & 1 deletion Sources/Sentry/include/SentryScope+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (atomic, strong) SentryUser *_Nullable userObject;

@property (atomic, strong) SentryPropagationContext *propagationContext;
/**
* The propagation context has a setter, requiring it to be nonatomic
*/
@property (nonatomic, strong) SentryPropagationContext *propagationContext;

@property (nonatomic, nullable, copy) NSString *currentScreen;

Expand Down
17 changes: 17 additions & 0 deletions Tests/SentryTests/PrivateSentrySDKOnlyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,21 @@ class PrivateSentrySDKOnlyTests: XCTestCase {
event.exceptions?.first?.mechanism?.handled = false
return SentryEnvelope(event: event)
}

func testSetTrace() {
// -- Arrange --
let traceId = SentryId()
let spanId = SentrySpanId()

let scope = Scope()
let hub = TestHub(client: nil, andScope: scope)
SentrySDK.setCurrentHub(hub)

// -- Act --
PrivateSentrySDKOnly.setTrace(traceId, spanId: spanId)

// -- Assert --
XCTAssertEqual(scope.propagationContext?.traceId, traceId)
XCTAssertEqual(scope.propagationContext?.spanId, spanId)
}
}
50 changes: 50 additions & 0 deletions Tests/SentryTests/SentryPropagationContextTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@testable import Sentry
import XCTest

class SentryPropagationContextTests: XCTestCase {

func testInitWithTraceIdSpanId() {
// -- Arrange --
let traceId = SentryId()
let spanId = SpanId()

// -- Act --
let context = SentryPropagationContext(traceId: traceId, spanId: spanId)

// -- Assert --
XCTAssertEqual(traceId, context.traceId)
XCTAssertEqual(spanId, context.spanId)
}

func testTraceContextForEvent() {
// -- Arrange --
let traceId = SentryId()
let spanId = SpanId()

let context = SentryPropagationContext(traceId: traceId, spanId: spanId)

// -- Act --
let traceContext = context.traceContextForEvent()

// -- Assert --
XCTAssertEqual(traceContext.count, 2)
XCTAssertEqual(traceContext["trace_id"], traceId.sentryIdString)
XCTAssertEqual(traceContext["span_id"], spanId.sentrySpanIdString)
}

func testTraceHeader() {
// -- Arrange
let traceId = SentryId()
let spanId = SpanId()

let context = SentryPropagationContext(traceId: traceId, spanId: spanId)

// -- Act --
let traceHeader = context.traceHeader

// -- Assert --
XCTAssertNotNil(traceHeader)
XCTAssertEqual(traceHeader.traceId, traceId)
XCTAssertEqual(traceHeader.spanId, spanId)
}
}
20 changes: 20 additions & 0 deletions Tests/SentryTests/SentryScopeSwiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,26 @@ class SentryScopeSwiftTests: XCTestCase {
XCTAssertEqual(observer2.context as? NSDictionary, expected)
}

func testScopeObserver_setPropagationContext_UpdatesTraceContext() throws {
// -- Arrange --
let sut = Scope()
let observer = fixture.observer
sut.add(observer)

let traceId = SentryId(uuidString: "12345678123456781234567812345678")
let spanId = SpanId(value: "1234567812345678")
let propagationContext = SentryPropagationContext(trace: traceId, spanId: spanId)

// -- Act --
sut.propagationContext = propagationContext

// -- Assert --
let traceContext = try XCTUnwrap(observer.traceContext)
XCTAssertEqual(2, traceContext.count)
XCTAssertEqual(traceId.sentryIdString, traceContext["trace_id"] as? String)
XCTAssertEqual(spanId.sentrySpanIdString, traceContext["span_id"] as? String)
}

private class TestScopeObserver: NSObject, SentryScopeObserver {
var tags: [String: String]?
func setTags(_ tags: [String: String]?) {
Expand Down
Loading