log4net的屏幕实时日志查看器的最佳实践

时间:2009-04-07 08:25:06

标签: c# logging log4net

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

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

我正在寻找最佳方法。到目前为止,我唯一的解决方案是设置UDP appender并创建一个特殊的线程,该线程将监听所有消息并向UI发送消息。

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

非常感谢您的帮助。

5 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

我同意Peter Lillevold的观点。下面是一个简单的示例,说明如何通过动态设置日志记录的详细程度从控制台应用程序登录到数据库

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" />

答案 3 :(得分:0)

编写自己的appender会在发生某事时触发事件怎么样?您可以通过检查log4net存储库来获取它的实例。

答案 4 :(得分:0)

您可以尝试使用log4net查看器。请参阅Ayende的博客: http://ayende.com/Blog/archive/2006/08/22/WatchingTheLogsRunWithLog4net.aspx