Technik:NLog

Aus CoPlanner 11
Zur Navigation springenZur Suche springen
Die Druckversion wird nicht mehr unterstützt und kann Darstellungsfehler aufweisen. Bitte aktualisiere deine Browser-Lesezeichen und verwende stattdessen die Standard-Druckfunktion des Browsers.

In der NLog.Server.config bzw. NLog.Service.config lässt sich das Logging konfigurieren.

Prinzipiell kann hier mehr angepasst werden, aber die grundlegenden Eigenschaften beim Logging in eine Datei sind:

  • logDirectory: Verzeichnis ohne den Dateinamen, wo hingeloggt werden soll
  • fileName: Hier kann man den Dateinamen anpassen oder wenn man möchte auch den gesamten Pfad
  • archiveAboveSize: gibt an, ab welcher Dateigröße eine neue Datei geschrieben wird. Der Standard von 10000000 entspricht 10 MB.

Logging in die Datenbank

Verfügbar ab CoPlanner 11 Release 1 2026.

Wenn man in eine Datenbank loggen will, so kann man das auch in dieser Konfiguration machen.

Achtung!  Es gibt kein Housekeeping für das Logging in eine Datenbank. Darum muss man sich derzeit selber kümmern.



Beispiel NLog.Server.config für Logging in die Datenbank:

