On the project, I replace Serilog with NLog. In Serilog, I could create several sublogs with my own filters for a separate project. Here is my configuration:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.File(...filapath...)
.WriteTo.Logger(l => l
.Filter.ByIncludingOnly(Matching.FromSource<ExceptionMiddleware>())
.WriteTo.Email(new EmailConnectionInfo()
{
FromEmail = fromEmail,
ToEmail = toEmail,
EmailSubject = subject,
NetworkCredentials = credentials,
Port = port,
MailServer = mailServer,
}))
.WriteTo.Logger(l => l
.Filter.ByIncludingOnly(Matching.FromSource("SomeProjectName"))
.WriteTo.File(anotherFilePath)
.WriteTo.Email(new EmailConnectionInfo()
{
FromEmail = fromEmail,
ToEmail = toEmail,
EmailSubject = subject,
NetworkCredentials = credentials,
Port = port,
MailServer = mailServer,
}, restrictedToMinimumLevel: LogEventLevel.Error,
outputTemplate:
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{NewLine}{Exception}"))
.CreateLogger();
How can I implement this functionality in NLog? Here is my current configuration of the file:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="NLog.Extended" />
</extensions>
<extensions>
<add assembly="NLog.MailKit" />
</extensions>
<extensions>
<add assembly="NLog.Web" />
</extensions>
<extensions>
<add assembly="NLog.Web.AspNetCore" />
</extensions>
<variable name="smtp-server" value="smtp-server" />
<variable name="smtp-port" value="port" />
<variable name="smtp-password" value="password" />
<variable name="smtp-authentication" value="Basic" />
<variable name="smtp-ssl" value="ssl" />
<variable name="smtp-username" value="username" />
<variable name="smtp-from" value="from" />
<variable name="smtp-to" value="to" />
<targets>
<target name="fileLogs"
xsi:type="File"
fileName="${currentdir}/Logs/log.txt"
createDirs="True" />
<target name="mailLogs" xsi:type="Mail"
subject="subject}"
body="${message}${newline}"
from="${smtp-from}"
to="${smtp-to}"
smtpUsername="${smtp-username}"
secureSocketOption="sslOnConnect"
enableSsl="${smtp-ssl}"
smtpPassword="${smtp-password}"
smtpAuthentication="${smtp-authentication}"
smtpServer="${smtp-Server}"
smtpPort="${smtp-port}" />
</targets>
<rules>
<logger name="*" levels="Info,Error" writeTo="consoleLogs" />
<logger name="*" levels="Info,Debug,Error" writeTo="fileLogs" />
<logger name="*" minlevel="Error" writeTo="mailLogs" />
</rules>
</nlog>
I'm trying to create an alternative to subloger, similar to the Serilog functionality in NLog. More precisely, I am trying to create separate targets for SomeProjectName - file, mail.
Do you see the asterisks in <logger>
tags? <logger name="*" .../>
. Those are the filters you're looking for. Every Logger
object in your code has a name. Loggers created with LogManager.GetCurrentClassLogger()
have the name of the class in which the object was created, including namespaces. But you can call LogManager.GetLogger(string)
instead, and choose any string for the name. Filters are resolved from first to last, and you can stop the search if the filter is matched with final
attribute set to true. So, you create a special logger in your code:
var log = LogManager.GetLogger("Special");
And you use it in configuration, like this (make sure it's before all other rules):
<logger name="Special" final="true" writeTo="specialLogFile"/>
where "specialLogFile" is defined in <targets>
section.
In most cases logger name and log level are sufficient to filter all logs. But there is even more powerful filtering feature, with <filters>
section and <when>
conditions. Start from here to learn more about it.