为Windows服务和由该Windows服务托管的wcf服务创建记录器

时间:2014-06-03 23:11:03

标签: nlog

我在我的Windows服务中创建了一个记录器,它可以正常工作,直到该服务创建/托管wcf服务。当我在wcf服务中创建记录器时,目标为Windows服务日志的日志记录实际上记录到wcf服务日志中。以下是一些代码摘录:

Windows服务:

enum LoggingListeningPorts
{
  MCMessageService = 8182,
  MCService = 8183,
  MCWCFService = 8184,
  MyCourtsAdmin = 8185,
  MyCourtsWeb = 8186,
  MCManager = 8187,
  MCSupport = 8188,
  MyCourts = 8189
}

首先,我开始直接登录Windows服务,因为TCP Listener尚未初始化:

    private void startFileLogging()
{
  string location = "target";
  try
  {
    LoggingConfiguration config = new LoggingConfiguration();
    FileTarget target = new FileTarget();
    target.Layout = "${longdate} ${machineName} ${callsite} ${message} ${exception:format=tostring}";
    target.FileName = Path.Combine(dataDirectory, "MCService.log");
    target.KeepFileOpen = false;

    eventLog1.WriteEntry(string.Format("target.FileName [{0}]", target.FileName), EventLogEntryType.Information);

    LoggingRule normalRule = new LoggingRule("*", LogLevel.Trace, target);
    config.LoggingRules.Add(normalRule);       
    LogManager.Configuration = config;
    location = "Config";
    LogFactory fac = logger.Factory as LogFactory;
    fac.GlobalThreshold = loglevel;

    location = "Logging";
    //logger.Debug(string.Format("### NRMAP{0}_{1}", Assembly.GetExecutingAssembly().GetName().Name, Assembly.GetExecutingAssembly().GetName().Version));
    //logger.Debug(string.Format("### MCCommon_{0}", mccommonVersionNumber));
    logger.Debug("##########################################");
    logger.Debug(string.Format("########  MyCourts Service {0} ", Assembly.GetExecutingAssembly().GetName().Version).PadRight(42, '#'));
    logger.Debug("##########################################");

    //logger.Debug(string.Format("#### MyCourts Service {0} StartUp ", Assembly.GetExecutingAssembly().GetName().Version));
    logger.Debug(string.Format("Database directory [{0}]", dataDirectory));
    logger.Log(LogLevel.Trace, "Trace level is [{0}]", logger.IsTraceEnabled);
  }
  catch (Exception ex)
  {
    eventLog1.WriteEntry(string.Format("MCService Service logging failed at location [{0}]: {1}", location, ex.Message), EventLogEntryType.Warning);
  }
}

然后我启动wcf服务:

    mcwcfServiceHost.Open();
    logger.Trace("MCWCFService opened.");

在此阶段,Windows服务的日志记录工作正常。然后,我在Windows服务中执行以下方法,包括开始登录wcf服务:

private void initializeMCWCFService()
{
  logger.Debug("Set DB Path in MCWCFService");
  int pauseTime = 2000;
  System.Threading.Thread.Sleep(pauseTime);

  EndpointAddress basicHTTPendpoint = null;
  EndpointAddress serverTCPEndpoint = null;

  var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
  var findCriteria = FindCriteria.CreateMetadataExchangeEndpointCriteria(typeof(MCWCFService.MCManagementService));
  findCriteria.MaxResults = 1;
  var findResults = discoveryClient.Find(findCriteria);

  if (findResults.Endpoints.Count > 0)
  {
    var endpoints = MetadataResolver.Resolve(typeof(MCWCFService.MCManagementService), findResults.Endpoints[0].Address);
    if (endpoints.Count > 0)
    {
      foreach (var item in endpoints)
      {
        if (item.Address.Uri.Scheme == "net.tcp")
        {
          logger.Debug("Discovered NetTcpAddress [{0}]", item.Address);
          //serverTCPEndpoint = item.Address;
          IPAddress[] serverIPAddresses = Dns.GetHostAddresses(item.Address.Uri.Host);
          foreach (var address in serverIPAddresses)
          {
            if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
              serverTCPEndpoint = item.Address;
              break;
            }
          }
        }
        if (item.Address.Uri.Scheme == "http")
        {
          logger.Debug("Discovered basicHTTPAddress [{0}]", item.Address);
          basicHTTPendpoint = item.Address;
        }
      }
    }
  }
  else
    logger.Debug("Discovery failed for MCWCFService");

  logger.Debug("MCWCFService TCPEndpoint = [{0}]", serverTCPEndpoint);
  mcWCFEndpointAddress = serverTCPEndpoint;


  string hostName = Dns.GetHostName();
  IPAddress hostIPAddress = null;
  IPHostEntry host;
  host = Dns.GetHostEntry(hostName);
  //logger.Debug("Host = [{0}]", host);
  foreach (IPAddress ip in host.AddressList)
  {
    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
    {
      hostIPAddress = ip;
      logger.Debug("MCService Host [{0}] IP address = [{1}]", hostName, ip);
    }
  }

  ChannelFactory<MCWCFService.IMCManagementService> scf = null;
  string location = "";
  try
  {
    location = "create scf";
    scf = new ChannelFactory<MCWCFService.IMCManagementService>(
               new NetTcpBinding(SecurityMode.None),
               serverTCPEndpoint); 

    location = "create channel";
    MCWCFService.IMCManagementService channel = scf.CreateChannel();
    location = "set db path";
    channel.SetMyCourtsDataDirectory(dataDirectory);
    location = "set hostIPaddress";
    channel.SetMCServiceIPAddress(hostIPAddress);
    location = "start logging";
    channel.StartLogging();
  }
  catch (Exception ex)
  {
    logger.Fatal("Unable to complete setdb path in MCWCFService @ [{0}]: {1}", location, ex);
  }
  finally
  {
    if (scf != null && scf.State != CommunicationState.Faulted)
    {
      if (scf.State == CommunicationState.Opened)
        scf.Close();
    }

  }

}

