quarta-feira, janeiro 20, 2010

Appender para TextBox em log4net

Este problema apareceu-me porque tenho uma aplicação já construída que usa o log4net para fazer log, neste caso para ficheiro, mas eu queria por essa aplicação a ser invocada por um windows form estando o log a ser escrito para uma RichTextBox.

Esta técnica não só serve para esta situação, mas para qualquer objecto que tenha uma propriedade/campo que seja do tipo string. É necessário fazer 3 coisas:
1) Criar uma classe que derive de AppenderSkeleton;
2) Registar o appender no xml de configuração;
3) Dar ao appender o objecto para o qual vai escrever.

1)
using log4net.Appender;
using System.Windows.Forms;
using log4net.Core;

namespace LogExample
{
    public class TextAppender : AppenderSkeleton
    {
        private RichTextBox logPlace;

        public RichTextBox LogPlace
        {
            get { return logPlace; }
            set { logPlace = value; }
        }

        /// 
        /// Writes the logging event to a TextBox
        /// 
        override protected void Append(LoggingEvent loggingEvent)
        {
            LogPlace.Text += string.Format("\n{0}", loggingEvent.RenderedMessage);
        }
    }
}

2)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <appender name="Writer" type="LogExample.TextAppender, LogExample">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d{HH:mm:ss} %-5p - %m%n"/>
      </layout>
    </appender>

    <root>
      <priority value="info"/>
      <appender-ref ref="Writer"/>
    </root>
  </log4net>
</configuration>

3)
using System;
using System.Windows.Forms;
using log4net;
using log4net.Config;
using log4net.Appender;

namespace LogExample
{
    public partial class Log : Form
    {
        private readonly ILog log;

        public Log()
        {
            InitializeComponent();
            log = LogManager.GetLogger(typeof(Log));
            XmlConfigurator.Configure();
            IAppender[] appenders = log.Logger.Repository.GetAppenders();

            foreach (IAppender append in appenders)
            {
                if (append is TextAppender)
                {
                    ((TextAppender)append).LogPlace = logBox;
                }
            }
        }
    }
}

1 comentário:

Caxaria disse...

Essa é uma biblioteca que, desde que tive na Inosat, não parei de usar... mas isto não sabia :) boa dica!