为何FileSystemWatcher监听SQL Server日志文件时事件不触发
问题核心原因及修复方案
1. 日志过滤规则配置错误
你设置的watcher.Filter = "ERRORLOG.*"仅匹配带后缀的归档日志文件,SQL Server当前正在写入的活跃错误日志文件名为ERRORLOG,无任何后缀,完全不符合过滤规则,自然无法捕获变更。
2. 目录监听权限不足
C:\Program Files下的SQL Server日志目录属于系统受保护目录,普通权限运行的程序没有监听该目录文件变更的权限,必须以管理员身份运行你的程序。
3. 主线程等待逻辑可优化(非必要但建议修改)
空while(true)循环会持续占用单核心CPU资源,虽然不会直接阻塞FileSystemWatcher的线程池回调,但属于不必要的资源浪费,可替换为低消耗的等待逻辑。
修正后的代码示例
static class Program { static void Main(string[] args) { try { var logDirectory = @"C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Log"; // 先验证目录可访问,避免路径配置错误 if (!Directory.Exists(logDirectory)) { Console.WriteLine("监听目录不存在,请检查路径配置"); return; } using var watcher = new FileSystemWatcher(logDirectory); // 可移除不需要的监听属性,减少无效事件触发 watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName; watcher.Changed += OnChanged; watcher.Created += OnChanged; // 新增归档日志生成也可以监听,不需要可以注释 watcher.Error += OnError; // 修正过滤规则,匹配所有ERRORLOG开头的文件(包括无后缀的活跃日志) watcher.Filter = "ERRORLOG*"; watcher.IncludeSubdirectories = false; watcher.EnableRaisingEvents = true; Console.WriteLine("日志监听已启动,按任意键退出..."); Console.ReadLine(); // 替换死循环 } catch (Exception e) { Console.WriteLine(e); throw; } } private static void OnError(object sender, ErrorEventArgs e) { Console.WriteLine("监听错误:" + e.GetException().Message); } private static void OnChanged(object sender, FileSystemEventArgs e) { Console.WriteLine($"检测到日志变更:{e.ChangeType} | {e.Name}"); } }
补充说明
如果出现同一变更触发多次Changed事件的情况,属于FileSystemWatcher的已知特性,可以在回调中增加简单的去抖逻辑,比如设置时间间隔,相同文件的变更在几百毫秒内只处理一次即可。
内容的提问来源于stack exchange,提问作者Randy
相关产品推荐
相关产品推荐

