我在 Nuget 上使用 Microsoft EventSource Libary 1.1.25 编写了一个 ETW EventSource。EventSource 的目的是将事件发送到我们维护的安全应用程序的自定义事件日志。该代码在本地工作,但我们无法将事件写入服务器上的事件日志。
EventSource 被命名为(也类似)Company-Security,并将事件发送到 Admin Channel。在我的本地开发机器上,我可以使用 wevtutil 注册事件源清单,并在 Windows 事件查看器中查看带有管理日志的 Company-Security 文件夹。当我运行应用程序时,事件记录在事件日志中。
但是,当我将应用程序部署到测试服务器(运行 Windows Server 2012)时,事件日志记录不起作用。在我使用 wevtutil 注册清单后,该日志已创建并在事件查看器中可见,但名称略有不同。创建了一个名为 Company-Security/Admin 的文件夹,其中包含一个名为 Company-Security/Admin 的日志,位于该文件夹内。我还可以在服务器上运行 perfview 并查看创建的事件。但是,没有任何内容写入事件日志。我还在 EventSource 代码中添加了一些调试语句,可以看到 EventSource IsEnabled() 正在返回 true。
下面是我写的eventsource的基类和实现类的代码片段。
我已经研究并找不到任何解释为什么事件日志不能在服务器上工作,但在开发机器上工作。我想我错过了一些东西,但不确定是什么。
抽象基类:
public abstract class SecurityEventsBase : EventSource {
protected unsafe void WriteEvent(int eventId, long arg1, string arg2, string arg3) {
if (IsEnabled()) {
if (arg2 == null) {
arg2 = "[not provided]";
}
if (arg3 == null) {
arg3 = "[not provided]"; ;
}
fixed (char* arg2Ptr = arg2) {
fixed (char* arg3Ptr = arg3) {
EventSource.EventData* dataDesc = stackalloc EventSource.EventData[3];
dataDesc[0].DataPointer = (IntPtr)(&arg1);
dataDesc[0].Size = 8;
dataDesc[1].DataPointer = (IntPtr)arg2Ptr;
dataDesc[1].Size = (arg2.Length + 1) * 2;
dataDesc[2].DataPointer = (IntPtr)arg3Ptr;
dataDesc[2].Size = (arg3.Length + 1) * 2;
WriteEventCore(eventId, 3, dataDesc);
}
}
}
}
事件源类:
[EventSource(Name="Company-Security",LocalizationResources="Events.Properties.Resources")]
public sealed class AuthorizationEvents : SecurityEventsBase {
public static AuthorizationEvents Log = new AuthorizationEvents();
[Event(2000,Level=EventLevel.Informational,Channel=EventChannel.Admin,Message="User '{1}' ({0}) logged in successfully from IP Address {2}")]
public void Login(long UserId, string UserName, string IPAddress) {
if (IsEnabled()) {
WriteEvent(2000, UserId, UserName, IPAddress);
}
}
** additional events would follow here**
}