<?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"
      autoReload="true"
      internalLogLevel="Off"
      internalLogFile="C:\NLogInternal\CopServer_NLogInternal.txt"
      throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore" />
    <add assembly="CopServer" />
  </extensions>

  <variable name="logDirectory" value="Logs/" />
    
  <targets>
    <!-- console -->
    <target xsi:type="AsyncWrapper"
            name="consoleAsync"
            overflowAction="Grow">
      <target xsi:type="ColoredConsole"
              name="console"
              layout="${date:format=HH\:mm\:ss} ${message}">
        <highlight-row condition="level == LogLevel.Warn"
                       foregroundColor="Yellow"
        />
        <highlight-row condition="level == LogLevel.Error"
                       foregroundColor="Red"
        />
      </target>
    </target>
    
    <!-- database -->
    <target xsi:type="AsyncWrapper"
            name="generalFileAsync">
      <target xsi:type="Database"
              name="generalFile"
			  commandType="Text"
			  commandText="Insert into Serverlog_GeneralErrorAndWarning (Message, Level) values (@Message, @Level)"
			  connectionString ="Server=localhost;Initial Catalog=CopNlogDb;User=cop;password=cop;pooling=false; TrustServerCertificate=true; timeout=300">
              <parameter name="@level"          layout="${level}" />
			  <parameter name="@message"        layout="${message}" />
			  
      </target>
    </target>
    <target xsi:type="AsyncWrapper"
            name="commandsFileAsync">
      <target xsi:type="Database"
              name="commandsFile"
              commandType="Text"
			  commandText="Insert into Serverlog_Commands (Message, Level) values (@Message, @Level)"
			  connectionString ="Server=localhost;Initial Catalog=CopNlogDb;User=cop;password=cop;pooling=false; TrustServerCertificate=true; timeout=300">
              <parameter name="@level"          layout="${level}" />
			  <parameter name="@message"        layout="${message}" />
			  
      </target>
    </target>
    <target xsi:type="AsyncWrapper"
            name="formulaFileAsync">
      <target xsi:type="Database"
              name="formulaFile"
			  commandType="Text"
			  commandText="Insert into Serverlog_Formula (Message, Level) values (@Message, @Level)"
			  connectionString ="Server=localhost;Initial Catalog=CopNlogDb;User=cop;password=cop;pooling=false; TrustServerCertificate=true; timeout=300">
              <parameter name="@level"          layout="${level}" />
			  <parameter name="@message"        layout="${message}" />
			  
      </target>
    </target>
    <target xsi:type="AsyncWrapper"
            name="webApiFileAsync">
      <target xsi:type="Database"
              name="webApiFile"
			  commandType="Text"
			  commandText="Insert into Serverlog_Web (Message, Level, ip, TraceIdentifier, Userclaim_session, Userclaim_name, Userclaim_context, Longdate, Logger, Exception) values (@Message, @Level, @ip, @TraceIdentifier, @Userclaim_session, @Userclaim_name, @Userclaim_context, @Longdate, @Logger, @Exception)"
			  connectionString ="Server=localhost;Initial Catalog=CopNlogDb;User=cop;password=cop;pooling=false; TrustServerCertificate=true; timeout=300">
              <parameter name="@level"             layout="${level}" />
			  <parameter name="@message" 	       layout="${message}" />
			  <parameter name="@ip"  		       layout="${aspnet-request-ip}" />
			  <parameter name="@traceIdentifier"   layout="${aspnet-TraceIdentifier}" />		  
			  <parameter name="@userclaim_session" layout="${aspnet-user-claim:cop_session_id}" />
			  <parameter name="@userclaim_name"    layout="${aspnet-user-claim:name}" />
			  <parameter name="@userclaim_context" layout="${aspnet-user-claim:cop_session_context}" />
			  <parameter name="@longdate"          layout="${longdate}" />
			  <parameter name="@logger"        	   layout="${logger}" />
			  <parameter name="@exception"         layout="${exception:format=tostring}" />
			  
      </target>
    </target>
    <target xsi:type="AsyncWrapper"
        name="olapFileAsync">
		 <target xsi:type="Database"
				commandType="Text"
				commandText="Insert into Serverlog_Olap (Message, Level, ip, TraceIdentifier, Userclaim_session, Userclaim_name, Userclaim_context, Longdate, Logger, Exception) values (@Message, @Level, @ip, @TraceIdentifier, @Userclaim_session, @Userclaim_name, @Userclaim_context, @Longdate, @Logger, @Exception)"
			  connectionString ="Server=localhost;Initial Catalog=CopNlogDb;User=cop;password=cop;pooling=false; TrustServerCertificate=true; timeout=300">
              <parameter name="@level"             layout="${level}" />
			  <parameter name="@message" 	       layout="${message}" />
			  <parameter name="@ip"  		       layout="${aspnet-request-ip}" />
			  <parameter name="@traceIdentifier"   layout="${aspnet-TraceIdentifier}" />		  
			  <parameter name="@userclaim_session" layout="${aspnet-user-claim:cop_session_id}" />
			  <parameter name="@userclaim_name"    layout="${aspnet-user-claim:name}" />
			  <parameter name="@userclaim_context" layout="${aspnet-user-claim:cop_session_context}" />
			  <parameter name="@longdate"          layout="${longdate}" />
			  <parameter name="@logger"        	   layout="${logger}" />
			  <parameter name="@exception"         layout="${exception:format=tostring}" />
			  
      </target>
    </target>
  
    <!-- memories -->
    <target xsi:type="LimitedMemory"
            name="generalMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
    <target xsi:type="LimitedMemory"
            name="commandsMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
    <target xsi:type="LimitedMemory"
            name="formulaMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
  </targets>
  
  <rules>
    <logger name="consolelogger" writeTo="consoleAsync" final="true" />
    
    <logger name="generalfilelogger" writeTo="generalMemory" />
    <logger name="generalfilelogger" writeTo="generalFileAsync" final="true" />
    
    <logger name="commandsfilelogger" writeTo="commandsMemory" />
    <logger name="commandsfilelogger" writeTo="commandsFileAsync" final="true" />
    
    <logger name="formulafilelogger" writeTo="formulaMemory" />
    <logger name="formulafilelogger" writeTo="formulaFileAsync" final="true" />

    <logger name="Microsoft.AspNetCore.Hosting.Internal.WebHost" minlevel="Warn" writeTo="consoleAsync">
      <filters defaultAction="Log">
        <when condition="contains('${message}', '/health ') or contains('${message}', '/session/isalive ') or contains('${message}', 'Request finished in ')"
              action="Ignore"
        />
      </filters>
    </logger>
    <logger name="Microsoft.AspNetCore*" minlevel="Warn" writeTo="webApiFileAsync" final="true">
      <filters defaultAction="Log">
        <when condition="starts-with('${message}', 'An error occurred while trying to create an XmlSerializer for the type')"
              action="Ignore"
        />
      </filters>
    </logger>
    
    <logger name="AspNet.*" minlevel="Warn" writeTo="consoleAsync" />
    <logger name="AspNet.*" minlevel="Warn" writeTo="webApiFileAsync" final="true" />
    
    <logger name="System.Net.Http.HttpClient*" minlevel="Warn" writeTo="consoleAsync" />
    <logger name="System.Net.Http.HttpClient*" minlevel="Warn" writeTo="webApiFileAsync" final="true" />
    
    <logger name="Cop.Server.WebApi*" minlevel="Warn" writeTo="consoleAsync" />
    <logger name="Cop.Server.WebApi*" minlevel="Warn" writeTo="webApiFileAsync" final="true" />

    <logger name="Cop.Analyze.ConnectorOlap" writeTo="olapFileAsync" final="true" />

    <!--
    <logger name="*" minlevel="Info" writeTo="consoleAsync" />
    <logger name="*" minlevel="Info" writeTo="generalMemory" />
    <logger name="*" minlevel="Info" writeTo="generalFileAsync" final="true" />
    -->
  </rules>
