Skip to content
Open
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
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
31 changes: 30 additions & 1 deletion 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,6 +184,7 @@ internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk)
SetAttribute("sentry.release", release);
}

sdk ??= scope?.Sdk ?? SdkVersion.Instance;
if (sdk.Name is { } name)
{
SetAttribute("sentry.sdk.name", name);
Expand All @@ -191,6 +193,33 @@ internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk)
{
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