Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
3 changes: 2 additions & 1 deletion src/Sentry.Extensions.Logging/SentryStructuredLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
SpanId = spanId,
};

log.SetDefaultAttributes(_options, _sdk);
var scope = _hub.GetScope();
log.SetDefaultAttributes(_options, scope, _sdk);
log.SetOrigin("auto.log.extensions_logging");

if (_categoryName is not null)
Expand Down
3 changes: 2 additions & 1 deletion src/Sentry.Serilog/SentrySink.Structured.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ private static void CaptureStructuredLog(IHub hub, SentryOptions options, LogEve
SpanId = spanId,
};

log.SetDefaultAttributes(options, Sdk);
var scope = hub.GetScope();
log.SetDefaultAttributes(options, scope, Sdk);
log.SetOrigin("auto.log.serilog");

foreach (var attribute in attributes)
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/Internal/DefaultSentryStructuredLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private protected override void CaptureLog(SentryLogLevel level, string template
}

var scope = _hub.GetScope();
log.SetDefaultAttributes(_options, scope?.Sdk ?? SdkVersion.Instance);
log.SetDefaultAttributes(_options, scope);
Comment thread
jamescrosswell marked this conversation as resolved.

CaptureLog(log);
}
Expand Down
35 changes: 32 additions & 3 deletions src/Sentry/SentryLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ internal void SetAttribute(string key, int value)
_attributes[key] = new SentryAttribute(value, "integer");
}

internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk)
internal void SetDefaultAttributes(SentryOptions options, Scope? scope, SdkVersion? sdk = null)
{
// Core Attributes
var environment = options.SettingLocator.GetEnvironment();
SetAttribute("sentry.environment", environment);

Expand All @@ -183,14 +184,42 @@ internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk)
SetAttribute("sentry.release", release);
}

if (sdk.Name is { } name)
sdk ??= scope?.Sdk;
if (sdk?.Name is { } name)
{
SetAttribute("sentry.sdk.name", name);
}
if (sdk.Version is { } version)
if (sdk?.Version is { } version)
{
SetAttribute("sentry.sdk.version", version);
}

// Server Attributes
if (!string.IsNullOrEmpty(options.ServerName))
{
SetAttribute("server.address", options.ServerName!);
}
else if (options.SendDefaultPii)
{
SetAttribute("server.address", Environment.MachineName);
}

// User Attributes
if (scope?.User is { } user)
Comment thread
jamescrosswell marked this conversation as resolved.
{
if (user.Id is { } userId)
{
SetAttribute("user.id", userId);
}
if (user.Username is { } username)
{
SetAttribute("user.name", username);
}
if (user.Email is { } email)
{
SetAttribute("user.email", email);
}
}
}

internal void SetOrigin(string origin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public Fixture()

Options = Microsoft.Extensions.Options.Options.Create(loggingOptions);
Hub = Substitute.For<IHub>();
Hub.SubstituteConfigureScope(new Scope(loggingOptions));
Clock = new MockClock();
Sdk = new SdkVersion
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public Fixture()
CategoryName = nameof(CategoryName);
Options = Microsoft.Extensions.Options.Options.Create(loggingOptions);
Hub = Substitute.For<IHub>();
Hub.SubstituteConfigureScope(new Scope(loggingOptions));
Clock = new MockClock(new DateTimeOffset(2025, 04, 22, 14, 51, 00, 789, TimeSpan.FromHours(2)));
Sdk = new SdkVersion
{
Expand Down
89 changes: 79 additions & 10 deletions test/Sentry.Tests/SentryLogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,9 @@ public void Protocol_Default_VerifyAttributes()
Environment = "my-environment",
Release = "my-release",
};
var sdk = new SdkVersion
{
Name = "Sentry.Test.SDK",
Version = "1.2.3-test+Sentry",
};
var scope = new Scope(options);
scope.Sdk.Name = "Sentry.Test.SDK";
scope.Sdk.Version = "1.2.3-test+Sentry";

var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message")
{
Expand All @@ -57,7 +55,7 @@ public void Protocol_Default_VerifyAttributes()
SpanId = SpanId,
};
log.SetAttribute("attribute", "value");
log.SetDefaultAttributes(options, sdk);
log.SetDefaultAttributes(options, scope);

log.Timestamp.Should().Be(Timestamp);
log.TraceId.Should().Be(TraceId);
Expand All @@ -77,13 +75,81 @@ public void Protocol_Default_VerifyAttributes()
log.TryGetAttribute("sentry.release", out string release).Should().BeTrue();
release.Should().Be(options.Release);
log.TryGetAttribute("sentry.sdk.name", out string name).Should().BeTrue();
name.Should().Be(sdk.Name);
name.Should().Be(scope.Sdk.Name);
log.TryGetAttribute("sentry.sdk.version", out string version).Should().BeTrue();
version.Should().Be(sdk.Version);
version.Should().Be(scope.Sdk.Version);
log.TryGetAttribute("not-found", out object notFound).Should().BeFalse();
notFound.Should().BeNull();
}

[Fact]
public void SetDefaultAttributes_OptionsServerName_SetsServerAddress()
{
var options = new SentryOptions { ServerName = "my-server" };
var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Info, "message");

