I am using log4net-core-preview(2.0.6) in Asp.Net Web API Core 2.0, and my log4net config layout is
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p %d{hh:mm:ss} %logger [%M %line] %message%newline" />
</layout>
and at Startup.ConfigureServices
//log4net stuff goes here ...
var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
XmlConfigurator.Configure(logRepo, File.OpenRead("log4net.config"));
ILog log = LogManager.GetLogger(this.GetType());
log.Info("App is starting");
but I don't know why my logs look like this
DEBUG 01:29:10 MyNameSpace.Controllers.XYZController [? ?] , somemessage
Can anyone tell me what's wrong here
thanks
A little bit late but just run into this issue recently, turns out that some patterns are not supported under .NET Standard framework.
According to Apache's documentation, these features are not supported:
- the ADO.NET appender
- anything related to ASP.NET (trace appender and several pattern converters)
- .NET Remoting
- the colored console appender
- the event log appender
- The NetSendAppender
- The SMTP appender
- DOMConfigurator
- stack trace patterns
- access to appSettings (neither the log4net section itself nor using the AppSettingsPatternConverter)
- Access to "special paths" using the EnvironmentFolderPathPatternConverter
- Impersonation of Windows accounts
There are two workarounds:
PatternConverter
with StackTrace
(.NET Standard 2.0 and later
required) shown as belowStackTraceConverter.cs
namespace MyWebApp
{
public class StackTraceConverter : PatternConverter
{
protected override void Convert(TextWriter writer, object state)
{
try
{
StackTrace st = new StackTrace(true);
int idx = 1;
while (st.GetFrame(idx).GetMethod().DeclaringType.Assembly == typeof(LogManager).Assembly)
idx++;
//I have to create a new StackTrace object in order to get the line number.
var targetSt = new StackTrace(st.GetFrame(idx));
writer.Write($"{targetSt.GetFrame(0).GetMethod().DeclaringType.FullName}.{targetSt.GetFrame(0).GetMethod().Name}({targetSt.GetFrame(0).GetFileLineNumber()})");
}
catch (Exception)
{
}
}
}
}
StackTracePatternLayout.cs
namespace MyWebApp
{
public class StackTracePatternLayout : PatternLayout
{
public StackTracePatternLayout()
{
AddConverter(new ConverterInfo
{
Name = "stack_trace", //your pattern name here
Type = typeof(StackTraceConverter)
}
);
}
}
}
And log4net.config
<appender name="RollingFileAppenderCustomPattern" type="log4net.Appender.RollingFileAppender">
...
<layout type="MyWebApp.StackTracePatternLayout, MyWebApp">
<conversionPattern value="%-5p %date{yyyy/MM/dd HH:mm:ss} [tread-%t] %stack_trace - %m%n" />
</layout>
...
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppenderCustomPattern" />
</root>
Then log as usual
public class HomeController : Controller
{
...
public IActionResult LogForNetTest()
{
if (Logger.IsDebugEnabled)
Logger.Debug($"Log4Net is ready to log!");
...
}
...
}
The result is something like this
DEBUG 2018/07/02 15:30:59 [tread-9] MyWebApp.Controllers.HomeController.LogForNetTest(46) - Log4Net is ready to log!
Haven't fully tested yet but both methods work well so far, though there are some differences between them:
Caller info attribute
can only get file path, StackTrace
can get AssemblyQualifiedName
or it's namespace with DeclaringType.FullName
, providing more information.Hope this will help.
Timmy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With