</nlog>

Skript zum Erstellen der Tabellen für das Logging:

use [CopNlogDb]
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

  CREATE TABLE [dbo].[Serverlog_GeneralErrorAndWarning] (
	  [Id] [int] IDENTITY(1,1) NOT NULL,
	  [Level] [nvarchar](50) NULL,
	  [Message] [nvarchar](max) NULL,
    CONSTRAINT [PKGeneralErrorAndWarning] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

  CREATE TABLE [dbo].[Serverlog_Commands] (
	  [Id] [int] IDENTITY(1,1) NOT NULL,
	  [Level] [nvarchar](50) NULL,
	  [Message] [nvarchar](max) NULL,
    CONSTRAINT [PKCommands] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

  CREATE TABLE [dbo].[Serverlog_Formula] (
	  [Id] [int] IDENTITY(1,1) NOT NULL,
	  [Level] [nvarchar](50) NULL,
	  [Message] [nvarchar](max) NULL,
    CONSTRAINT [PKFormula] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

  CREATE TABLE [dbo].[Serverlog_Web] (
	  [Id] [int] IDENTITY(1,1) NOT NULL,
	  [Level] [nvarchar](50) NULL,
	  [Message] [nvarchar](max) NULL,
	  [Ip] [nvarchar](150) NULL,
	  [TraceIdentifier] [nvarchar](max) NULL,
	  [Userclaim_session] [nvarchar](max) NULL,
	  [Userclaim_name] [nvarchar](max) NULL,
	  [Userclaim_context] [nvarchar](max) NULL,
	  [Longdate] [nvarchar](100) NULL,
	  [Logger] [nvarchar](max) NULL,
	  [Exception] [nvarchar](max) NULL,
    CONSTRAINT [PKWeb] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

  CREATE TABLE [dbo].[Serverlog_Olap] (
	  [Id] [int] IDENTITY(1,1) NOT NULL,
	  [Level] [nvarchar](50) NULL,
	  [Message] [nvarchar](max) NULL,
	  [Ip] [nvarchar](150) NULL,
	  [TraceIdentifier] [nvarchar](max) NULL,
	  [Userclaim_session] [nvarchar](max) NULL,
	  [Userclaim_name] [nvarchar](max) NULL,
	  [Userclaim_context] [nvarchar](max) NULL,
	  [Longdate] [nvarchar](100) NULL,
	  [Logger] [nvarchar](max) NULL,
	  [Exception] [nvarchar](max) NULL,
    CONSTRAINT [PKOlap] PRIMARY KEY CLUSTERED ([Id] ASC)
      WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]


Logging mit Seq

Verfügbar ab CoPlanner 11 Release 2 2026.

Beispieldefinition für das Logging mit Seq.

<?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"
      autoReload="true"
      internalLogLevel="Off"
      internalLogFile="C:\NLogInternal\CopServer_NLogInternal.txt"
      throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore" />
    <add assembly="CopServer" />
	<add assembly="NLog.Targets.Seq"/>
  </extensions>

  <variable name="logDirectory" value="Logs/" />
    
  <targets>
  
	<!-- Seq -->
	<target xsi:type="AsyncWrapper"
            name="seqToolAsync">
			<target xsi:type="Seq"
					name="seqTool"
					serverUrl="http://localhost:5341"
					apiKey="">
				<property name="Environment" value="${environment:variable=ASPNETCORE_ENVIRONMENT}" />
				<!-- <property name="CorrelationId" layout="${aspnet-TraceIdentifier}" /> -->
				<!-- <property name="CorrelationId" value="${aspnet-activity-id}" /> -->
				<!-- <property name="user" value="${aspnet-user-identity}" /> -->
				<!-- <property name="RequestUrl" value="${aspnet-request-url}" /> -->
				<!-- <property name="Method" value="${aspnet-request-method}" /> -->
				<!-- <property name="Status" value="${aspnet-response-statuscode}" /> -->
				<!-- <property name="Area" value="${logger}" /> -->
				<property name="ThreadId" value="${threadid}" />
			</target>
	</target>
	
    <!-- console -->
    <target xsi:type="AsyncWrapper"
            name="consoleAsync"
            overflowAction="Grow">
      <target xsi:type="ColoredConsole"
              name="console"
              layout="${date:format=HH\:mm\:ss} ${message}">
        <highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
        <highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
      </target>
    </target>
	
	 <!-- files -->
    <target xsi:type="AsyncWrapper"
            name="generalFileAsync"
            overflowAction="Grow">
      <target xsi:type="File"
              name="generalFile"
              layout="[${aspnet-TraceIdentifier}]	${replace-newlines:replacement=<CR>:${message}}"
              fileName="${var:logDirectory}Serverlog_GeneralErrorAndWarning.txt"
              archiveAboveSize="10000000"
              archiveNumbering="DateAndSequence"
              archiveDateFormat="yyyyMMddHHmmss"
              enableArchiveFileCompression="true"
              keepFileOpen="true"
              concurrentWrites="false"
              openFileCacheTimeout="30"
      />
    </target>
    <target xsi:type="AsyncWrapper"
            name="commandsFileAsync"
            overflowAction="Grow">
      <target xsi:type="File"
              name="commandsFile"
              layout="[${aspnet-TraceIdentifier}]	${replace-newlines:replacement=<CR>:${message}}"
              fileName="${var:logDirectory}Serverlog_Commands.txt"
              archiveAboveSize="10000000"
              archiveNumbering="DateAndSequence"
              archiveDateFormat="yyyyMMddHHmmss"
              enableArchiveFileCompression="true"
              keepFileOpen="true"
              concurrentWrites="false"
              openFileCacheTimeout="30"
      />
    </target>
    <target xsi:type="AsyncWrapper"
            name="formulaFileAsync"
            overflowAction="Grow">
      <target xsi:type="File"
              name="formulaFile"
              layout="[${aspnet-TraceIdentifier}]	${replace-newlines:replacement=<CR>:${message}}"
              fileName="${var:logDirectory}Serverlog_Formula.txt"
              archiveAboveSize="10000000"
              archiveNumbering="DateAndSequence"
              archiveDateFormat="yyyyMMddHHmmss"
              enableArchiveFileCompression="true"
              keepFileOpen="true"
              concurrentWrites="false"
              openFileCacheTimeout="30"
      />
    </target>
    <target xsi:type="AsyncWrapper"
            name="webApiFileAsync"
            overflowAction="Grow">
      <target xsi:type="File"
              name="webApiFile"
              layout="[${aspnet-TraceIdentifier}]	[${aspnet-request-ip}]	[${level:uppercase=true}]	[${aspnet-user-claim:cop_session_id}|${aspnet-user-claim:name}]	${longdate}	${logger}	${message} ${exception:format=tostring}"
              fileName="${var:logDirectory}Serverlog_WebApi.txt"
              archiveAboveSize="10000000"
              archiveNumbering="DateAndSequence"
              archiveDateFormat="yyyyMMddHHmmss"
              enableArchiveFileCompression="true"
              keepFileOpen="true"
              concurrentWrites="false"
              openFileCacheTimeout="30"
      />
    </target>
    <target xsi:type="AsyncWrapper"
        name="olapFileAsync"
        overflowAction="Grow">
      <target xsi:type="File"
              name="olapFile"
              layout="[${aspnet-TraceIdentifier}]	[${level:uppercase=true}]	[${aspnet-user-claim:cop_session_id}|${aspnet-user-claim:name}]	${longdate}	${logger}	${message} ${exception:format=tostring}"
              fileName="${var:logDirectory}Serverlog_Olap.txt"
              archiveAboveSize="10000000"
              archiveNumbering="DateAndSequence"
              archiveDateFormat="yyyyMMddHHmmss"
              enableArchiveFileCompression="true"
              keepFileOpen="true"
              concurrentWrites="false"
              openFileCacheTimeout="30"
      />
    </target>
    
    <!-- memories -->
    <target xsi:type="LimitedMemory"
            name="generalMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
    <target xsi:type="LimitedMemory"
            name="commandsMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
    <target xsi:type="LimitedMemory"
            name="formulaMemory"
            layout="${replace-newlines:${message}}"
            maxLogsCount="1000"
    />
  </targets>
  
  <rules>
    <logger name="consolelogger" writeTo="consoleAsync" final="true" />
    <logger name="Microsoft.AspNetCore.Hosting.Internal.WebHost" minlevel="Warn" writeTo="consoleAsync">
      <filters defaultAction="Log">
        <when condition="contains('${message}', '/health ') or contains('${message}', '/session/isalive ') or contains('${message}', 'Request finished in ')" action="Ignore" />
      </filters>
    </logger>
    <logger name="AspNet.*" minlevel="Warn" writeTo="consoleAsync" />
    <logger name="System.Net.Http.HttpClient*" minlevel="Warn" writeTo="consoleAsync" />
    <logger name="Cop.Server.WebApi*" minlevel="Warn" writeTo="consoleAsync" />

    <logger name="generalfilelogger" writeTo="generalMemory" />
    <logger name="generalfilelogger" writeTo="generalFileAsync" final="true" />
    <logger name="commandsfilelogger" writeTo="commandsMemory" />
    <logger name="commandsfilelogger" writeTo="commandsFileAsync" final="true" />
    <logger name="formulafilelogger" writeTo="formulaMemory" />
    <logger name="formulafilelogger" writeTo="formulaFileAsync" final="true" />

	<logger name="Microsoft.AspNetCore*" minlevel="Warn" writeTo="webApiFileAsync" >
      <filters defaultAction="Log">
        <when condition="starts-with('${message}', 'An error occurred while trying to create an XmlSerializer for the type')" action="Ignore" />
      </filters>
    </logger>

	<logger name="AspNet.*" minlevel="Warn" writeTo="webApiFileAsync" />
	<logger name="System.Net.Http.HttpClient*" minlevel="Warn" writeTo="webApiFileAsync" />
	<logger name="Cop.Server.WebApi*" minlevel="Warn" writeTo="webApiFileAsync" />
	<logger name="Cop.Analyze.ConnectorOlap" writeTo="olapFileAsync" />

	<!-- <logger name="copserverlogger" minlevel="Info" writeTo="seqToolAsync" final="true" /> -->
	<logger name="*" minlevel="Info" writeTo="seqToolAsync" final="true">
		<filters defaultAction="Log">
			<when condition="contains('${message}', '/health ') or contains('${message}', '/session/isalive ')" action="Ignore"/>
			<when condition="starts-with('${message}', 'An error occurred while trying to create an XmlSerializer for the type')" action="Ignore" />
		</filters>
	</logger>
  </rules>
</nlog>