以下是开始登录WCF服务的方法:

public void StartLogging()
{
  try
  {
    LoggingConfiguration cfg = new LoggingConfiguration();

    NetworkTarget networkTarget = new NetworkTarget();
    networkTarget.Layout = "${longdate} ${machineName} ${callsite} ${message} ${exception:format=tostring}";
    networkTarget.Address = string.Format("tcp://{0}:{1}", mcServiceIPAddress, (int)LoggingListeningPorts.MCWCFService);
    networkTarget.NewLine = false;
    networkTarget.KeepConnection = false;
    networkTarget.Name = "network1";

    LoggingRule networkRule = new LoggingRule("*", LogLevel.Trace, networkTarget);
    cfg.LoggingRules.Add(networkRule);

    LogManager.Configuration = cfg;

    mcmLogger = LogManager.GetLogger("MCManagementService");

    mcmLogger.Fatal("##########################################");
    mcmLogger.Trace(string.Format("########  MCWCFService {0} ",
      Assembly.GetExecutingAssembly().GetName().Version).PadRight(42, '#'));
    mcmLogger.Fatal("##########################################");

  }
  catch (Exception ex)
  {
    eventlog.WriteEntry(string.Format("MCManagemntService error {0}", ex), EventLogEntryType.Error);
    //errorLogger.FatalException("Unable to start logging: ", ex);
  }

此时,Windows服务的登录现在将记录到WCF服务日志中。

显而易见的解决方案是我混淆了TCP侦听端口,但我已经检查了很多次,我头疼。

我也尝试在开始登录WCF服务后立即在Windows服务上执行以下方法,但它没有做任何事情......

private void startTCPLogging()
{
  logger.Debug("Starting TCP Logger");
  try
  {

    if (logger != null)
      logger = null;

    LoggingConfiguration cfg = new LoggingConfiguration();

    NetworkTarget networkTarget = new NetworkTarget();
    networkTarget.Layout = "${longdate} ${machineName} ${callsite} ${message} ${exception:format=tostring}";
    networkTarget.Address = string.Format("tcp://{0}:{1}", mcWCFEndpointAddress, (int)LoggingListeningPorts.MCService);
    networkTarget.NewLine = false;
    networkTarget.KeepConnection = false;
    networkTarget.Name = "network1";

    LoggingRule networkRule = new LoggingRule("*", LogLevel.Trace, networkTarget);
    cfg.LoggingRules.Add(networkRule);

    LogManager.Configuration = cfg;
    logger = LogManager.GetCurrentClassLogger();
    logger.Fatal("Logger switched to TCP Listener");

  }
  catch (Exception ex)
  {
    //eventlog1.WriteEntry(string.Format("MCManagemntService error {0}", ex), EventLogEntryType.Error);
    //errorLogger.FatalException("Unable to start logging: ", ex);
  }

我需要两个单独的日志,我不明白为什么它们被合并到WCF服务日志中?

1 个答案:

答案 0 :(得分:1)

如果您在同一过程中运行Windows服务和WCF服务,则可能是因为您正在重置LogManager.Configuration

LogManager的实例在您的整个过程中可用。因此,每次使用new LoggingConfiguration()设置配置时,都会丢失先前的设置配置。

尝试设置一次LogManager.Configuration,然后使用以下方法添加或删除目标:

  • LogManager.Configuration.FindTargetByName(..)
  • LogManager.Configuration.RemoveTarget(..)
  • LogManager.Configuration.AddTarget(...)

或在财产的帮助下:

  • LogManager.Configuration.AllTargets