This is my NLog Config file.
<?xml version="1.0" ?>
<nlog autoReload="true" throwExceptions="true" internalLogLevel="Debug" internalLogToConsole="true"
internalLogFile="c:\\temp\\nlog.txt"
>
<targets>
<!--Useful for debugging-->
<target name="consolelog" type="ColoredConsole"
layout="${date:format=HH\:mm\:ss}|${level}|${stacktrace}|${message}" />
<target name="filelog" type="File" fileName="c:\\temp\\nlog1.txt"
layout="${date}: ${message}" />
<target name="eventlog" type="EventLog" source="My App" log="Application"
layout="${date}: ${message} ${stacktrace}" />
<target name="databaselog" type="Database">
<dbProvider>sqlserver</dbProvider>
<!-- database connection parameters -->
<!-- alternatively you could provide a single 'connectionstring' parameter -->
<connectionString>Data Source=.\SQLEXPRESS;Initial Catalog=SnSolutions;User Id=sa;Password=test#1234#;</connectionString>
<!--<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MyTest;User Id=mytest;Password=mytest123;" providerName="System.Data.SqlClient" />-->
<commandText>
insert into NLog_Error ([time_stamp],[level],[host],[type],1,[logger],[message],[stacktrace],[allxml]) values(#time_stamp,#level,#host,#type,#source,#logger,#message,#stacktrace,#allxml);
</commandText>
<parameter name="#time_stamp" layout="${date}" />
<parameter name="#level" layout="${level}" />
<parameter name="#host" layout="${machinename}" />
<parameter name="#type" layout="${exception:format=type}" />
<parameter name="#source" layout="${callsite:className=true:fileName=false:includeSourcePath=false:methodName=false}" />
<parameter name="#logger" layout="${logger}" />
<parameter name="#message" layout="${message}" />
<parameter name="#stacktrace" layout="${exception:stacktrace}" />
<parameter name="#allxml" layout="${web_variables}" />
</target>
</targets>
<rules>
<!--
<logger name="*" minlevel="Fatal" writeTo="eventlog" />
-->
<logger name="*" minlevel="Info" writeTo="filelog" />
<logger name="*" minlevel="Info" writeTo="databaselog" />
</rules>
</nlog>
This is my NLogLogger Class
public class NLogLogger
{
private readonly Logger _logger;
public NLogLogger(Logger logger)
{
_logger = logger;
}
public NLogLogger()
{
StackFrame frame = new StackFrame(1, false);
_logger = LogManager.GetLogger(frame.GetMethod().DeclaringType.FullName);
}
public void Trace(string message)
{
_logger.Trace(message);
}
public void Debug(string message)
{
_logger.Debug(message);
}
public void Info(string message)
{
_logger.Info(message);
}
public void Warn(string message)
{
_logger.Warn(message);
}
public void Error(string message)
{
_logger.Error(message);
}
public void Fatal(string message)
{
_logger.Fatal(message);
}
}
which I am trying to use in the following way.
NLogLogger logger = new NLogLogger();
logger.Info("We're on the Index page for Activities");
But not able to see any records in the DB nor any error in the File System.
Please let me know which is the part I am missing.
Thanks in advance.
You have an error in insert command - 1 is not a valid column name.
insert into NLog_Error (...[type],1,[logger]..)
Here is an example regarding logging to DB.
Related
xsi:type="File" has maxArchiveFiles="5" archiveEvery="Day" properties. Is that possibble to delete db content older than X days?
xsi:type="Database" has rules for that purpose?
My sample Nlog.config;
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
throwConfigExceptions="true"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<targets>
<!--target name="logfile" xsi:type="File" fileName="file.txt" /!-->
<target xsi:type="Database"
name="db"
dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite"
connectionString="Data Source=log.db3;"
commandType="Text"
commandText="INSERT into Log(Timestamp, Loglevel, Callsite, Message) values(#Timestamp, #Loglevel, #Callsite, #Message)"
>
<parameter name="#Timestamp" layout="${longdate}"/>
<parameter name="#Loglevel" layout="${level:uppercase=true}"/>
<parameter name="#Callsite" layout="${callsite:filename=true}"/>
<parameter name="#Message" layout="${message}"/>
</target>
<target name="colouredConsole" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false" layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}">
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Info" maxlevel="Info" writeTo="colouredConsole" />
<logger name="*" minlevel="Error" maxlevel="Error" writeTo="colouredConsole" />
<logger name="*" minlevel="Debug" maxlevel="Debug" writeTo="colouredConsole" />
<logger name="*" minlevel="Debug" maxlevel="Debug" writeTo="db" />
<logger name="*" minlevel="Error" maxlevel="Error" writeTo="db" />
</rules>
</nlog>
How to delete sqlite db content older than 7 days?
Some people suggests EnsureDb(); it works but I want to ask any possibility to set from xsi:type="Database" parameters?
private static void EnsureDb()
{
if (File.Exists("log.db3"))
{
using (SQLiteConnection connection = new SQLiteConnection("Data Source=log.db3"))
using (SQLiteCommand command = new SQLiteCommand(
"DELETE FROM Log WHERE Timestamp <= datetime('now', '-7 day');",
connection))
{
connection.Open();
command.ExecuteNonQuery();
}
return;
}
using (SQLiteConnection connection = new SQLiteConnection("Data Source=log.db3"))
using (SQLiteCommand command = new SQLiteCommand(
"CREATE TABLE Log (Timestamp TEXT, Loglevel TEXT, Callsite TEXT, Message TEXT)",
connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
I have an SmtpAppender like this:
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="MyEmail#example.org" />
<from value="SenderEmail#example.org" />
<subject type="log4net.Util.PatternString" value="This is a subject" />
<smtpHost value="smtp.host.value" />
<authentication value="Basic" />
<port value="587" />
<username value="Username" />
<password value="Password" />
<bufferSize value="1" />
<EnableSsl value="true"/>
<lossy value="false" />
<threshold value="ERROR" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%3thread] %-5level [%class].[%method] - %message%newline" />
</layout>
</appender>
I would like to change the subject of the log mail in my code to a string I would specify so it suits my needs better than a standard subject.
Right now I achieve it like this. First, I find the SmtpAppender by name:
public static IAppender FindAppenderByName(string name)
{
ILoggerRepository rootRep = LogManager.GetRepository();
foreach (IAppender iApp in rootRep.GetAppenders()) {
if (string.Compare(name, iApp.Name, true) == 0) {
return iApp;
}
}
return null;
}
and then I can change the subject like this:
IAppender appender = FindAppenderByName("SmtpAppender");
SmtpAppender smtpAppender = (SmtpAppender)appender;
smtpAppender.Subject = "An error occured trying to convert the values";
log.Error("Error message");
But this seems to be a bit too complicated since every time I send an error mail I first have to find the appender by name and I don't want to use a global IAppender object as well as that seems like bad practice to me.
Is there a way to use the user-specified error message as a subject or is there an extension method I could use?
My proposal is as follows :
Create a new class extending SmtpAppender
Override SendBuffer
Based on your LoggingEvent, dynamically change the base.Subject
public class CustomSmtpAppender : SmtpAppender
{
protected override void SendBuffer(LoggingEvent[] events)
{
PrepareSubject(events);
base.SendBuffer(events);
}
protected virtual void PrepareSubject(IEnumerable<LoggingEvent> events)
{
//here you can eval events and set base.Subject
}
}
I am running an aspnet core site on Linux using Kestrel. I have set up nlog to log to csv files. All is well in my Windows development environment, but when I run it on Linux I only get one entry in the log file. I turned on nlog tracing and found the following error in the output:
2016-09-09 07:22:46.2123 Error Error has been raised. Exception: System.IO.IOException: The file '/var/aspnetcore/CSWebSite/releases/20160909061254/logs/archives/own-log.20160908.csv' already exists.
at System.IO.UnixFileSystem.MoveFile(String sourceFullPath, String destFullPath)
at System.IO.File.Move(String sourceFileName, String destFileName)
at NLog.Targets.FileTarget.ArchiveByDate(String fileName, String pattern, LogEventInfo logEvent)
at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
at NLog.Targets.FileTarget.FlushCurrentFileWrites(String currentFileName, LogEventInfo firstLogEvent, MemoryStream ms, List`1 pendingContinuations)
2016-09-09 07:22:46.2123 Error Error has been raised. Exception: System.IO.IOException: The file '/var/aspnetcore/CSWebSite/releases/20160909061254/logs/archives/all-log.20160907.csv' already exists.
at System.IO.UnixFileSystem.MoveFile(String sourceFullPath, String destFullPath)
at System.IO.File.Move(String sourceFileName, String destFileName)
at NLog.Targets.FileTarget.ArchiveByDate(String fileName, String pattern, LogEventInfo logEvent)
at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
at NLog.Targets.FileTarget.FlushCurrentFileWrites(String currentFileName, LogEventInfo firstLogEvent, MemoryStream ms, List`1 pendingContinuations)
This is my nlog.config:
<?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>
<!--enable NLog.Web for ASP.NET Core-->
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<!-- https://github.com/nlog/nlog/wiki/File-target -->
<!-- http://stackoverflow.com/questions/34679727/use-nlog-in-asp-net-5-application -->
<target name="allfile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target name="allfile" xsi:type="File"
fileName="${basedir}/logs/all-logfile.csv"
archiveFileName="${basedir}/logs/archives/all-log.{#}.csv"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="28"
concurrentWrites="true"
keepFileOpen="false"
encoding="utf-8">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="logger" layout="${logger}" />
<column name="authtype" layout="${aspnet-user-authtype}" />
<column name="identity" layout="${aspnet-user-identity}" />
<column name="level" layout="${uppercase:${level}}" />
<column name="message" layout="${message} ${exception:format=ToString,StackTrace}" />
</layout>
</target>
</target>
<target name="ownfile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target name="ownfile" xsi:type="File"
fileName="${basedir}/logs/own-logfile.csv"
archiveFileName="${basedir}/logs/archives/own-log.{#}.csv"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="28"
concurrentWrites="true"
keepFileOpen="false"
encoding="utf-8">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="logger" layout="${logger}" />
<column name="authtype" layout="${aspnet-user-authtype}" />
<column name="identity" layout="${aspnet-user-identity}" />
<column name="level" layout="${uppercase:${level}}" />
<column name="message" layout="${message} ${exception:format=ToString,StackTrace}" />
</layout>
</target>
</target>
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Debug" writeTo="allfile" />
<!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Debug" writeTo="ownFile" />
</rules>
</nlog>
I have concurrent writes true and keepFileOpen false which seems necessary as kestrel forks multiple dotnet processes on Linux.
Is this a bug or is my configuration incorrect?
i just want to know that, what is use of log4net in application and how i`m gonna implement in c#.
i am done with some of the research that i am put under it.
public static class Logger
{
private static log4net.ILog Log { get; set; }
static Logger()
{
Log = log4net.LogManager.GetLogger(typeof(Logger));
}
public static void Error(object msg)
{
Log.Error(msg);
}
public static void Error(object msg, Exception ex)
{
Log.Error(msg, ex);
}
public static void Error(Exception ex)
{
Log.Error(ex.Message, ex);
}
public static void Info(object msg)
{
Log.Info(msg);
}
}
}
above is just a method that maintain log in separate file i just want to know in advance.
1.First you have to add a reference for log4net.dll if you havn't done that yet.
2.Then you have to add that statement above your stating class declaration. You can put it right bellow your using statements and outside of your class declaration:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
3.The class that you already have created.
4.Add that config to your configSections tag on your web.config/app.config:
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
That will allow you to add tags to configure your log.
5.Add that to your configuration tag on your web.config/app.config:
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender"/>
</root>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="./Log/log.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="'.'yyyy_MM_dd" />
<maxSizeRollBackups value="30" />
<maximumFileSize value="100MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date{yyyy/mm/dd HH:mm:ss,fff} %-5level %logger [%thread] %message %exception%newline"/>
</layout>
</appender>
</log4net>
6.Then you just have to call the methods on your Logger class.
If you want more information i'll sugest you to read the blog of that guy Log4Net Tutorials and Resources
Given this NLog config file:
<extensions>
<add assembly="Seq.Client.NLog"/>
</extensions>
<variable name="ServiceName" value="LO.Leads.Processor"/>
<targets async="true">
<target name="seq" xsi:type="Seq" serverUrl="http://mywebsite">
<property name="ThreadId" value="${threadid}" as="number" />
<property name="MachineName" value="${machinename}" />
</target>
<target name="file" xsi:type="File"
layout="${longdate}|${logger}|${level}|${threadid}|${message}"
fileName="C:\LogFiles\Leads\Processor\Processor.log"
archiveFileName="C:\LogFiles\Leads\Processor\Processor.{##}.log"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="45"
concurrentWrites="true"/>
<target name="debugger" xsi:type="Debugger"
layout="${logger}:${message}"/>
<target name="console" xsi:type="Console"
layout="${logger}:${level}:${threadid}:${message}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="seq" />
<logger name="*" minlevel="Error" writeTo="file" />
<logger name="*" minlevel="Debug" writeTo="debugger" />
<logger name="*" minlevel="Debug" writeTo="console" />
</rules>
and this code block:
public class Program
{
static Program()
{
LogManager.LogFactory = new NLogFactory();
}
public static void Main()
{
HostFactory.Run(x =>
{
x.Service<ProcessorAppHost>(s =>
{
s.ConstructUsing(name => new ProcessorAppHost());
s.WhenStarted(ah =>
{
ah.Init();
ah.Start("http://*:8088/");
"Message processor listening at http://localhost:8088 ".Print();
});
s.WhenStopped(ah => ah.Dispose());
});
x.RunAsLocalSystem();
x.SetDescription("Processes all messages for the Leads application.");
x.SetDisplayName("Leads Message Processor");
x.SetServiceName("LOLeadsProcessor");
});
}
}
//MQHandlers
mqServer.RegisterHandler<LeadInformation>(m =>
{
try
{
var db = container.Resolve<IFrontEndRepository>();
db.SaveMessage(m as Message);
}
catch (Exception exception)
{
_log.Error("This is the only text logged", exception);
}
return ServiceController.ExecuteMessage(m);
});
and this exception
and here is the output from the 'file' logger
2014-11-11 10:06:53.9179|ProcessorAppHost|Error|24|This is the only text logged
Any idea about how to get the overloaded version of Error to work correctly?
Thank you,
Stephen
${message} contains the message of your exception, which is "This is the only text logged".
Take a look at the exception layout renderer.
layout="${longdate}|${logger}|${level}|${threadid}|${message}|${exception}"
Have you told ServiceStack to use NLog anywhere? e.g. before initializing your AppHost:
LogManager.LogFactory = new ServiceStack.Logging.NLogger.NLogFactory();
new AppHost().Init();