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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### Features

- Add `dataCollection` option under `experimental` for configuring data scrubbing behavior (#8369)
- Attach feature flag evaluations to active spans (#8158)
- Add feature flag scope ObjC API (#8160)

Expand Down
7 changes: 7 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,13 @@
Public/SentryObjCAttributeContent.h,
Public/SentryObjCBreadcrumb.h,
Public/SentryObjCClient.h,
Public/SentryObjCDataCollectionDatabaseCollectionOptions.h,
Public/SentryObjCDataCollectionGraphQLCollectionOptions.h,
Public/SentryObjCDataCollectionHttpBodyType.h,
Public/SentryObjCDataCollectionHttpHeaderCollectionOptions.h,
Public/SentryObjCDataCollectionKeyValueCollectionBehavior.h,
Public/SentryObjCDataCollectionKeyValueCollectionMode.h,
Public/SentryObjCDataCollectionOptions.h,
Public/SentryObjCDebugMeta.h,
Public/SentryObjCDefines.h,
Public/SentryObjCEnvelope.h,
Expand Down
19 changes: 19 additions & 0 deletions Sources/SentryObjC/Public/SentryObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,25 @@
# import <SentryObjC/SentryObjCLogger.h>
#endif

// --- Data collection types ---
#if !__has_include(<SentryObjC/SentryObjCDefines.h>)
# import "SentryObjCDataCollectionDatabaseCollectionOptions.h"
# import "SentryObjCDataCollectionGraphQLCollectionOptions.h"
# import "SentryObjCDataCollectionHttpBodyType.h"
# import "SentryObjCDataCollectionHttpHeaderCollectionOptions.h"
# import "SentryObjCDataCollectionKeyValueCollectionBehavior.h"
# import "SentryObjCDataCollectionKeyValueCollectionMode.h"
# import "SentryObjCDataCollectionOptions.h"
#else
# import <SentryObjC/SentryObjCDataCollectionDatabaseCollectionOptions.h>
# import <SentryObjC/SentryObjCDataCollectionGraphQLCollectionOptions.h>
# import <SentryObjC/SentryObjCDataCollectionHttpBodyType.h>
# import <SentryObjC/SentryObjCDataCollectionHttpHeaderCollectionOptions.h>
# import <SentryObjC/SentryObjCDataCollectionKeyValueCollectionBehavior.h>
# import <SentryObjC/SentryObjCDataCollectionKeyValueCollectionMode.h>
# import <SentryObjC/SentryObjCDataCollectionOptions.h>
#endif

// --- Configuration ---
#if !__has_include(<SentryObjC/SentryObjCDefines.h>)
# import "SentryObjCExperimentalOptions.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// Controls database query parameter collection.
@interface SentryObjCDataCollectionDatabaseCollectionOptions : NSObject

/// Whether to collect parameterized database query values. Defaults to @c YES.
@property (nonatomic) BOOL queryParams;

- (instancetype)init;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// Controls GraphQL document and variable collection.
@interface SentryObjCDataCollectionGraphQLCollectionOptions : NSObject

/// Whether to collect GraphQL query/mutation documents. Defaults to @c YES.
@property (nonatomic) BOOL document;

/// Whether to collect GraphQL variables. Defaults to @c YES.
@property (nonatomic) BOOL variables;

- (instancetype)init;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>

/// Identifies the direction and role of an HTTP body for collection purposes.
typedef NS_OPTIONS(NSUInteger, SentryObjCDataCollectionHttpBodyType) {
/// Body of an incoming HTTP request (server-side).
SentryObjCDataCollectionHttpBodyTypeIncomingRequest = 1 << 0,
/// Body of an outgoing HTTP request (client-side).
SentryObjCDataCollectionHttpBodyTypeOutgoingRequest = 1 << 1,
/// Body of an incoming HTTP response (client-side).
SentryObjCDataCollectionHttpBodyTypeIncomingResponse = 1 << 2,
/// Body of an outgoing HTTP response (server-side).
SentryObjCDataCollectionHttpBodyTypeOutgoingResponse = 1 << 3,
/// All body types.
SentryObjCDataCollectionHttpBodyTypeAll = SentryObjCDataCollectionHttpBodyTypeIncomingRequest
| SentryObjCDataCollectionHttpBodyTypeOutgoingRequest
| SentryObjCDataCollectionHttpBodyTypeIncomingResponse
| SentryObjCDataCollectionHttpBodyTypeOutgoingResponse
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#import <Foundation/Foundation.h>

@class SentryObjCDataCollectionKeyValueCollectionBehavior;

NS_ASSUME_NONNULL_BEGIN

/// Controls HTTP header collection independently for request and response directions.
@interface SentryObjCDataCollectionHttpHeaderCollectionOptions : NSObject

/// Controls collection of request header values. Defaults to denyList.
@property (nonatomic, strong) SentryObjCDataCollectionKeyValueCollectionBehavior *request;

/// Controls collection of response header values. Defaults to denyList.
@property (nonatomic, strong) SentryObjCDataCollectionKeyValueCollectionBehavior *response;

- (instancetype)init;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#import <Foundation/Foundation.h>
#if !__has_include(<SentryObjC/SentryObjCDefines.h>)
# import "SentryObjCDataCollectionKeyValueCollectionMode.h"
# import "SentryObjCDefines.h"
#else
# import <SentryObjC/SentryObjCDataCollectionKeyValueCollectionMode.h>
# import <SentryObjC/SentryObjCDefines.h>
#endif

NS_ASSUME_NONNULL_BEGIN

/// Controls how key-value data (headers, cookies, query params) is collected and filtered.
///
/// Key names are always included regardless of mode. This type controls which
/// values are sent in plaintext vs. replaced with @c [Filtered].
///
/// DenyList and AllowList are mutually exclusive.
@interface SentryObjCDataCollectionKeyValueCollectionBehavior : NSObject
SENTRY_NO_INIT

/// The active collection mode.
@property (nonatomic, readonly) SentryObjCDataCollectionKeyValueCollectionMode mode;

/// Extra terms for the active mode. Empty for @c off.
@property (nonatomic, readonly, copy) NSArray<NSString *> *terms;

/// Do not collect this category at all — no keys or values are attached.
+ (instancetype)off;

/// Collect all values, scrubbing those matching the built-in sensitive denylist.
/// @param terms Extra terms to add to the built-in denylist.
+ (instancetype)denyListWithTerms:(NSArray<NSString *> *)terms;

/// Collect all values, scrubbing those matching the built-in sensitive denylist only.
+ (instancetype)denyList;

/// Only send values for explicitly listed keys; scrub all others.
/// @param terms The keys whose values should be sent in plaintext.
+ (instancetype)allowListWithTerms:(NSArray<NSString *> *)terms;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import <Foundation/Foundation.h>

/// Modes for key-value data collection filtering.
typedef NS_ENUM(NSInteger, SentryObjCDataCollectionKeyValueCollectionMode) {
/// Do not collect this category at all.
SentryObjCDataCollectionKeyValueCollectionModeOff = 0,
/// Collect all values, scrubbing those matching the built-in sensitive denylist.
SentryObjCDataCollectionKeyValueCollectionModeDenyList,
/// Only send values for explicitly listed keys; scrub all others.
SentryObjCDataCollectionKeyValueCollectionModeAllowList
};
54 changes: 54 additions & 0 deletions Sources/SentryObjC/Public/SentryObjCDataCollectionOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#import <Foundation/Foundation.h>
#if !__has_include(<SentryObjC/SentryObjCDefines.h>)
# import "SentryObjCDataCollectionHttpBodyType.h"
#else
# import <SentryObjC/SentryObjCDataCollectionHttpBodyType.h>
#endif

@class SentryObjCDataCollectionKeyValueCollectionBehavior;
@class SentryObjCDataCollectionHttpHeaderCollectionOptions;
@class SentryObjCDataCollectionGraphQLCollectionOptions;
@class SentryObjCDataCollectionDatabaseCollectionOptions;

NS_ASSUME_NONNULL_BEGIN

/// Configuration for what data the SDK collects automatically.
///
/// All properties have spec-defined defaults. Users supply only the options they want to override;
/// omitted fields use the documented defaults.
///
/// Data explicitly set by the user on the scope is not gated by these options.
@interface SentryObjCDataCollectionOptions : NSObject

/// Automatically populate @c user.* fields from auto-instrumentation. Defaults to @c YES.
@property (nonatomic) BOOL userInfo;

/// Controls cookie collection. Defaults to denyList.
@property (nonatomic, strong) SentryObjCDataCollectionKeyValueCollectionBehavior *cookies;

/// Controls HTTP header collection for request and response directions.
@property (nonatomic, strong) SentryObjCDataCollectionHttpHeaderCollectionOptions *httpHeaders;

/// Body types to collect. Defaults to @c SentryObjCDataCollectionHttpBodyTypeAll.
@property (nonatomic) SentryObjCDataCollectionHttpBodyType httpBodies;

/// Controls URL query parameter filtering. Defaults to denyList.
@property (nonatomic, strong) SentryObjCDataCollectionKeyValueCollectionBehavior *queryParams;

/// Controls GraphQL document and variable collection.
@property (nonatomic, strong) SentryObjCDataCollectionGraphQLCollectionOptions *graphql;

/// Controls database query parameter collection.
@property (nonatomic, strong) SentryObjCDataCollectionDatabaseCollectionOptions *database;

/// Include local variable values captured within stack frames. Defaults to @c YES.
@property (nonatomic) BOOL stackFrameVariables;

/// Number of source code lines to include above and below each stack frame. Defaults to @c 5.
@property (nonatomic) NSUInteger frameContextLines;

- (instancetype)init;

@end

NS_ASSUME_NONNULL_END
5 changes: 5 additions & 0 deletions Sources/SentryObjC/Public/SentryObjCExperimentalOptions.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#import <Foundation/Foundation.h>

@class SentryObjCDataCollectionOptions;

NS_ASSUME_NONNULL_BEGIN

/// Options for experimental features that are subject to change or may be removed in future
Expand Down Expand Up @@ -32,6 +34,9 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic) BOOL enableReplayNetworkDetailsCapturing;

/// Configuration for what data the SDK collects automatically.
@property (nonatomic, strong) SentryObjCDataCollectionOptions *dataCollection;

/// Initializes experimental options with default values.
- (instancetype)init;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// swiftlint:disable missing_docs
#if SWIFT_PACKAGE
internal import SentrySwift
#else
internal import Sentry
#endif
import Foundation

@objc(SentryObjCDataCollectionDatabaseCollectionOptions)
public final class SentryObjCDataCollectionDatabaseCollectionOptions: NSObject {
private let storage: Accessor<SentryDataCollection.DatabaseCollectionOptions>

internal var wrapped: SentryDataCollection.DatabaseCollectionOptions {
get { storage.value }
set { storage.value = newValue }
}

internal init(_ storage: Accessor<SentryDataCollection.DatabaseCollectionOptions>) {
self.storage = storage
}

internal init(_ wrapped: SentryDataCollection.DatabaseCollectionOptions) {
self.storage = Accessor(wrapped)
}

@objc public override init() {
self.storage = Accessor(SentryDataCollection.DatabaseCollectionOptions())
}

@objc public var queryParams: Bool {
get { storage.value.queryParams }
set { storage.value.queryParams = newValue }
}
}

// swiftlint:enable missing_docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// swiftlint:disable missing_docs
#if SWIFT_PACKAGE
internal import SentrySwift
#else
internal import Sentry
#endif
import Foundation

@objc(SentryObjCDataCollectionGraphQLCollectionOptions)
public final class SentryObjCDataCollectionGraphQLCollectionOptions: NSObject {
private let storage: Accessor<SentryDataCollection.GraphQLCollectionOptions>

internal var wrapped: SentryDataCollection.GraphQLCollectionOptions {
get { storage.value }
set { storage.value = newValue }
}

internal init(_ storage: Accessor<SentryDataCollection.GraphQLCollectionOptions>) {
self.storage = storage
}

internal init(_ wrapped: SentryDataCollection.GraphQLCollectionOptions) {
self.storage = Accessor(wrapped)
}

@objc public override init() {
self.storage = Accessor(SentryDataCollection.GraphQLCollectionOptions())
}

@objc public var document: Bool {
get { storage.value.document }
set { storage.value.document = newValue }
}

@objc public var variables: Bool {
get { storage.value.variables }
set { storage.value.variables = newValue }
}
}

// swiftlint:enable missing_docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// swiftlint:disable missing_docs
#if SWIFT_PACKAGE
internal import SentrySwift
#else
internal import Sentry
#endif

public typealias SentryObjCDataCollectionHttpBodyType = UInt

extension SentryObjCDataCollectionHttpBodyType {
init(_ underlying: SentryDataCollection.HttpBodyType) {
self = UInt(underlying.rawValue)
}

var underlying: SentryDataCollection.HttpBodyType {
SentryDataCollection.HttpBodyType(rawValue: Int(self))
}
}

// swiftlint:enable missing_docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// swiftlint:disable missing_docs
#if SWIFT_PACKAGE
internal import SentrySwift
#else
internal import Sentry
#endif
import Foundation

@objc(SentryObjCDataCollectionHttpHeaderCollectionOptions)
public final class SentryObjCDataCollectionHttpHeaderCollectionOptions: NSObject {
private let storage: Accessor<SentryDataCollection.HttpHeaderCollectionOptions>

internal var wrapped: SentryDataCollection.HttpHeaderCollectionOptions {
get { storage.value }
set { storage.value = newValue }
}

internal init(_ storage: Accessor<SentryDataCollection.HttpHeaderCollectionOptions>) {
self.storage = storage
}

internal init(_ wrapped: SentryDataCollection.HttpHeaderCollectionOptions) {
self.storage = Accessor(wrapped)
}

@objc public override init() {
self.storage = Accessor(SentryDataCollection.HttpHeaderCollectionOptions())
}

@objc public var request: SentryObjCDataCollectionKeyValueCollectionBehavior {
get { SentryObjCDataCollectionKeyValueCollectionBehavior(storage.value.request) }
set { storage.value.request = newValue.wrapped }
}

@objc public var response: SentryObjCDataCollectionKeyValueCollectionBehavior {
get { SentryObjCDataCollectionKeyValueCollectionBehavior(storage.value.response) }
set { storage.value.response = newValue.wrapped }
}
}

// swiftlint:enable missing_docs
Loading
Loading