log.SetDefaultAttributes(options, new Scope(options));

log.TryGetAttribute("server.address", out string address).Should().BeTrue();
address.Should().Be("my-server");
}

[Fact]
public void SetDefaultAttributes_SendDefaultPii_SetsServerAddressToMachineName()
{
var options = new SentryOptions { SendDefaultPii = true };
var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Info, "message");

log.SetDefaultAttributes(options, new Scope(options));

log.TryGetAttribute("server.address", out string address).Should().BeTrue();
address.Should().Be(Environment.MachineName);
}

[Fact]
public void SetDefaultAttributes_NoServerNameNoPii_OmitsServerAddress()
{
var options = new SentryOptions();
var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Info, "message");

log.SetDefaultAttributes(options, new Scope(options));

log.TryGetAttribute("server.address", out object _).Should().BeFalse();
}

[Fact]
public void SetDefaultAttributes_ScopeUser_SetsUserAttributes()
{
var options = new SentryOptions();
var scope = new Scope(options)
{
User = new SentryUser { Id = "user-id", Username = "user-name", Email = "user@example.com" },
};
var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Info, "message");

log.SetDefaultAttributes(options, scope);

log.TryGetAttribute("user.id", out string id).Should().BeTrue();
id.Should().Be("user-id");
log.TryGetAttribute("user.name", out string username).Should().BeTrue();
username.Should().Be("user-name");
log.TryGetAttribute("user.email", out string email).Should().BeTrue();
email.Should().Be("user@example.com");
}

[Fact]
public void SetDefaultAttributes_NoScopeUser_OmitsUserAttributes()
{
var options = new SentryOptions();
var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Info, "message");

log.SetDefaultAttributes(options, new Scope(options));

log.TryGetAttribute("user.id", out object _).Should().BeFalse();
log.TryGetAttribute("user.name", out object _).Should().BeFalse();
log.TryGetAttribute("user.email", out object _).Should().BeFalse();
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down Expand Up @@ -118,7 +184,7 @@ public void WriteTo_Envelope_MinimalSerializedSentryLog()
};

var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Trace, "message");
log.SetDefaultAttributes(options, new SdkVersion());
log.SetDefaultAttributes(options, new Scope(options));

var envelope = Envelope.FromLog(new StructuredLog([log]));

Expand Down Expand Up @@ -196,7 +262,10 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog()
log.SetAttribute("boolean-attribute", true);
log.SetAttribute("integer-attribute", 3);
log.SetAttribute("double-attribute", 4.4);
log.SetDefaultAttributes(options, new SdkVersion { Name = "Sentry.Test.SDK", Version = "1.2.3-test+Sentry" });
var scope = new Scope(options);
scope.Sdk.Name = "Sentry.Test.SDK";
scope.Sdk.Version = "1.2.3-test+Sentry";
log.SetDefaultAttributes(options, scope);

var envelope = EnvelopeItem.FromLog(new StructuredLog([log]));

Expand Down
52 changes: 52 additions & 0 deletions test/Sentry.Tests/SentryStructuredLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,58 @@ public void Dispose_BeforeLog_DoesNotCaptureEnvelope()
entry.Args.Should().BeEquivalentTo([nameof(SentryLog)]);
}

[Fact]
public void Log_WithScopeUser_SetsUserAttributes()
{
var scope = new Scope();
scope.User = new SentryUser { Id = "user-id", Username = "user-name", Email = "user@example.com" };
_fixture.Hub.SubstituteConfigureScope(scope);

SentryLog capturedLog = null!;
_fixture.Options.EnableLogs = true;
_fixture.Options.SetBeforeSendLog((SentryLog log) =>
{
capturedLog = log;
return log;
});
var logger = _fixture.GetSut();

logger.LogInfo("A message");
logger.Flush();

capturedLog.Should().NotBeNull();
capturedLog.TryGetAttribute("user.id", out string? userId).Should().BeTrue();
userId.Should().Be("user-id");
capturedLog.TryGetAttribute("user.name", out string? userName).Should().BeTrue();
userName.Should().Be("user-name");
capturedLog.TryGetAttribute("user.email", out string? userEmail).Should().BeTrue();
userEmail.Should().Be("user@example.com");
}

[Fact]
public void Log_WithoutScopeUser_DoesNotSetUserAttributes()
{
var scope = new Scope();
_fixture.Hub.SubstituteConfigureScope(scope);

SentryLog capturedLog = null!;
_fixture.Options.EnableLogs = true;
_fixture.Options.SetBeforeSendLog((SentryLog log) =>
{
capturedLog = log;
return log;
});
var logger = _fixture.GetSut();

logger.LogInfo("A message");
logger.Flush();

capturedLog.Should().NotBeNull();
capturedLog.TryGetAttribute("user.id", out object? _).Should().BeFalse();
capturedLog.TryGetAttribute("user.name", out object? _).Should().BeFalse();
capturedLog.TryGetAttribute("user.email", out object? _).Should().BeFalse();
}

private static void ConfigureLog(SentryLog log)
{
log.SetAttribute("attribute-key", "attribute-value");
Expand Down
Loading