I’d like to use NLog to log to a RavenDb database. There is apparently no existing NLog Target for this (according to this, and searches), so I’m attempting to write my own. I keep getting in conflict with the RavenDb client’s own NLog config, and I can’t work out how to fix this. Here’s my Target:
namespace NLog.RavenDb
{
class LogEntry
{
public string Id { get; set; }
public Exception Exception { get; set; }
public string LogLevel { get; set; }
public StackTrace StackTrace { get; set; }
public DateTimeOffset TimeStamp { get; set; }
public string Message { get; set; }
}
public class RavenDbTarget : NLog.Targets.TargetWithLayout
{
public static IDocumentStore Store { get; set; }
protected override void Write(LogEventInfo logEvent)
{
if (Store == null)
{
const string noStoreWarning = "No Document Store set for the RavenDb Log target";
Debug.WriteLine(noStoreWarning);
return;
}
LogEntry entry = new LogEntry
{
Exception = logEvent.Exception,
LogLevel = logEvent.Level.Name,
Message = logEvent.FormattedMessage,
StackTrace = logEvent.StackTrace,
TimeStamp = new DateTimeOffset(logEvent.TimeStamp)
};
using (var session = Store.OpenSession())
{
session.Store(entry);
session.SaveChanges();
}
}
}
}
And here’s how I can get it to work with a SimpleConfigurator:
RavenDbTarget.Store = new DocumentStore { Url = "http://localhost:8080/" };
RavenDbTarget.Store.Initialize();
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(new RavenDbTarget());
Logger logger = NLog.LogManager.GetLogger("Any");
logger.Info("Hi");
However, NLog.config is used by RavenDb too, so when I put references to my Target in there , it throws an exception at Store.Initialize(). Here’s what I tried in NLog.config (NLog.RavenDb is the name of my library project containing the RavenDb Target):
<?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.RavenDb"/>
</extensions>
<targets>
<target xsi:type="NLog.RavenDb.RavenDbTarget" name="Raven"/>
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger minlevel="Trace" name="Any" writeTo="Raven" />
</rules>
</nlog>
How can I make my NLog.config file play nice with RavenDb’s use of it?
Found it. I missed the Target attribute on my target class as shown here.
The name parameter you pass to the Target attribute is the one you reference as “type” in your config file:
Now NLog picks up NLog.config automatically, and I don’t need any extra config code. Here’s the contents of my test console app’s main method now: