Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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.
Comment thread
Flash0ver marked this conversation as resolved.

CaptureLog(log);
}
Expand Down
33 changes: 32 additions & 1 deletion src/Sentry/SentryLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,40 @@ public bool TryGetAttribute(string key, [NotNullWhen(true)] out object? value) =
/// </summary>
public void SetAttribute(string key, object value) => Attributes.SetAttribute(key, value);

internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk) =>
internal void SetDefaultAttributes(SentryOptions options, Scope? scope, SdkVersion? sdk = null)
{
// Core Attributes
sdk ??= scope?.Sdk ?? SdkVersion.Instance;
Comment thread
Flash0ver marked this conversation as resolved.
Attributes.SetDefaultAttributes(options, sdk);

// 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);
}
}
Comment thread
Flash0ver marked this conversation as resolved.
}

internal void SetOrigin(string origin) => Attributes.SetAttribute("sentry.origin", origin);

internal void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger)
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
84 changes: 74 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 @@ -73,11 +71,74 @@ public void Protocol_Default_VerifyAttributes()
log.Attributes.ShouldContain<string>("attribute", "value");
log.Attributes.ShouldContain<string>("sentry.environment", options.Environment);
log.Attributes.ShouldContain<string>("sentry.release", options.Release);
log.Attributes.ShouldContain<string>("sentry.sdk.name", sdk.Name);
log.Attributes.ShouldContain<string>("sentry.sdk.version", sdk.Version);
log.Attributes.ShouldContain<string>("sentry.sdk.name", scope.Sdk.Name);
log.Attributes.ShouldContain<string>("sentry.sdk.version", scope.Sdk.Version);
log.Attributes.ShouldNotContain<object>("not-found");
}

[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.Attributes.ShouldContain("server.address", "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.Attributes.ShouldContain("server.address", 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.Attributes.ShouldNotContain<string>("server.address");
}

[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.Attributes.ShouldContain("user.id", "user-id");
log.Attributes.ShouldContain("user.name", "user-name");
log.Attributes.ShouldContain("user.email", "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.Attributes.ShouldNotContain<string>("user.id");
log.Attributes.ShouldNotContain<string>("user.name");
log.Attributes.ShouldNotContain<string>("user.email");
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down Expand Up @@ -112,7 +173,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 @@ -190,7 +251,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
49 changes: 49 additions & 0 deletions test/Sentry.Tests/SentryStructuredLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,55 @@ 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.Attributes.ShouldContain("user.id", "user-id");
capturedLog.Attributes.ShouldContain("user.name", "user-name");
capturedLog.Attributes.ShouldContain("user.email", "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