started net logger implement getting example ejemplo c# nlog

c# - net - ¿Cómo registro un campo personalizado en NLog en la base de datos?



nlog winforms (4)

Actualmente uso NLog en muchos proyectos. En algunos, me conecto a una base de datos.

Esto es lo que me gustaría hacer:

CREATE TABLE [dbo].[NLogEntries]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Origin] [nvarchar](100) NOT NULL, [LogLevel] [nvarchar](20) NOT NULL, [Message] [nvarchar](3600) NOT NULL, [CreatedOn] [datetime] NOT NULL, [OrderId] [int] NULL --Custom field! )

Y NLog.config con este objetivo:

<target type="Database" name="database" connectionstring="Server=localhost;Database=NLog;Trusted_Connection=True;"> <commandText> INSERT INTO NLogEntries ([Origin], [Message], [LogLevel],[CreatedOn],[OrderId]) VALUES (@Origin,@Message,@LogLevel,@Date, @OrderId); </commandText> <parameter name="@Date" layout="${date}"/> <parameter name="@Origin" layout="${callsite}"/> <parameter name="@LogLevel" layout="${level}"/> <parameter name="@message" layout="${message}"/> <parameter name="@OrderId" layout="${orderId}"/> <!-- custom field! --> </target>

Y luego registre algo como esto:

var logger = LogManager.GetCurrentClassLogger(); var orderId = 123; logger.Debug("What is going on here", orderId);

¿Hay una buena manera de hacer esto y seguir usando NLog? ¿O tengo que rodar mi propio registrador y omitir NLog cuando estos son los requisitos?


Aquí hay un enfoque que usa GlobalContext.

Configuración:

<target type="Database" name="database" connectionstring="Server=localhost;Database=NLog;Trusted_Connection=True;"> <commandText> INSERT INTO NLogEntries ([Origin], [Message], [LogLevel],[CreatedOn],[OrderId]) VALUES (@Origin,@Message,@LogLevel,@Date, @OrderId); </commandText> <parameter name="@Date" layout="${date}"/> <parameter name="@Origin" layout="${callsite}"/> <parameter name="@LogLevel" layout="${level}"/> <parameter name="@message" layout="${message}"/> <parameter name="@OrderId" layout="${gdc:OrderId}"/> <!-- custom field! --> </target>

Llamar al sitio:

var logger = LogManager.GetCurrentClassLogger(); GlobalDiagnosticsContext.Set("OrderId",123); logger.Debug("What is going on here"); //If you use the logging configuration above, 123 will be logged to the OrderId column in your database

Con un poco más de esfuerzo, puede envolver el registrador NLog usando una de las técnicas que se ilustran here .

O bien, puede crear su propio objeto de "contexto" y escribir un LayoutRenderer personalizado para extraer los valores y escribirlos en el registro. LayourRenderers personalizados son fáciles de escribir. Puedes ver un ejemplo en mi primera respuesta a esta pregunta . Allí, le muestro cómo escribir su propio LayoutRenderer que agrega el valor actual de System.Diagnostics.Trace.CorrelationManager.ActivityId al mensaje de registro.


En lugar de utilizar GDC obsoleto, MDC, MDLC o contexto de eventos, es mejor utilizar EventProperties-Layout-Renderer que permita pasar propiedades personalizadas específicas para el evento.

LogEventInfo theEvent = new LogEventInfo(logLevel, "", message); theEvent.Properties["OrderId"] =orderId;` log.Log(theEvent); ... and in your NLog.config file: ${event-context:item=OrderId} -- obsolete ${event-properties:item=OrderId} -- renders OrderId



Si eso es todo lo que uno necesita, a partir de la versión 4.3.3 de NLog hay una manera más fácil de declarar y acceder a variables personalizadas. Cuidado: ninguna de estas soluciones es segura para subprocesos.

Agregue lo siguiente a NLog.config

<nlog ... <!-- optional, add some variables --> ... <variable name="myvarone" value="myvalue"/> <variable name="myvartwo" value=2/> ... </nlog>

Las variables pueden ser cambiadas / accedidas en el código por:

LogManager.Configuration.Variables["myvarone"] = "New Value" LogManager.Configuration.Variables["myvartwo"] = 2

Los valores se pueden referenciar en NLog.config:

"${var:myvarone}" -- renders "New Value" "${var:myvartwo}" -- renders 2

Como mencioné anteriormente, los objetos var y LogEventInfo son globales. Entonces, si se definen varias instancias, cambiar un valor cambiaría el valor para todas las instancias. Estoy muy interesado si alguien sabe una forma de declarar variables personalizadas por instancia para NLog.