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
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.Attributes.ShouldNotContain<object>("user.id");
capturedLog.Attributes.ShouldNotContain<object>("user.name");
capturedLog.Attributes.ShouldNotContain<object>("user.email");
}

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