考虑使用WCF作为日志服务…请建议

本文关键字:服务 日志 WCF | 更新日期: 2023-09-27 17:49:48

我正在考虑企业日志服务的体系结构。它的工作是接收和存储日志消息,然后允许用户访问这些日志消息。我们需要将日志功能分离出来,以便其他服务在不久的将来可以使用它,而不是将日志功能构建到一个现有的Windows服务中。我喜欢我们的各种服务可以通过网络记录他们的信息。然后我可以构建一个RESTful接口,用于将特定的日志消息传递给浏览器或其他东西。

谁能说出以下选择是明智的还是缺乏的?

  1. 使用WCF作为日志服务
  2. 使用净。tcp用于传输
  3. 在Windows service项目中托管服务(使用ServiceHost)

另外,我该如何设计它,使它能够利用一些相当强大的服务器来托管它?是否有可能打开多个连接(或自动完成)或实现一些自动多线程?

我们目前使用该日志服务的一个服务非常冗长,并且会非常频繁地发送日志消息(~40-100k/天)。我还没有建立一个原型,也没有做任何基准测试,我知道我没有给你足够的细节来做出一个明确的决定,但我只是在寻找一些方向和考虑。谢谢。

考虑使用WCF作为日志服务…请建议

除了为日志记录再创建一个服务之外,还有其他选择。您可以将日志构建为一个方面,并在任何ServiceContractOperationContract需要时附加/分离该方面(也称为注入)。这种方式可以解耦日志记录,但它避免了每次调用时调用多个服务的开销。一旦你创建了这些方面,把它们编译成单独的二进制文件,并在你未来的所有服务中需要时使用它们,启用和禁用特定的日志场景比拥有一个专门的日志服务更容易维护。

看看下面的两篇文章,他们提供了简单的方法来做到这一点,你必须填写你想要的项目的肉。

  • 创建日志Aspect
  • WCF扩展性:参数检查器

你想看的重要MSDN文档。

  • IParameterInspector
  • IOperationBehavior
  • IServiceBehavior

编辑-示例代码

使用下面的代码,您可以将[OperationLogging]添加到任何操作契约之上,并且可以在LoggingInspector.BeforeCall中拦截对该操作契约的调用。

在任何服务契约上使用[ServiceLogging],服务调用中定义的所有操作都可以被拦截和记录。

your_app_config_key设置为TRUE以外的任何行为,这些额外的行为不会添加到您的服务管道中。这是非常酷的,因为这些代码都不是基于配置中的这个键来执行的。

public class LoggingInspector : IParameterInspector
{
    private string service;
    public LoggingInspector(string serviceName){ service = serviceName;}
    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState){}
    public object BeforeCall(string operationName, object[] inputs)
    {
      // your logging logic
    }
}
 //Operation Logging attribute - applied to operationcontracts.
 [AttributeUsage(AttributeTargets.Method)]
 public class OperationLoggingAttribute : Attribute, IOperationBehavior
 {
    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters){}
    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}
    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        if (ConfigurationManager.AppSettings["your_app_config_key"] == "TRUE")
            dispatchOperation.ParameterInspectors.Add(new LoggingInspector(dispatchOperation.Parent.Type.Name));
    }
    public void Validate(OperationDescription operationDescription){}
 }
 //Service Loggign attribute - applied to Service contract
[AttributeUsage(AttributeTargets.Class)]
public class ServiceLoggingAttribute : Attribute, IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters){}
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        if (ConfigurationManager.AppSettings["your_app_config_key"] == "TRUE")
            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
                foreach (OperationDescription operation in endpoint.Contract.Operations)
                    operation.Behaviors.Add(new OperationLoggingAttribute());
    }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase){}
}

原则上,我认为单个审计服务是有意义的,只要它位于应用程序的限定上下文中。IDesign在这里有一个ES日志的示例实现(查找"企业服务日志")。您可以进行一些初始测试,看看它是否能够处理您期望的负载。如果您担心性能问题,我会考虑使用tcp进行消息队列(示例日志应用程序也支持此功能)。至于托管,服务需要一直运行,所以Windows服务是有意义的。如果你想使用IIS,那么我建议使用Windows Server AppFabric并启用应用程序的自动启动功能。

HTH。

读到这个问题,我有一些想法要分享。日志记录本身并不是一项非常复杂的活动,使用WCF创建企业日志记录框架就可以了。但是仅仅为了记录而记录的数据是没有用的。然后,这些数据需要被某个进程/app使用,从而提供一些附加价值。因此,日志记录更重要的方面是

  • 正在记录哪些数据。
  • 记录的数据如何被消耗'利用

所以我的建议是花更多的时间考虑需要记录什么以及这些数据增加了什么价值。