【问题标题】:Logs do not get saved into Logs table日志不会保存到日志表中
【发布时间】:2017-10-23 10:08:00
【问题描述】:

我正在尝试将从应用程序收到的任何日志保存到我的数据库中的日志表中,到目前为止,没有任何内容被保存。我正在使用 Log4net 和 AdoNetAppender 将日志保存到我的 SQL Server 表中。此代码位于我的应用程序服务器端的 Web API 项目中。

我将日志设置如下:

1) 在我的 Web.Config 中设置 XML:

<log4net>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1" />
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=token" />
      <connectionString value="data source=db;Initial Catalog=dbname;Trusted_Connection=True;" providerName="System.Data.SqlClient" />
      <commandText value="dbo.procLogs_Insert" />
      <commandType value="StoredProcedure" />
      <parameter>
        <parameterName value="@log_timestamp" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_recordNum" />
        <dbType value="Int32" />
        <size value="32" />
        <layout type="log4net.Layout.RawPropertyLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_computerName" />
        <dbType value="String" />
        <size value="128" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%X{machine}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_processTimeStamp" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_group" />
        <dbType value="StringFixedLength" />
        <size value="1" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_type" />
        <dbType value="StringFixedLength" />
        <size value="1" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_eventId" />
        <dbType value="Int32" />
        <size value="32" />
        <layout type="log4net.Layout.RawPropertyLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_userId" />
        <dbType value="Int32" />
        <size value="32" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%identity" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_line" />
        <dbType value="Int32" />
        <size value="32" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%line" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_description" />
        <dbType value="AnsiString" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message%newline %exception" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_source" />
        <dbType value="AnsiString" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%file" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_data" />
        <dbType value="AnsiString" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_addTimeStamp" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_deviceId" />
        <dbType value="StringFixedLength" />
        <size value="10" />
        <layout type="log4net.Layout.PatternLayout" />
      </parameter>
    </appender>
    <appender name="asyncForwarder" type="Log4Net.Async.AsyncForwardingAppender,Log4Net.Async">
      <appender-ref ref="AdoNetAppender" />
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="asyncForwarder" />
    </root>
  </log4net>

2) 这是我的 Global.asax.cs 中的代码:

public class WebApiApplication : System.Web.HttpApplication
{
    private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    protected void Application_Start()
    {
        XmlConfigurator.Configure();
        _log.Info("Service Started");
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();
    }
}

3) 将存储过程添加到数据库中:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE dbo.procLogs_Insert 
  @log_timestamp datetime, 
  @log_recordNum int, 
  @log_computerName varchar(128), 
  @log_processTimeStamp datetime, 
  @log_group char(1), 
  @log_type char(1), 
  @log_eventId int, 
  @log_userId varchar(128), 
  @log_line int, 
  @log_description text, 
  @log_source text, 
  @log_data text, 
  @log_addTimeStamp datetime, 
  @log_deviceId char(10)
AS
BEGIN
    SET NOCOUNT ON;

  insert into dbo.BS_ApplicationLogs(LogTimestamp, RecordNum, ComputerName, ProcessTimestamp, LogGroup, [Type],EventId,UserId,Line,[Description],[Source],[Data],AddTimestamp,DeviceID)
  values (@log_timestamp,  @log_recordNum, @log_computerName, @log_processTimeStamp, @log_group, @log_type, @log_eventId, @log_userId, @log_line,@log_description,@log_source,@log_data,@log_addTimeStamp,@log_deviceId)

END
GO

问题:这个存储过程应该保存在SSMS的什么地方?当我保存存储过程时,它会自动将其默认为 Documents\SSMS 但我想将其保存在 DB/Programmability/StoredProcedures 文件夹下,但我在那里看不到它。但是,我确实成功执行了存储过程,没有任何错误。

4) 将日志添加到我的应用项目中 global.asax.cs 文件之外的其他文件。 Log4Net 也知道记录这些吗?

所以是的,我不确定我做错了什么,并且没有任何内容记录到我在 SQL Server 中的表中。我是否错过了设置 Log4Net 的过程中的一个步骤?

编辑:内部调试器说:

log4net: Created Appender [AdoNetAppender]
log4net: Created Appender [asyncForwarder]
log4net: Adding appender named [asyncForwarder] to logger [root].
log4net: Hierarchy Threshold []
log4net:ERROR [AdoNetAppender] ErrorCode: GenericFailure. Exception while writing to database
System.ArgumentNullException: Key cannot be null.
Parameter name: key
   at System.Collections.Hashtable.get_Item(Object key)
   at log4net.Util.PropertiesDictionary.get_Item(String key)
   at log4net.Core.LoggingEvent.LookupProperty(String key)
   at log4net.Layout.RawPropertyLayout.Format(LoggingEvent loggingEvent)
   at log4net.Appender.AdoNetAppenderParameter.FormatValue(IDbCommand command, LoggingEvent loggingEvent)
   at log4net.Appender.AdoNetAppender.SendBuffer(IDbTransaction dbTran, LoggingEvent[] events)
   at log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent[] events)

