user610217
user610217

Reputation:

NLog/ SQLite with .NET Core

I'm trying to log to an SQLite DB from NLog in a .NET Core 2.1 web application project.

I have a config set up like this:

<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xsi:schemaLocation="NLog NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="true"
      internalLogIncludeTimestamp="true"
      internalLogFile="nlog-internal.log"
      internalLogLevel="Error">
    <targets>
        <target xsi:type="Database"
                name="database"
                commandType="Text"
                dbProvider="Microsoft.Data.Sqlite.SqliteConnection, Microsoft.Data.Sqlite"
                connectionString="${var:appDbConnectionString}"
                commandText="Layout">
            <commandText>
                insert into Logs (TimestampUtc, Application, Level, Message, Exception, Logger)
                values (@timestamputc, @application, @level, @message, @exception, @logger);
            </commandText>
            <parameter name="@timestamputc" layout="${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss.fff}" />
            <parameter name="@application" layout="My App" />
            <parameter name="@level" layout="${level}" />
            <parameter name="@message" layout="${message}" />
            <parameter name="@exception" layout="${exception:format=tostring}" />
            <parameter name="@logger" layout="${logger}" />
        </target>
    </targets>
    <rules>
        <logger name="MyApp.*" minlevel="Info" writeTo="database" />
        <logger name="*" minlevel="Warn" writeTo="database" />
    </rules>
</nlog>

...my SQLite table is set up like this:

CREATE TABLE "Logs" ( 
    `Id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
    `TimestampUtc` TEXT NOT NULL, 
    `Application` TEXT NOT NULL, 
    `Level` TEXT NOT NULL, 
    `Message` TEXT NOT NULL, 
    `Logger` TEXT NOT NULL, 
    `Exception` TEXT )

...but when I try to log something, I get the following exception:

System.AggregateException
  HResult=0x80131500
  Message=An error occurred while writing to logger(s).
  Source=Microsoft.Extensions.Logging
  StackTrace:
   at Microsoft.Extensions.Logging.Logger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
   at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args)
   at Microsoft.Extensions.Logging.LoggerExtensions.LogError(ILogger logger, String message, Object[] args)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.OnErrorDataReceived(String errorData)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.<>c__DisplayClass24_0.<ConnectToInputOutputStreams>b__1(Object sender, DataReceivedEventArgs evt)
   at System.Diagnostics.Process.ErrorReadNotifyUser(String data)
   at System.Diagnostics.AsyncStreamReader.FlushMessageQueue(Boolean rethrowInNewThread)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Diagnostics.AsyncStreamReader.<>c.<FlushMessageQueue>b__17_0(Object edi)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Inner Exception 1:
SqliteException: SQLite Error 19: 'NOT NULL constraint failed: Logs.TimestampUtc'.

The message seems to indicate that I'm trying to insert a null value into the TimestampUtc field, but that shouldn't be the case; according to all the documentation I've read, the layout string for the timestamp parameter looks correct and should not be generating a null value.

Is my format string wrong? Is my parameter syntax wrong? Do I need to do something I'm not thinking of to my query to get this to work?

Upvotes: 3

Views: 1770

Answers (1)

Niels R.
Niels R.

Reputation: 7364

As an alternative you could use System.Data.SQLite (NuGet) instead.

nlog.config snippet:

<target xsi:type="Database"
            name="db"
            dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite"
            connectionString="Data Source=database.db;">
   ...
</target>

Upvotes: 4

Related Questions