我编写了一个C#windows服务,可以将消息写入自定义EventLog或任意数量的文件.这些消息都标记有一些优先级(因此,例如,只有ERROR和WARNING存储在EventLog中,但如果需要,可以将更多内容存储到文件中).
我现在要做的是创建一个GUI,可以监听这些消息并实时显示它们.允许用户观看当前的消息(在任何他们想要的优先级),而不需要的一切存储到文件中.我认为这是某种形式的挂钩到服务的一个单独的程序,但我不能确定从哪里开始.
这是我第一次真正的Windows服务,所以我似乎缺少一些关键字找出如何做到这一点?是否有任何代码样本,教程,参考文献等,为如何做这样的事情?
更新
很多有用的答案,我喜欢它,有很多方法可以解决问题!我想我将实现一个基于WCF的自托管解决方案.我仍然非常关注细节,因为我正在努力了解WCF(我相信它对我来说在其他项目中非常有用)...但到目前为止,我发现这里的视频是最多的有用的介绍方法.
我试图按照这个演练.
我正在使用Visual Studio 2010 Premium.
我在服务器资源管理器或事件查看器中看到的唯一事件是"服务已成功启动".并且"服务已成功停止".
这是服务代码:
namespace MyNewService
{
public partial class MyNewService : ServiceBase
{
public MyNewService()
{
InitializeComponent();
if (!EventLog.SourceExists("MySource"))
{
EventLog.CreateEventSource("MySource", "MyNewLog");
}
eventLog1.Source = "MySource";
eventLog1.Log = "MyNewLog";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart");
}
protected override void OnStop()
{
eventLog1.WriteEntry("In onStop.");
}
}
}
Run Code Online (Sandbox Code Playgroud) 我需要处理来自EventLog的事件.使用附加到EventRecordWritten事件的EventLogWatcher很容易.但是我感兴趣的查询(eventid == 299 || eventid == 500)提供了比我需要的更多的事件.这是流的示例
Event ID Correlation ID
299 1AD... (this is actually a guid) X1
500 1AD... X2
500 1AD...
500 1AD...
299 43B... Y1
299 EDB... Z1
500 43B... Y2
500 EDB... Z2
500 43B...
500 43B...
Run Code Online (Sandbox Code Playgroud)
我对事件299以及与299事件的相关id匹配的第一个事件500感兴趣.我在上面的流中标记了它们,这是我感兴趣的输出集合:[X1, X2, Y1, Y2, Z1, Z2]这可能是使用相关id作为键的字典和EventRecord作为值的元组
{ 1AD.., <X1, X2> }
{ 43B.., <Y1, Y2> }
{ EDB.., <Z1, Z2> }
Run Code Online (Sandbox Code Playgroud)
一般情况下,事件可能会按顺序排列(299然后是500),但在高并发情况下,我预见会有两个299个事件,然后是500个事件,所以我不想依赖事件发生的顺序.相关id是关联它们的关键(这是事件的第一个属性eventRecord.Properties[0])
我认为这可以通过状态机来解决,但是看看是否有人想出一个Rx的解决方案,这个解决方案由一个可观察的查询表示,这将是很有趣的.这将使模式匹配逻辑保持在一个位置.
更新:这是解决方案的答案.谢谢基甸,这正是我需要的起点!
var pairs = events
.Where(e299 …Run Code Online (Sandbox Code Playgroud) 我正在使用FileSystemWatcher来监视文件夹.但是当目录中发生某些事件时,我不知道如何搜索谁对该文件产生了影响.我试着使用EventLog.它无法正常工作.还有另一种方法吗?
我有一个我在多个ClickOnce应用程序中使用的库.如果这个库出错,我想把错误写入windows EventLog.
我发现了一篇知识库文章,但似乎需要管理员权限来搜索源代码.特别是在尝试搜索Security事件日志时会发生窒息.
有没有办法解决这个问题并在ClickOnce应用程序中写入事件日志?我看到一个人试图写一个已知来源,但他们似乎无法找到一直可用的来源.
编辑:
根据这里的答案,我创建了一个程序,该程序包含在我的应用程序中,我可以在第一次运行时运行以设置可以获得管理员权限的事件源.但是一旦创建了源代码,我似乎仍然无法写入它.
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (!EventLog.SourceExists("ATE"))
{
EventLog.CreateEventSource("ATE", "Application");
}
}
Run Code Online (Sandbox Code Playgroud)
是否正确创建了一个源(相当于Yannick Blondeau提供的注册表编辑).当我在非提升的应用程序中写入源时,我收到一个新的错误,但它仍然无法正常工作.新错误是:
Cannot open log for source 'ATE'. You may not have write access.
编辑2:
我现在一直试图让它通过CustomSD键上的注册表编辑工作.我尝试添加(A ;; 0x7 ;;; AU)为经过身份验证的用户提供完全访问权限,但似乎没有任何效果.
我EventLog在我的应用程序中创建了一个对象,我用来记录到我自己的日志,创建如下:
if (!System.Diagnostics.EventLog.SourceExists("MyApplication")) {
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyApplication");
}
eventLog.Source = "MySource";
eventLog.Log = "MyApplication";
Run Code Online (Sandbox Code Playgroud)
我记录这样的条目:
eventLog.WriteEntry("some log line");
Run Code Online (Sandbox Code Playgroud)
检查eventLog对象时,它说Log设置为"MyApplication"。但是,日志记录始终转到 Windows 应用程序日志。我还必须说,在我将另一个源注册到同一日志之前,代码一直有效。该“新”源正确记录。
更新查看注册表时,正确创建了源(作为日志的子项)
可能有什么问题?
我的 C# 应用程序订阅 Windows 事件日志消息:
var subscriptionQuery = new EventLogQuery(Settings.Default.LogPath, PathType.LogName, Settings.Default.LogQuery);
_watcher = new EventLogWatcher(subscriptionQuery);
_watcher.EventRecordWritten += EventLogEventRead;
Run Code Online (Sandbox Code Playgroud)
当消息发生时,EventLogEventRead处理程序接收一个System.Diagnostics.Eventing.Reader.EventLogRecord包含事件数据的对象。此信息包括EventProperty对象的集合。问题是:EventProperty只定义了一个值,而不是属性的名称。但是,当我在 Windows 事件日志查看器中打开相同的事件时,它会显示带有名称的属性。现在的问题是:如何获取事件属性名称?
我正在使用System.Diagnostics.Eventing.Reader.EventLogWatcher类挂钩安全事件日志,我正在观察2008服务器盒上的事件ID 4625,以查看传入的失败登录(特别是RDP).
日志捕获工作正常,我将结果转储到队列中以进行相关的后续处理.但是,有时捕获的日志会填充(解析)IPAddress数据字段,有时则不会.
我在观看服务器的同时运行windump,尝试从不同的服务器和操作系统风格中进行常规的RDP登录,我可以得出的唯一结论是版本差异问题,而且编码也不错.虽然我错了,LOL.
问题在于事件日志本身与这些连接有关.记录所有失败的RDP登录,并正确处理,但某些日志根本不记录失败连接的源IP地址.
一些较新的mstsc风格会不会导致远程事件日志不记录源IP地址?对于我对这个钩子服务器运行的任何其他2008服务器来说,这似乎都是正确的.到目前为止我尝试过的任何2003或XP机器都已正确记录.
如果您需要更多信息,请告诉我们.谢谢!
编辑
我是否需要做一些疯狂的事情 - 比如实施sharpPcap并将IP与事件日志相关联?= /.也许可以查询lsass(这不是通常写入安全日志的唯一内容)吗?
我目前能够使用以下代码创建Windows事件日志:
string sSource;
string sLog;
string sEvent;
sSource = "Sample App";
sLog = "Application";
sEvent = "Sample Event";
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource,sLog);
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 11111);
Run Code Online (Sandbox Code Playgroud)
这将在应用程序日志中创建一个日志.我想在事件日志中为事件添加多行数据,以便在调试时我可以直接解析日志以解决问题.此外,我查看了应用程序日志中的一些其他日志,它们似乎有一个二进制数据字段.我无法弄清楚如何编写这样的字段,因为上面的代码只添加了一个EventData字段.
我有一个要在其中将条目写入事件日志的应用程序。记录器通过MEF实例化。我创建了一个派生类,以便能够在使用它之前执行日志初始化。
我的代码如下:
public class WinEventLog : EventLog, ILogger
{
private const string LOG_SourceName = "DataGen_Source";
private const string LOG_SysLogName = "Pool_Log";
private bool _isInitialized = false;
public WinEventLog()
: base()
{
Initialize();
}
public void LogMessage(MessageLevel level, string message)
{
WriteEntry(message, level.EventLogType());
}
public void LogMessage(string source, MessageLevel level, string message)
{
WriteEntry(source, message, level.EventLogType());
}
public void Initialize()
{
if (!_isInitialized)
{
this.BeginInit();
this.EndInit();
if (!System.Diagnostics.EventLog.SourceExists(LOG_SourceName))
{
System.Diagnostics.EventLog.CreateEventSource(
LOG_SourceName, LOG_SysLogName);
}
Source = LOG_SourceName;
Log = LOG_SysLogName;
_isInitialized = …Run Code Online (Sandbox Code Playgroud)