Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LogEventBuilder - Added Log(Type wrapperType) for custom Logger wrapper #5056

Merged
merged 1 commit into from
Sep 3, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/NLog/Abstractions/ILoggerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ LogFactory Factory
/// <summary>
/// Writes the specified diagnostic message.
/// </summary>
/// <param name="wrapperType">The name of the type that wraps Logger.</param>
/// <param name="wrapperType">Type of custom Logger wrapper.</param>
/// <param name="logEvent">Log event.</param>
void Log(Type wrapperType, LogEventInfo logEvent);

Expand Down
57 changes: 46 additions & 11 deletions src/NLog/LogEventBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public LogEventBuilder([NotNull] ILogger logger)
_logEvent = new LogEventInfo() { LoggerName = _logger.Name };
}


/// <summary>
/// Initializes a new instance of the <see cref="LogEventBuilder"/> class.
/// </summary>
Expand Down Expand Up @@ -91,7 +90,7 @@ public LogEventBuilder([NotNull] ILogger logger, [NotNull] LogLevel logLevel)
/// Logging event that will be written
/// </summary>
[CanBeNull]
public LogEventInfo LogEvent => _logEvent;
public LogEventInfo LogEvent => _logEvent is null ? null : ResolveLogEvent(_logEvent);

/// <summary>
/// Sets a per-event context property on the logging event.
Expand Down Expand Up @@ -121,7 +120,7 @@ public LogEventBuilder Properties([NotNull] IEnumerable<KeyValuePair<string, obj

if (_logEvent is null)
return this;

foreach (var property in properties)
_logEvent.Properties[property.Key] = property.Value;
return this;
Expand Down Expand Up @@ -305,16 +304,52 @@ public LogEventBuilder Message(IFormatProvider formatProvider, [Localizable(fals
{
if (_logEvent != null)
{
if (logLevel != null)
_logEvent.Level = logLevel;
else if (_logEvent.Level == null)
_logEvent.Level = _logEvent.Exception != null ? LogLevel.Error : LogLevel.Info;
if (_logEvent.Message == null)
_logEvent.Message = _logEvent.Exception != null ? _logEvent.Exception.Message : string.Empty;
if (_logEvent.CallSiteInformation == null && _logEvent.Level != LogLevel.Off)
var logEvent = ResolveLogEvent(_logEvent, logLevel);
if (logEvent.CallSiteInformation is null && _logger.IsEnabled(logEvent.Level))
{
_logEvent.SetCallerInfo(null, callerMemberName, callerFilePath, callerLineNumber);
_logger.Log(_logEvent);
}
_logger.Log(logEvent);
}
}

/// <summary>
/// Writes the log event to the underlying logger.
/// </summary>
/// <param name="wrapperType">Type of custom Logger wrapper.</param>
#if !NET35
public void Log(Type wrapperType)
#else
public void Log(Type wrapperType)
#endif
{
if (_logEvent != null)
{
var logEvent = ResolveLogEvent(_logEvent);
_logger.Log(wrapperType, logEvent);
}
}

private LogEventInfo ResolveLogEvent(LogEventInfo logEvent, LogLevel logLevel = null)
{
if (logLevel is null)
{
if (logEvent.Level is null)
logEvent.Level = logEvent.Exception != null ? LogLevel.Error : LogLevel.Info;
}
else
{
logEvent.Level = logLevel;
}

if (logEvent.Message is null && logEvent.Exception != null && _logger.IsEnabled(logEvent.Level))
{
logEvent.FormatProvider = NLog.Internal.ExceptionMessageFormatProvider.Instance;
logEvent.Message = "{0}";
logEvent.Parameters = new object[] { logEvent.Exception };
}

return logEvent;
}
}
}
8 changes: 4 additions & 4 deletions src/NLog/LogFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ public Logger GetCurrentClassLogger(Type loggerType)
#else
var className = StackTraceUsageUtils.GetClassFullName();
#endif
return GetLoggerThreadSafe(className, loggerType);
return GetLoggerThreadSafe(className, loggerType ?? typeof(Logger));
}

/// <summary>
Expand Down Expand Up @@ -539,7 +539,7 @@ public T GetLogger<T>(string name) where T : Logger, new()
/// same argument aren't guaranteed to return the same logger reference.</returns>
public Logger GetLogger(string name, Type loggerType)
{
return GetLoggerThreadSafe(name, loggerType);
return GetLoggerThreadSafe(name, loggerType ?? typeof(Logger));
}

private bool RefreshExistingLoggers()
Expand Down Expand Up @@ -1068,12 +1068,12 @@ public void ResetCandidateConfigFilePath()
_candidateConfigFilePaths = null;
}

