WCF log4net 的 Appender
为 WCF 设置 log4net Appender 的简便方法

引言
Log4Net 中非常重要的一点是能够以简单易用的方式设置自定义 appender,从而满足您的需求。 大多数日志都写入数据库,因此通常可以轻松地稍后查询它们,但是如果您想直接从您工作中的 Q/A 团队处获取日志到您家中的网络上怎么办? 想象一下,您告诉他们:“再次运行包含错误的 section”,同时您在屏幕上实时看到日志...
背景
当我想为 WCF 服务编写自定义 appender 时,我心想,“这很简单”,并试图在互联网上找到一个简单的 WCF appender 示例。 但令我惊讶的是,我发现的示例很少,而且它们非常复杂且不易理解,因此我开始研究如何编写自定义 appender,并且我遇到了 这个 好的帖子,并意识到它是多么容易。 在我实现它之后,我在这里与您分享...
这篇文章是为初学者准备的。 有意地,代码尽可能短且清晰。 这不是最好的方法(在实际的应用程序中,您将编写更详细的消息,格式化消息,并使用线程处理服务等等...),但这篇文章的目的是展示基本步骤并使其尽可能清晰。
此外,我故意避免使用自动的“添加服务引用”方式来设置服务的代理,因为我想准确地展示发生了什么,以便您可以轻松地更改或调整代码以理解示例。
那么,如何编写自定义 Appender?(或者这个类中到底有什么...)
为了编写自定义 appender,有两种方法:第一种是实现 log4net.Appender.IAppender
接口,但第二种方法更简单,在大多数情况下,您会发现它适合您的需求。 在第二种方法中,您需要从抽象类 log4net.Appender.AppenderSkeleton
派生您的自定义 appender 类,并实现一个名为 Append
的方法。 这是我的类
public class WcfAppender : AppenderSkeleton
{
}
此类用作 Wcf appender,因此它将包含与服务通信的整个基础结构。 幸运的是,只有一个 static
字段保存到日志服务的通道
static IServiceLogger Service;
正如我提到的,此类需要实现 'Append
' 方法
protected override void Append(LoggingEvent loggingEvent)
{
string message = string.Format("{0}, {1}", loggingEvent.Level.DisplayName,
loggingEvent.RenderedMessage);
Service.NewLog(message);
}
loggingEvent
包含记录器收集的所有数据,在这里我选择我想要的数据并将其制作成一个 string
并将其发送到 WCF 服务(在实际的应用程序中,发送 Log
类或类似的东西而不是将所有数据压缩到一个 string
中更有意义)。
现在我们有了 WCF appender 类。 不是很简单吗??? 但是工作尚未完成。 我们需要告诉 log4net 将此类实例化为我们的 appender,这可以通过 *App.config* 文件来完成。
配置 App.config
我们可以配置任意数量的记录器,但对于此示例,我们仅设置一个
<logger name="WcfLogger">
<appender-ref ref="WcfAppender" />
</logger>
记录器负责收集所有消息并将它们传递给 appender。 Appender 负责将消息写入特定位置。 Logger
可以将消息传递给多个 appender,但我们仅为此记录器设置一个 appender。 我们可以设置任意数量的 appender,但在此示例中,我们仅使用一个 appender
<appender name="WcfAppender" type="WcfAppenderLog4net.WcfAppender, WcfAppenderLog4net">
<layout type="log4net.Layout.PatternLayout">
<ConversionPattern value="%m" />
</layout>
</appender>
'type
' 告诉 log4net 将哪个类用作该 appender。 当记录器想要将消息传递给名为 WcfAppender
的 appender 时,它会检查需要实例化哪个类(在本例中为 WcfAppenderLog4net.WcfAppender
)以及哪个程序集保存它(在本例中为 'WcfAppenderLog4net
')并实例化该 appender。
出于某种原因,当我们使用 log4net 时,除非我们明确告诉它,否则它不知道在哪里查找其默认配置
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo ("..//..//App.config"));
该行告诉 log4net 其 *config* 文件存在的位置。 (如果我们从 EXE 文件向上移动两个目录,debug -> bin -> 我们将到达 *App.config* 的目录。)(还有更多方法可以这样做,例如在 AssemblyInfo
中)。
WCF 部分
如果没有“添加服务引用”的方式,它会为我们创建代理,我们可以简单地为 WCF 服务设置我们的设置。 在 WCF 中,我们需要三个部分,地址,绑定和协定来建立服务。 当应用程序启动时,它会创建并提升 WCF 记录器的服务
ServiceHost sh = new ServiceHost(typeof(ServiceLogger));
string address = "https://:8080/WcfAppenderService";
BasicHttpBinding binding = new BasicHttpBinding();
Type contract = typeof(IServiceLogger);
sh.AddServiceEndpoint(contract,binding,address);
sh.Open();
记录器知道它应该将消息传递给名为 WcfAppender
的 appender(如在 *App.config* 中配置的那样)并且需要实例化此 appender 类。 在此类的构造函数中,我们初始化并获取到服务的通道,因此 appender 可以将数据发送到服务。 这很简单
static IServiceLogger Service;
EndpointAddress address = new EndpointAddress
(new Uri("https://:8080/WcfAppenderService"));
BasicHttpBinding binding = new BasicHttpBinding();
Service = ChannelFactory<IServiceLogger>.CreateChannel(binding,address);
示例应用程序
在示例应用程序中,我们尝试在循环中除以数字并将结果作为信息发送到记录器。 当我们尝试除以零时,我们得到一个异常并将其作为错误发送。 我希望这篇文章能帮助理解如何编写 WCF appender。 如果您发现更好的方法,请告诉我,我会标记此更正。
历史
- 2010 年 7 月 23 日:初始发布