【问题标题】:Service installation fails as event source already exists服务安装失败,因为事件源已经存在
【发布时间】:2013-12-18 23:20:35
【问题描述】:

我正在尝试配置基于 Topshelf 的 Windows 服务以使用 Topshelf.Log4Net 和 log4net 记录到自定义事件日志。如果我在命令行模式下运行应用程序,这很好。当我尝试使用BillsTestService.exe install 安装服务时,我得到:

INFO  Topshelf v3.1.107.0, .NET Framework v4.0.30319.18052
DEBUG Attempting to install 'BillsTestService'
Running a transacted installation.
...
Service BillsTestService has been successfully installed.
Creating EventLog source BillsTestService in log Application...

An exception occurred during the Install phase.
System.ArgumentException: Source BillsTestService already exists on the local computer.
...
   at System.Diagnostics.EventLog.CreateEventSource(EventSourceCreationData sourceData)

我已经尝试在安装之前在 LINQPad 中运行EventLog.DeleteEventSource("BillsTestService");;成功,但后续服务安装仍然失败。

我的 log4net appender 配置是:

<appender name="ErrorEventLogAppender" type="log4net.Appender.EventLogAppender" >
  <threshold value="ERROR" />
  <logName value="MyCompanyServices" />
  <applicationName value="BillsTestService" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%-5level %logger - %message%newline" />
  </layout>
</appender>

我做错了什么?

目的是让多个服务将错误记录到相同的日志名称(使用不同的应用程序名称);日志将由 Operations 创建。

【问题讨论】:

标签: windows-services log4net event-log topshelf


【解决方案1】:

部分问题是 Topshelf 在安装时会自动创建一个以服务命名的事件日志源。由于 log4net 附加程序 applicationName 也用作事件日志源,因此 不能 是实际的应用程序/服务名称。源在本地计算机上必须是唯一的。我在 log4net 配置中为名称添加了“Source”后缀。

另一部分是服务没有创建日志的权限。它可以创建新源,但不能创建新日志。一种方法是在代码中(我使用 LINQPad):

EventLog.CreateEventSource("FOODEBUG", "MyCoSvc");

EventLog mylog = new EventLog("MyCoSvc");
mylog.Source = "FOODEBUG";

mylog.WriteEntry("This is a test.");

EventLog.DeleteEventSource("FOODEBUG");

如果你真的必须写入日志来创建它,我不肯定;在这花了两天多之后,我宁愿安全。

还要注意日志名称限制为 8 个字符;你可以再长一点,但系统只认为前 8 个字符是重要的。

没有必要像 Chris Patterson 建议的那样移动 log4net 初始化。简单地包括

configurator.DependsOnEventLog();
configurator.UseLog4Net("MyService.exe.config");

HostFactory.Run 委托中就足够了。 (我正在使用 Topshelf.Log4Net。)

最后,我有理由确定整个 Windows 事件记录系统是不稳定的。事件查看器的刷新并非在所有情况下都有效,有一次我的应用程序日志条目消失了,我相信我在重新启动后看到了不同的结果。

【讨论】:

  • 伟大的收获! ServiceInstaller.ServiceName != EventLog.LogName
【解决方案2】:

将您的 log4net 初始化移动到服务的 ConstructUsing() 配置委托,而不是指定在不需要实例化服务类的安装/卸载期间使用。

或者,仅在实际服务运行时使用事件日志附加程序,方法是在配置文件之外添加附加程序或修改配置以消除事件日志附加程序,除非发生错误或致命事件。

我的猜测是 DEBUG/INFO 级别的事件正在尝试记录到 appender,而源还不存在。

【讨论】:

  • 我已经尝试在 ConstructUsing 的代码中配置 log4net - 它不起作用(如果作为服务运行)。显然,Topshelf 默认会在日志应用程序中创建一个以服务命名的 EventLog 源。我尝试更改来源的名称;没有帮助。我正在尝试使用 Topshelf.Log4Net;我认为记录到事件日志的服务将是一种常见的情况。
  • 我也尝试在 BeforeStartingService 中配置 log4net(同样使用不同的 ApplicationName)——它在控制台模式下工作正常,在服务模式下什么也不做。
猜你喜欢
  • 2011-11-26
  • 2016-10-29
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
  • 2018-12-23
  • 2015-11-25
  • 1970-01-01
  • 2013-06-29
相关资源
最近更新 更多