private Logger GetLoggerThreadSafe(string name, Type loggerType)
private Logger GetLoggerThreadSafe(string name, [NotNull] Type loggerType)
{
if (name is null)
throw new ArgumentNullException(nameof(name), "Name of logger cannot be null");

LoggerCacheKey cacheKey = new LoggerCacheKey(name, loggerType ?? typeof(Logger));
LoggerCacheKey cacheKey = new LoggerCacheKey(name, loggerType);

lock (_syncRoot)
{
Expand Down
2 changes: 1 addition & 1 deletion src/NLog/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public void Log(LogEventInfo logEvent)
/// <summary>
/// Writes the specified diagnostic message.
/// </summary>
/// <param name="wrapperType">The name of the type that wraps Logger.</param>
/// <param name="wrapperType">Type of custom Logger wrapper.</param>
/// <param name="logEvent">Log event.</param>
public void Log(Type wrapperType, LogEventInfo logEvent)
{
Expand Down
2 changes: 1 addition & 1 deletion tests/NLog.UnitTests/Fluent/LogEventBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ public void LogBuilder_exception_only()
.Exception(ex)
.Log();

var expectedEvent = new LogEventInfo(LogLevel.Error, "logger1", ex.Message) { Exception = ex };
var expectedEvent = LogEventInfo.Create(LogLevel.Error, "logger1", null, ex);
AssertLastLogEventTarget(expectedEvent);
}

Expand Down
32 changes: 27 additions & 5 deletions tests/NLog.UnitTests/LayoutRenderers/CallSite/CallSiteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,10 @@ public void When_Wrapped_Ignore_Wrapper_Methods_In_Callstack()
var wrappedLogger = new MyWrapper(logFactory);
wrappedLogger.Log("wrapped");
logFactory.AssertDebugLastMessage($"{currentMethodFullName}|wrapped");

var fluentLogger = new MyFluentWrapper(logFactory);
fluentLogger.Log("wrapped");
logFactory.AssertDebugLastMessage($"{currentMethodFullName}|wrapped");
}

[Fact]
Expand Down Expand Up @@ -1022,12 +1026,12 @@ public void Log(string what)
InternalLog(typeof(BaseWrapper), what);
}

public void Log(Type type, string what) //overloaded with type for composition
public void Log(Type wrapperType, string what) //overloaded with type for composition
{
InternalLog(type, what);
InternalLog(wrapperType, what);
}

protected abstract void InternalLog(Type type, string what);
protected abstract void InternalLog(Type wrapperType, string what);
}

public class MyWrapper : BaseWrapper
Expand All @@ -1039,14 +1043,32 @@ public MyWrapper(LogFactory logFactory)
_wrapperLogger = logFactory.GetLogger("WrappedLogger");
}

protected override void InternalLog(Type type, string what) //added type for composition
protected override void InternalLog(Type wrapperType, string what) //added type for composition
{
LogEventInfo info = new LogEventInfo(LogLevel.Warn, _wrapperLogger.Name, what);

// Provide BaseWrapper as wrapper type.
// Expected: UserStackFrame should point to the method that calls a
// method of BaseWrapper.
_wrapperLogger.Log(type, info);
_wrapperLogger.Log(wrapperType, info);
}
}

public class MyFluentWrapper : BaseWrapper
{
private readonly Logger _wrapperLogger;

public MyFluentWrapper(LogFactory logFactory)
{
_wrapperLogger = logFactory.GetLogger("WrappedLogger");
}

protected override void InternalLog(Type wrapperType, string what) //added type for composition
{
// Provide BaseWrapper as wrapper type.
// Expected: UserStackFrame should point to the method that calls a
// method of BaseWrapper.
_wrapperLogger.ForWarnEvent().Message(what).Log(wrapperType);
}
}

Expand Down