由于事件源已存在,服务安装失败

时间:2013-12-18 23:20:35

标签: windows-services log4net event-log topshelf

我正在尝试使用Topshelf.Log4Net和log4net配置基于Topshelf的Windows服务以登录自定义事件日志。如果我在命令行模式下运行应用程序,这可以正常工作。当我尝试使用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创建。

2 个答案:

答案 0 :(得分:5)

部分问题是Topshelf会在您安装时自动创建以服务命名的事件日志源。由于log4net appender 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事件记录系统都是不稳定的。事件查看器的刷新在所有情况下都不起作用,我的应用程序日志条目一度消失了,我相信在重新启动后我看到了不同的结果。

答案 1 :(得分:0)

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

或者,仅在实际服务运行时使用事件日志appender,方法是在配置文件之外添加appender或修改配置以消除事件日志appender,除非发生ERROR或FATAL事件。

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