什么键?

【问题讨论】:

  • 将存储过程保存到文件是不相关的。您需要确保您确实执行在 SQL 数据库中创建存储过程的 sql 命令。 (应该在 SSMS 中的 Programmability/Stored Procedures 下显示)
  • @sgmoore 我可以执行存储过程,但它仍然无法保存到数据库。你知道我是否遗漏了上述代码中的任何步骤或配置吗?
  • 您的问题不是很清楚,但有一点是错误的,您的 log4net 配置似乎需要一个存储过程 'dbo.procLog_Insert',而您的 SP 被称为 'dbo.procLogs_Insert'。此外,如果您启用 log4net 内部日志记录,您可能会获得更多关于发生了什么的线索。
  • @Joe Ohh,好消息!让我解决这个问题,看看它是否有帮助!如何启用 Log4Net 内部日志记录?谢谢!
  • @Euridice01 - 谷歌有许多关于启用 log4net 内部调试的建议,包括:stackoverflow.com/questions/756125/…

标签: c# sql-server asp.net-web-api log4net log4net-appender


【解决方案1】:

3) 听起来您已经创建了存储过程,但它最终在 Master 数据库中(Master/Programmability/StoredProcedures)。

您应该选择 DropDownList 并从 Master 更改为您的 DB,或者您可以在存储的 proc 之前使用语法 USE YourDB 并单击 Execute 按钮:

USE YourDB

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE dbo.procLogs_Insert 
  @log_timestamp datetime, 
  @log_recordNum int, 
  @log_computerName varchar(128), 
  @log_processTimeStamp datetime, 
  @log_group char(1), 
  @log_type char(1), 
  @log_eventId int, 
  @log_userId varchar(128), 
  @log_line int, 
  @log_description text, 
  @log_source text, 
  @log_data text, 
  @log_addTimeStamp datetime, 
  @log_deviceId char(10)
AS
BEGIN
    SET NOCOUNT ON;

  insert into dbo.BS_ApplicationLogs(LogTimestamp, RecordNum, ComputerName, ProcessTimestamp, LogGroup, [Type],EventId,UserId,Line,[Description],[Source],[Data],AddTimestamp,DeviceID)
  values (@log_timestamp,  @log_recordNum, @log_computerName, @log_processTimeStamp, @log_group, @log_type, @log_eventId, @log_userId, @log_line,@log_description,@log_source,@log_data,@log_addTimeStamp,@log_deviceId)

END
GO

【讨论】:

    【解决方案2】:

    这是我拥有的一个文件,它可以写入 MS SQL 服务器

    它指的是用户定义的属性 %property{xxx},在这样的代码中填充

    GlobalContext.Properties["user"] = Environment.UserName;
    

    也许你可以用它来替换你的一些属性,以确定是哪一个导致了问题

    <appender name="AppenderDB" type="log4net.Appender.AdoNetAppender">
    
    <bufferSize value="0" />
    <reconnectOnError value="true" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral" />
    <connectionString value="Data Source=MYDB\DB;Initial Catalog=XXX;Integrated Security=True;" />    
    <commandText value="EXECUTE WriteLogEntry @time, @recipeName, @userId, @timeSeries, @loadTimeMs" />
    
    <parameter>
      <parameterName value="@time" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.RawUtcTimeStampLayout" />
    </parameter>
    
    
    <parameter>
      <parameterName value="@recipeName" />
      <dbType value="String" />
      <size value="1024" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{recipeName}" />
      </layout>
    </parameter>
    
    <parameter>
      <parameterName value="@userId" />
      <dbType value="String" />
      <size value="20" />
      <layout type="log4net.Layout.PatternLayout" value="%property{user}"/>
    </parameter>
    <parameter>
      <parameterName value="@timeSeries" />
      <dbType value="String" />
      <size value="1024" />
      <layout type="log4net.Layout.PatternLayout" value="%property{timeSeries}"/>
    </parameter>
    
    <parameter>
      <parameterName value="@loadTimeMs" />
      <dbType value="Int32" />
      <size value="50" />
      <layout type="log4net.Layout.PatternLayout" value="%property{loadTimeMs}"/>
    </parameter>
    

    `

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 2017-07-10
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      相关资源
      最近更新 更多