【问题标题】:Best practice(s) for on screen real-time log viewer for log4net [closed]log4net 屏幕实时日志查看器的最佳实践 [关闭]
【发布时间】:2010-10-18 00:01:12
【问题描述】:

我有一个使用 log4net 进行日志记录功能的多线程 C# 应用程序。主要是 RollingFileAppender。

我想为用户提供在“应用程序日志”窗口中查看应用程序活动的功能。这将包括一个列表视图(详细信息模式)、一个网格或类似的东西。

我正在寻找最好的方法来做到这一点。到目前为止,我唯一的解决方案是设置一个 UDP 附加程序并创建一个特殊的线程来侦听并将所有消息转发到 UI。

我还研究了创建一个“包装器”的可能性,它既可以写入 UI,也可以使用 log4net 记录消息...嗯。

非常感谢您的帮助。

【问题讨论】:

    标签: c# logging log4net


    【解决方案1】:

    如果您愿意依赖其他程序,您可以使用来自 Sysinternals 的 dbgview。这将显示使用Debug.WriteLine() 方法记录的任何内容。我认为OutputDebugStringAppender 会这样做,但我没有使用过 Log4Net,所以我不能确定。

    【讨论】:

    • 您也可以将 log4net 发送到跟踪输出。
    【解决方案2】:

    您需要在此窗口中查看持久化的日志数据吗?如果是这样,我建议登录到数据库。这样log4net就可以不受客户端的干扰,客户端可以以非锁定的方式从数据库中读取日志数据。

    如果您不想/拥有 Express 或完整服务器,您可以使用 SQL Server Compact 版本。

    使用内置的 log4net AdoNetAdapter 记录到数据库。

    【讨论】:

      【解决方案3】:

      我同意彼得·利勒沃德的观点。这是一个简单的示例,说明如何通过动态设置日志记录的详细程度从控制台应用程序记录到数据库

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using log4net;
      using log4net.Config;
      using NUnit.Framework;
      
      namespace ExampleConsoleApplication
      {
          [TestFixture]
          class TestClass
          {
      
          //private static readonly ILog logger =
          //     LogManager.GetLogger ( typeof ( TestClass ) );
      
          private static readonly log4net.ILog logger = log4net.LogManager.GetLogger ( System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType );
      
              static void Main ( string[] args )
              {
      
                  Console.WriteLine ( " START " );
                  #region LoggerUsage
                  DOMConfigurator.Configure (); //tis configures the logger 
                  logger.Debug ( "Here is a debug log." );
                  logger.Info ( "... and an Info log." );
                  logger.Warn ( "... and a warning." );
                  logger.Error ( "... and an error." );
                  logger.Fatal ( "... and a fatal error." );
      
                  #endregion LoggerUsage
                  TestClass objTestClass = new TestClass();
                  objTestClass.TestMethodNameOK ();
                  objTestClass.TestMethodNameNOK ();
      
                  Console.WriteLine ( " END HIT A KEY TO EXIT " );
                  Console.ReadLine ();
                  } //eof method 
      
              [SetUp]
              protected void SetUp ()
              {
                  //Add Here the Initialization of the objects 
              }
              [Test ( Description = "Add here the description of this test method " )]
              protected void TestMethodNameOK ()
              { 
                  //build ok use case scenario here - e.g. no exception should be raced '
                  //Vegetable newCarrot = pool.GetItemByPropertyValue<Vegetable> ( "WriongByPurpose", "Orange" );
                  //Assert.IsInstanceOfType ( typeof ( Vegetable ), newCarrot );
                  //Assert.AreSame ( newCarrot, carrot );
                  //logger.Info ( " I got the newCarrot which is " + newCarrot.Color );
      
              } //eof method 
      
              [Test ( Description = "Add here the description of this test method " )]
              protected void TestMethodNameNOK ()         //e.g. the one that should raze Exception
              {
                  //build ok use case scenario here - e.g. no exception should be raced '
                  //Vegetable newCarrot = pool.GetItemByPropertyValue<Vegetable> ( "WriongByPurpose", "Orange" );
                  //Assert.IsInstanceOfType ( typeof ( Vegetable ), newCarrot );
                  //Assert.AreSame ( newCarrot, carrot );
                  //logger.Info ( " I got the newCarrot which is " + newCarrot.Color );
      
              } //eof method 
      
          } //eof class 
      
      } //eof namespace 
      
      
      
      
      
      #region TheAppConfig
      /*
      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
          <configSections>
              <section name="log4net"
                       type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
          </configSections>
      
          <log4net>
              <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
                  <param name="File" value="Program.log" />
                  <param name="AppendToFile" value="true" />
                  <layout type="log4net.Layout.PatternLayout">
              <!--<param name="Header" value="======================================" />
              <param name="Footer" value="======================================" />-->
              <param name="ConversionPattern" value="%d [%t] %-5p - %m%n" />
            </layout>
              </appender>
      
              <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
            <mapping>
              <level value="ERROR" />
              <foreColor value="Red" />
            </mapping>
            <mapping>
              <level value="DEBUG" />
              <foreColor value="HighIntensity" />
            </mapping>
            <mapping>
              <level value="INFO" />
              <foreColor value="Green" />
            </mapping>
            <mapping>
              <level value="WARN" />
              <foreColor value="Yellow" />
            </mapping>
            <mapping>
              <level value="FATAL" />
              <foreColor value="White" />
              <backColor value="Red" />
            </mapping>
      
            <layout type="log4net.Layout.PatternLayout">
                      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
                  </layout>
              </appender>
      
      
              <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
                  <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.2.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
                  <connectionString value="data source=ysg;initial catalog=DBGA_DEV;integrated security=true;persist security info=True;" />
                  <commandText value="INSERT INTO [DBGA_DEV].[ga].[tb_Data_Log] ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />
      
                  <parameter>
                      <parameterName value="@log_date" />
                      <dbType value="DateTime" />
                      <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'.'MM'.'dd HH':'mm':'ss'.'fff}" />
                  </parameter>
                  <parameter>
                      <parameterName value="@thread" />
                      <dbType value="String" />
                      <size value="255" />
                      <layout type="log4net.Layout.PatternLayout" value="%thread" />
                  </parameter>
            <parameter>
              <parameterName value="@domainName" />
              <dbType value="String" />
              <size value="255" />
              <layout type="log4net.Layout.PatternLayout" value="%user" />
            </parameter>
                  <parameter>
                      <parameterName value="@log_level" />
                      <dbType value="String" />
                      <size value="50" />
                      <layout type="log4net.Layout.PatternLayout" value="%level" />
                  </parameter>
                  <parameter>
                      <parameterName value="@logger" />
                      <dbType value="String" />
                      <size value="255" />
                      <layout type="log4net.Layout.PatternLayout" value="%logger" />
                  </parameter>
                  <parameter>
                      <parameterName value="@message" />
                      <dbType value="String" />
                      <size value="4000" />
                      <layout type="log4net.Layout.PatternLayout" value="%message" />
                  </parameter>
              </appender>
              <root>
                  <level value="ALL" />
                  <appender-ref ref="LogFileAppender" />
                  <appender-ref ref="AdoNetAppender" />
                  <appender-ref ref="ColoredConsoleAppender" />
              </root>
          </log4net>
      </configuration>
      */
      #endregion TheAppconfig
      
       //this is the xml added replace here your log4net and Nunit paths
      //<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
              //  <SpecificVersion>False</SpecificVersion>
              //  <HintPath>..\..\..\Log4Net\log4net-1.2.10\bin\net\2.0\release\log4net.dll</HintPath>
              //</Reference>
              //<Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
      

      【讨论】:

        【解决方案4】:

        如何编写自己的附加程序以在发生某些事情时触发事件?您可以通过检查 log4net 存储库来获取它的实例。

        【讨论】:

          【解决方案5】:

          你可以试试 log4net 查看器。请参阅 Ayende 的博文Watching the logs run with log4net

          【讨论】:

            猜你喜欢
            • 2010-10-08
            • 2018-10-27
            • 2011-05-02
            • 1970-01-01
            • 1970-01-01
            • 2012-03-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多