EventView Appender Log4net using C# - c#

I want clarification on root cause of an issue. I have integrated log4net library in my C# project. I have created appender using code. FileAppender, ConsoleAppender and AdoDotnetAppender was working fine but event
var eventViewAppender = new log4net.Appender.EventLogAppender();
eventViewAppender.Threshold = Level.Error;
eventViewAppender.LogName = "MyName";
eventViewAppender.ApplicationName = "MyName";
var layout = new log4net.Layout.PatternLayout()
{
ConversionPattern = "%date{hh:mm:ss.fff} [%thread] %-5level - %message%newline"
};
eventViewAppender.Layout = layout;
layout.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(eventViewAppender);
Then I took approach of having xml format configuration in app.config. I had below settings.
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<applicationName value="MyApp" />
<logName value="MyApp" />
<threshold value="ERROR" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
I think both configuration should work, but unfortunately second option works while first not. If anyone had encountered similar issue and fixed it, please do let me know resolution.

Related

How to log timestamp in EST format using log4net configuration ignoring the Server Timezone it runs on

I have added my log4net.config setting at the end of my question.
In "MyLog.txt" file I want to log timestamp in EST format using just the config file.
It should replace the %date in config below. I have seen some random articles suggest something like %d{yyyy-MM-dd HH:mm:ss}{GMT-4} but that didnt work.
I also read that Log4j has something called EnhancedPatternLayout which seems to have such date options. But Log4net has nothing equivalent.
Please share if you have some solution to show EST dynamically in Log irrespective of the Server timezone it runs on.
<appender name="ApiLoggerAppender" type="log4net.Appender.RollingFileAppender">
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="C:\MyLog.txt"/>
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="-ddMMyyyy" />
<PreserveLogFileNameExtension value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>

Configuring log4net without code in Rider for dotnet 2.1 project

I'm working on a pet .netcore2.1 project using Rider IDE. I'm currently trying to add log4net support for the project, and trying to do it the "proper way" (separate config file, automatically configure log4net without having to write code for intialization etc.). So far all tutorials (ex1, ex2) I've found suggest configuring it by adding assembly property
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
to AssemblyInfo.cs file. However I seem to fail to find the file, and it looks from other questions (e.g. this) that it might not be used with .netcore at all, in favor of doing configuration via other means (e.g. .csproj file).
So far I've found a workaround here, which works, but it uses explicit configuration via code, which looks like a step backwards compared to assembly-level configuration.
Is there a way of doing this in a more static way (e.g. using some ItemGroup in .csproj)?
Upd: for future reference - this is just a custom case of https://learn.microsoft.com/en-us/dotnet/standard/assembly/set-attributes , so it just goes to .cs file directly.
Easy example using log4net for .net core in console:
[assembly: XmlConfigurator(Watch = true)]
namespace ConsoleApp
{
class Program
{
private static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));
log.Info("Entering application.");
log.Error("Error application.");
}
}
}
You need to add file with settings log4net to your project: log4net.config, and don't forget chnage it options "Copy to output directory" to "Copy if newer" or "Copy always"
Example of log4net.config:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<file value="logs/" />
<datePattern value="yyyy-MM-dd'.log'" />
<staticLogFileName value="false" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<layout type="log4net.Layout.PatternLayout">
<IgnoresException value="False" />
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
</filter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="FileAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
By the way: log4net don't supporting for 1 april 2020: http://logging.apache.org/log4net/

Log4net - How to get calling method name when using wrapper

I have a log4net wrapper for logging error messages in web api application. It is working fine but i am not able to log calling method name. It only display's top level method name. Lets say, i have a method a of class A which calls method b of a class B and b logs error message. Log4net only displays Class A and method a but i want to display either full calling chain A-a-B-b or at least B-b
private static readonly ILog LoggerObject = LogManager.GetLogger("ErrorLog");
log4net config
<log4net>
<appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
<file value="LogBackUp2.log" />
<staticLogFileName value="false" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyy-MM-dd.'Err'" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%M %C] - %message%newline" />
</layout>
</appender>
<logger name="ErrorLog">
<maximumFileSize value="15MB" />
<appender-ref ref="ErrorLog" />
</logger>
</log4net>
If i use this then log4net doesn't create any log file.
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
use %stacktrace{5} to show 5 levels of the stacktrace which lead to the call of the log method. Replace the 5 with the level you want to have. example:
<conversionPattern value="%date [%thread] %-5level %logger [%stacktrace{5}] - %message%newline" />
When you use a log4net wrapper you may want to apply this to get rid of the wrapper in the stacktrace

How to shorten log4net logger path

my log4net conversionpattern displays full path to class:
11:40:11,209 [C:\Users\martin\Documents\Visual Studio 2015\Projects\MyProject\MyProject\ViewModels\MainViewModel.cs] DEBUG - Test log
Is there a way how to shorten path to class name only?
11:40:11,209 [MainViewModel.cs] DEBUG - Test log
It's also my typical experience to have trouble with the odd conversion nomenclature and the scant levels of documentation that seems to be available in a central location.
I have adapted the conversion pattern I normally use to get you something similar to what you requested:
<conversionPattern value="%d %-22.22c{1} %-5p - %m%n"/>
The %-22.22c{1} bit is the shortened class name (I guess) :)
The above will result in something like:
2015-12-28 11:11:26,892 MyClass DEBUG - Test log
in the log4net configuration try using
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%-4thread] %-5level %logger{1} - %message%newline"/>
</layout>
use conversion pattern value like following
<conversionPattern value="[%d{yyyy-MM-dd HH:mm:ss}] [%t] %-5p %c - %m%n" />
See more in about conversionPattern

Customizing the body of the email using Log4net Smtp appender

How do I customize the body of the email using Log4net Smtp appender? I wanted to add custom message to the body.
Given you are using an appender similar this
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="to#domain.com" />
<from value="from#domain.com" />
<subject value="test logging message" />
<smtpHost value="SMTPServer.domain.com" />
<bufferSize value="512" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</appender>
You should be able to format the message using StringBuilder before logging:
var sb = new StringBuilder();
sb.Append("Header");
sb.Append(Environment.NewLine);
sb.Append("Message");
...
var msg = sb.ToString();
ILog log = //resolve ILog
log.Debug(msg);
More config samples here search for SmtpAppender
You can create your own appender and inherit it from SmtpAppender. There you can override such methods as SendEmail and so on.
class MySmtpAppender : SmtpAppender
{
protected override void SendEmail(string messageBody)
{
string newmessageBody = messageBody + "...";
base.SendEmail(newmessageBody);
}
}
<appender name="MySmtpAppender" type="YourLib.MySmtpAppender">
You can also add some extra properties to this class and you will be able to use them in your config file.
When you use an SMTP Appender the message body contains the log event,
Which is formatted by the layout you specify when you configure the appender.
The most used one is PatternLayout so whatever you put in this layout's conventionPattern property will go into the email message body.
so you should do something like this:
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="to#domain.com" />
<from value="from#domain.com" />
<subject value="test logging message" />
<smtpHost value="SMTPServer.domain.com" />
<bufferSize value="512" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="Hello, we got an error in the app. here are the details: %newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
</layout>
</appender>
You can customize at layout level for example by adding an header and/or a footer:
<layout type="log4net.Layout.PatternLayout">
<header value="[Header]
" />
<footer value="[Footer]
" />
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
The body is controlled using a conversion pattern (like any other appender).
<appender name="EmailAppender" type="log4net.Appender.SmtpAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%n%n%d{yyyy-MM-dd HH:mm:ss} %5p %10u %m" />
</layout>
</appender>

Categories