将二进制数据写入NLog数据库目标

时间:2014-01-08 20:42:16

标签: c# .net nlog

我试图通过NLog数据库目标将压缩数据写入日志表。记录器失败并显示以下消息:

“不允许从数据类型nvarchar到varbinary(max)的隐式转换。使用CONVERT函数运行此查询。”

数据库列定义为varbinary(max),添加到LogEventInfo属性的数据是字节数组。我没有看到NLog布局渲染器,我可以告诉NLog我发送二进制数据。有什么想法吗?

提前致谢。

*** 请求的信息 ** * *

这是我的NLog目标

  <target type="Database" name="atom_db" connectionstring="Server=MYSERVER;Database=MYDB;Trusted_Connection=True;">
    <dbprovider>mssql</dbprovider>
    <commandText>insert into TAtomLog ([requestdt], [sessionid], [clientip], [clientuser], [application], [method], [data]) values (@RequestDt, @SessionId, @ClientIP, @ClientUser, @SessionType, @Method, @Data);</commandText>
    <parameter name="@RequestDt" layout="${event-context:item=RequestDt}"/>
    <parameter name="@SessionId" layout="${event-context:item=${guid:SessionId}"/>
    <parameter name="@ClientIP" layout="${event-context:item=ClientIP"/>
    <parameter name="@ClientUser" layout="${event-context:item=ClientUser"/>
    <parameter name="@SessionType" layout="${event-context:item=SessionType"/>
    <parameter name="@Method" layout="${event-context:item=Method"/>
    <parameter name="@Data" layout="${event-context:item=Data"/>
  </target>

这是我的C#代码,它创建LogEventInfo并调用Logger。对StringCompressor.CompressString的调用返回“byte []”

    var ev = new LogEventInfo(LogLevel.Info, AtomLogger.LoggerName, string.Empty);
    ev.Properties.Add("RequestDt", DateTime.Now);
    ev.Properties.Add("ClientIP", clientip);
    ev.Properties.Add("ClientUser", clientuser);
    ev.Properties.Add("SessionId", sessionid);
    ev.Properties.Add("SessionType", sessiontype);
    ev.Properties.Add("Method", new StackFrame(1).GetMethod().Name);
    ev.Properties.Add("Data", StringCompressor.CompressString(data));
    AtomLogger.GetDBLoggerInstance().Log(ev);

1 个答案:

答案 0 :(得分:2)

您可以将二进制数据作为十六进制字符串传递,并使用convert函数将字符串转换为二进制:


    var buffer = new byte[]; // your binary buffer
    var stringToPassInDb = BitConverter.ToString(buffer).Replace("-", string.Empty);
    var logInfo = new LogEventInfo(LogLevel.Info, null, null);
    logInfo.Properties["Data"] = stringToPassInDb;
    _logger.Log(logInfo);

和Nlog.config中的sql命令应该是类似的:

  <commandText>
    insert into dbo.Log
    (
    log_date, log_level, log_message,
    log_machine_name, log_user_name,
    entity_id, command, data
    )
    values
    (
    @time_stamp, @level, @message,
    @machinename, @user_name,
    @entity_id, @command, convert(varbinary(max), @data, 2)
    );
  </commandText>
  <parameter name="@time_stamp" layout="${date:universalTime=true:format=yyyyMMdd HH\:mm\:ss"/>
  <parameter name="@level" layout="${level}"/>
  <parameter name="@message" layout="${message}"/>
  <parameter name="@machinename" layout="${machinename}"/>
  <parameter name="@user_name" layout="${windows-identity:domain=true}"/>
  <parameter name="@entity_id" layout="${event-properties:item=EntityId}" />
  <parameter name="@command" layout="${event-properties:item=Command}" />
  <parameter name="@data" layout="${event-properties:item=Data}" />