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
5 changes: 5 additions & 0 deletions src/Sentry/IScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
/// </summary>
public void SetTrace(SentryId traceId, SpanId parentSpanId);

/// <summary>
/// Sets the environment.
/// </summary>
Comment thread
sentry-warden[bot] marked this conversation as resolved.
public void SetEnvironment(string? environment);

Check warning on line 41 in src/Sentry/IScopeObserver.cs

View check run for this annotation

@sentry/warden / warden: code-review

Breaking change: Adding method to public interface IScopeObserver

Adding `SetEnvironment` to the public `IScopeObserver` interface is a breaking change. Any external implementations will fail to compile. Consider a default interface implementation (if dropping netstandard2.0/net462) or a separate interface.
Comment thread
bitsandfoxes marked this conversation as resolved.

/// <summary>
/// Adds an attachment.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/Sentry/Internal/ScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ public void SetTrace(SentryId traceId, SpanId parentSpanId)

public abstract void SetTraceImpl(SentryId traceId, SpanId parentSpanId);

public void SetEnvironment(string? environment)
{
_options.DiagnosticLogger?.Log(SentryLevel.Debug,
"{0} Scope Sync - Setting Environment e:\"{1}\"", null, _name, environment);
SetEnvironmentImpl(environment);
}

public abstract void SetEnvironmentImpl(string? environment);

public void AddAttachment(SentryAttachment attachment)
{
_options.DiagnosticLogger?.Log(SentryLevel.Debug,
Expand Down
12 changes: 12 additions & 0 deletions src/Sentry/Platforms/Android/AndroidScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ public void SetTrace(SentryId traceId, SpanId parentSpanId)
}
}

public void SetEnvironment(string? environment)
{
try
{
// TODO: Missing corresponding scope-level functionality on the Android SDK
}
finally
{
_innerObserver?.SetEnvironment(environment);
}
}

public void AddAttachment(SentryAttachment attachment)
{
try
Expand Down
12 changes: 12 additions & 0 deletions src/Sentry/Platforms/Cocoa/CocoaScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ public void SetTrace(SentryId traceId, SpanId parentSpanId)
}
}

public void SetEnvironment(string? environment)
{
try
{
SentryCocoaSdk.ConfigureScope(scope => scope.SetEnvironment(environment));
}
finally
{
_innerObserver?.SetEnvironment(environment);
}
}

