我目前在许多项目中使用NLog.在某些情况下,我登录到数据库.
这是我想做的事情:
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!
)
Run Code Online (Sandbox Code Playgroud)
NLog.config和这个目标:
<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>
Run Code Online (Sandbox Code Playgroud)
然后记录这样的事情:
var logger = LogManager.GetCurrentClassLogger();
var orderId = 123;
logger.Debug("What is going on here", orderId);
Run Code Online (Sandbox Code Playgroud)
有没有一个很好的方法来做这个并继续使用NLog?或者,当这些是要求时,我是否必须滚动我自己的记录器并跳过NLog?
MiF*_*vil 82
而不是使用GDC(用于全局静态数据并且在并发日志记录上失败),最好使用 EventProperties-Layout-Renderer ,它允许传递特定于事件的自定义属性
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
Run Code Online (Sandbox Code Playgroud)
wag*_*ghe 35
以下是使用GlobalContext的一种方法.
组态:
<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>
Run Code Online (Sandbox Code Playgroud)
通话网站:
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
Run Code Online (Sandbox Code Playgroud)
只需稍加努力,您就可以使用此处所示的技术之一包装NLog记录器.
或者,您可以创建自己的"上下文"对象并编写自定义LayoutRenderer以从中提取值并将其写入日志.自定义LayourRenderers易于编写.你可以在我对这个问题的第一个答案中看到一个例子.在那里,我展示了如何编写自己的LayoutRenderer,它将System.Diagnostics.Trace.CorrelationManager.ActivityId的当前值附加到日志消息中.
如果这是所有需要的,从NLog版本4.3.3开始,有一种更简单的方式来声明和访问自定义变量. 注意: 这些解决方案都不是线程安全的.
将以下内容添加到NLog.config中
<nlog ...
<!-- optional, add some variables -->
...
<variable name="myvarone" value="myvalue"/>
<variable name="myvartwo" value=2/>
...
</nlog>
Run Code Online (Sandbox Code Playgroud)
可以通过以下代码更改/访问变量:
LogManager.Configuration.Variables["myvarone"] = "New Value"
LogManager.Configuration.Variables["myvartwo"] = 2
Run Code Online (Sandbox Code Playgroud)
可以在NLog.config中引用这些值:
"${var:myvarone}" -- renders "New Value"
"${var:myvartwo}" -- renders 2
Run Code Online (Sandbox Code Playgroud)
正如我上面提到的,var和LogEventInfo对象是全局的.因此,如果定义了多个实例,则更改值将更改所有实例的值.如果有人知道为NLog声明每个实例自定义变量的方法,我会很感兴趣.
使用NLog 4.6.3,这现在变得更容易且线程安全!
呼叫
int orderId = 123;
logger.WithProperty("MyOrderId", orderId).Info("This is my message!");
Run Code Online (Sandbox Code Playgroud)
配置:
<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}" dbType="DbType.Date"/>
<parameter name="@Origin" layout="${callsite}"/>
<parameter name="@LogLevel" layout="${level}"/>
<parameter name="@message" layout="${message}"/>
<parameter name="@OrderId" layout="${event-properties:MyOrderId}" dbType="DbType.Int32"/> <!-- custom field! Note also the DB Type -->
</target>
Run Code Online (Sandbox Code Playgroud)
注意,NLog 4.6还支持DbType-请参阅https://nlog-project.org/2019/03/20/nlog-4-6-is-live.html