接收TraceAppender在另一个应用程序中发送的log4net消息

时间:2017-10-17 11:23:01

标签: c# log4net log4net-appender

我正在编写Windows服务和系统托盘应用程序来控制它。在我的服务中,我有很多log4net日志记录语句。我想在一个窗口中显示这些消息,该窗口可以从systray应用程序打开并开始尝试使用log4net TraceAppender。我还在我的systray应用程序中添加了一个自定义TraceListener。不幸的是,我没有在systray应用程序中看到任何消息。我不得不承认我不确定甚至可以在另一个应用程序中接收这些消息。

在我的服务中,我在log4net.xml中添加了以下行:

<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
  <immediateFlush value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  </layout>
</appender>

我也在使用文件追加器,所以在根部分我有这些行:

<root>
  <level value="WARN" />
  <appender-ref ref="RollingFileAppender" />
  <appender-ref ref="TraceAppender" />
</root>

请注意,消息很快就会到达日志文件中。

在systray应用程序中,我添加了以下类:

class TextBoxTraceListener : TraceListener
{
    private static TextBox _target;
    private StringSendDelegate _invokeWrite;

    public TextBoxTraceListener()
    {
    }

    public TextBoxTraceListener(TextBox target)
    {
        _target = target;
        _invokeWrite = new StringSendDelegate(SendString);
    }

    public override void Write(string message)
    {
        if (_target != null)
        {
            _target.Invoke(_invokeWrite, new object[] { message });
        }
    }

    public override void WriteLine(string message)
    {
        if (_target != null)
        {
            _target.Invoke(_invokeWrite, new object[]
            { message + Environment.NewLine });
        }
    }

    private delegate void StringSendDelegate(string message);
    private void SendString(string message)
    {
        // No need to lock text box as this function will only 
        // ever be executed from the UI thread
        _target.Text += message;
    }
}

我添加了没有参数的构造函数,因为我得到了一个异常,没有找到构造函数。

我的对话框类(WinForms)的代码是:

public partial class LogWatcherForm : Form
{
    TextBoxTraceListener _textBoxListener;

    public LogWatcherForm()
    {
        InitializeComponent();
    }

    private void LogWatcherForm_Load(object sender, EventArgs e)
    {
        _textBoxListener = new TextBoxTraceListener(logTextBox);
        Trace.Listeners.Add((TraceListener)_textBoxListener);
    }
}

最后,系统托盘应用程序的app.config包含:

<system.diagnostics>
  <trace autoflush="false" indentsize="4">
    <listeners>
      <add name="myListener" type="Cordis.ServiceSysTray.TextBoxTraceListener,ServiceSysTray"/>
      <remove name="Default" />
    </listeners>
  </trace>
</system.diagnostics>

我希望有人可以指出我正确的方向来实现这一目标。可以使用TraceAppender使其工作吗?

1 个答案:

答案 0 :(得分:0)

您有两个流程。您使用log4net和TraceAppender在Windows服务中执行Trace.WriteLine。在第二个进程中,在系统托盘中运行的应用程序,您正在通过自定义TraceListener进行侦听。

Trace.WriteLine未广播,因此所有进程都可以接收它。修复代码的方法是在系统托盘应用程序中,添加FileSystemWatcher监视Windows服务进程生成的日志文件。每次更新日志文件时,请将新值读入系统托盘应用程序并显示它们。打开日志文件时,请确保不使用专有文件访问权限。