public void AddAttachment(SentryAttachment attachment)
{
try
Expand Down
3 changes: 3 additions & 0 deletions src/Sentry/Platforms/Native/CFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ internal static string GetCacheDirectory(SentryOptions options)
[DllImport("sentry-native")]
internal static extern void sentry_set_trace(string traceId, string parentSpanId);

[DllImport("sentry-native")]
internal static extern void sentry_set_environment(string? environment);

Comment thread
bitsandfoxes marked this conversation as resolved.
internal static Dictionary<long, DebugImage> LoadDebugImages(IDiagnosticLogger? logger)
{
// It only makes sense to load them once because they're cached on the native side anyway. We could force
Expand Down
3 changes: 3 additions & 0 deletions src/Sentry/Platforms/Native/NativeScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public override void SetUserImpl(SentryUser user)
public override void SetTraceImpl(SentryId traceId, SpanId parentSpanId) =>
C.sentry_set_trace(traceId.ToString(), parentSpanId.ToString());

public override void SetEnvironmentImpl(string? environment) =>
C.sentry_set_environment(environment);
Comment thread
bitsandfoxes marked this conversation as resolved.

public override void AddAttachmentImpl(SentryAttachment attachment)
{
// TODO: Missing corresponding functionality on the Native SDK
Expand Down
27 changes: 26 additions & 1 deletion src/Sentry/Scope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,32 @@ public SentryUser User
public string? Distribution { get; set; }

/// <inheritdoc />
public string? Environment { get; set; }
public string? Environment
Comment thread
jamescrosswell marked this conversation as resolved.
{
get;
set
Comment thread
bitsandfoxes marked this conversation as resolved.
{
if (field == value)
{
return;
}

if (value is null)
{
Options.LogDebug("Environment cannot be null. Reverting to default value from the options.");
field = Options.Environment;
}
else
{
field = value;
}

if (Options is { EnableScopeSync: true, ScopeObserver: { } observer })
{
observer.SetEnvironment(field);
Comment thread
bitsandfoxes marked this conversation as resolved.
}
Comment thread
bitsandfoxes marked this conversation as resolved.
}
}
Comment thread
bitsandfoxes marked this conversation as resolved.

// TransactionName is kept for legacy purposes because
// SentryEvent still makes use of it.
Expand Down
3 changes: 3 additions & 0 deletions src/Sentry/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ internal static IHub InitHub(SentryOptions options)
#pragma warning restore 0162
#pragma warning restore CS0162 // Unreachable code detected

// This happens before the native SDKs get initialized
options.Environment = options.SettingLocator.GetEnvironment();
Comment thread
jamescrosswell marked this conversation as resolved.

// Initialize native platform SDKs here
if (options.InitNativeSdks)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@
void AddAttachment(Sentry.SentryAttachment attachment);
void AddBreadcrumb(Sentry.Breadcrumb breadcrumb);
void ClearAttachments();
void SetEnvironment(string? environment);

Check warning on line 224 in test/Sentry.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt

View check run for this annotation

@sentry/warden / warden: code-review

[8XF-6F9] Breaking change: Adding method to public interface IScopeObserver (additional location)

Adding `SetEnvironment` to the public `IScopeObserver` interface is a breaking change. Any external implementations will fail to compile. Consider a default interface implementation (if dropping netstandard2.0/net462) or a separate interface.
void SetExtra(string key, object? value);
void SetTag(string key, string value);
void SetTrace(Sentry.SentryId traceId, Sentry.SpanId parentSpanId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@
void AddAttachment(Sentry.SentryAttachment attachment);
void AddBreadcrumb(Sentry.Breadcrumb breadcrumb);
void ClearAttachments();
void SetEnvironment(string? environment);

Check warning on line 224 in test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt

View check run for this annotation

@sentry/warden / warden: code-review

[8XF-6F9] Breaking change: Adding method to public interface IScopeObserver (additional location)

Adding `SetEnvironment` to the public `IScopeObserver` interface is a breaking change. Any external implementations will fail to compile. Consider a default interface implementation (if dropping netstandard2.0/net462) or a separate interface.
void SetExtra(string key, object? value);
void SetTag(string key, string value);
void SetTrace(Sentry.SentryId traceId, Sentry.SpanId parentSpanId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ namespace Sentry
void AddAttachment(Sentry.SentryAttachment attachment);
void AddBreadcrumb(Sentry.Breadcrumb breadcrumb);
void ClearAttachments();
void SetEnvironment(string? environment);
void SetExtra(string key, object? value);
void SetTag(string key, string value);
void SetTrace(Sentry.SentryId traceId, Sentry.SpanId parentSpanId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
void AddAttachment(Sentry.SentryAttachment attachment);
void AddBreadcrumb(Sentry.Breadcrumb breadcrumb);
void ClearAttachments();
void SetEnvironment(string? environment);

Check warning on line 212 in test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt

View check run for this annotation

@sentry/warden / warden: code-review

[8XF-6F9] Breaking change: Adding method to public interface IScopeObserver (additional location)

Adding `SetEnvironment` to the public `IScopeObserver` interface is a breaking change. Any external implementations will fail to compile. Consider a default interface implementation (if dropping netstandard2.0/net462) or a separate interface.
void SetExtra(string key, object? value);
void SetTag(string key, string value);
void SetTrace(Sentry.SentryId traceId, Sentry.SpanId parentSpanId);
Expand Down
93 changes: 93 additions & 0 deletions test/Sentry.Tests/ScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,21 @@ public void Clone_CopiesFields()
Assert.Equal(_sut.Environment, clone.Environment);
}

[Fact]
public void Clone_EnvironmentOverridesOptions_OverridePreserved()
{
// Arrange
var options = new SentryOptions { Environment = "production" };
var scope = new Scope(options);
scope.Environment = "staging";

// Act
var clone = scope.Clone();

// Assert
clone.Environment.Should().Be("staging");
}

[Fact]
public void TransactionName_TransactionNotStarted_NameIsSet()
{
Expand Down Expand Up @@ -696,6 +711,84 @@ public void AddBreadcrumb_ObserverExist_ObserverAddsBreadcrumbIfEnabled(bool obs
observer.Received(expectedCount).AddBreadcrumb(Arg.Is(breadcrumb));
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void SetEnvironment_ObserverExist_ObserverSetsEnvironmentIfEnabled(bool observerEnable)
{
// Arrange
var observer = Substitute.For<IScopeObserver>();
var scope = new Scope(new SentryOptions
{
ScopeObserver = observer,
EnableScopeSync = observerEnable
});
const string expectedEnvironment = "staging";
var expectedCount = observerEnable ? 1 : 0;

// Act
scope.Environment = expectedEnvironment;

// Assert
observer.Received(expectedCount).SetEnvironment(Arg.Is(expectedEnvironment));
}

[Fact]
public void SetEnvironment_Null_EnvironmentSetToOptionEnvironment()
{
// Arrange
const string optionsEnvironment = "production";
var scope = new Scope(new SentryOptions { Environment = optionsEnvironment });
scope.Environment = "staging"; // Override before resetting

// Act
scope.Environment = null;

// Assert
scope.Environment.Should().Be(optionsEnvironment);
}

[Fact]
public void SetEnvironment_Null_ObserverReceivesOptionEnvironment()
{
// Arrange
const string optionsEnvironment = "production";
var observer = Substitute.For<IScopeObserver>();
var scope = new Scope(new SentryOptions
{
ScopeObserver = observer,
EnableScopeSync = true,
Environment = optionsEnvironment
});
scope.Environment = "staging"; // Override before resetting
observer.ClearReceivedCalls();

// Act
scope.Environment = null;

// Assert
observer.Received(1).SetEnvironment(Arg.Is(optionsEnvironment));
}

[Fact]
public void SetEnvironment_SameValue_ObserverNotifiedOnce()
{
// Arrange
var observer = Substitute.For<IScopeObserver>();
var scope = new Scope(new SentryOptions
{
ScopeObserver = observer,
EnableScopeSync = true
});

// Act
scope.Environment = "staging";
scope.Environment = "staging";

// Assert
observer.Received(1).SetEnvironment(Arg.Is("staging"));
}

[Fact]
public void Filtered_tags_are_not_set()
{
Expand Down
Loading