C#中使用Regex解析防火墙日志提取指定字段的技术问询
防火墙日志解析:用正则提取目标字段
针对你给出的防火墙日志格式,直接使用正则表达式即可精准提取所需字段,无需结合SubString或IndexOf——正则能更高效、可靠地匹配结构化(即使格式看起来杂乱)的日志内容。
日志示例
<46>Nov7 04:33:25 FirewallDeviceName [Some identifier from the firewall, can contain spaces]: in:[InterfaceName] out:[InterfaceName], connection-state:new src-mac [Mac-ID], proto UDP, [SourceIP]:[SourcePort]->[Dst-IP]:[Dst-Port], len 32
匹配正则表达式
使用命名捕获组的正则,方便后续直接通过字段名提取值:
in:\[(?<InInterface>[^\]]+)\] out:\[(?<OutInterface>[^\]]+)\],.*?proto (?<Protocol>\w+), (?<SourceIP>\d+\.\d+\.\d+\.\d+):(?<SourcePort>\d+)->(?<DestinationIP>\d+\.\d+\.\d+\.\d+):(?<DestinationPort>\d+)
正则捕获组说明
(?<InInterface>[^\]]+):匹配入接口名称(从[到]之间的内容)(?<OutInterface>[^\]]+):匹配出接口名称(?<Protocol>\w+):匹配协议类型(如UDP、TCP)(?<SourceIP>\d+\.\d+\.\d+\.\d+):匹配IPv4格式的源IP地址(?<SourcePort>\d+):匹配源端口号(?<DestinationIP>\d+\.\d+\.\d+\.\d+):匹配IPv4格式的目的IP地址(?<DestinationPort>\d+):匹配目的端口号
C# 代码实现(适配syslog监听器集成)
以下是可直接复用的解析类,解析后可将LogData对象的字段写入SQL数据库:
using System; using System.Text.RegularExpressions; public class FirewallLogParser { // 预编译正则提升性能,适合高频日志解析场景 private static readonly Regex _logRegex = new Regex( @"in:\[(?<InInterface>[^\]]+)\] out:\[(?<OutInterface>[^\]]+)\],.*?proto (?<Protocol>\w+), (?<SourceIP>\d+\.\d+\.\d+\.\d+):(?<SourcePort>\d+)->(?<DestinationIP>\d+\.\d+\.\d+\.\d+):(?<DestinationPort>\d+)", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static LogData ParseLogLine(string rawLog) { Match match = _logRegex.Match(rawLog); if (!match.Success) return null; // 日志格式不匹配时返回null,可根据需求调整处理逻辑 return new LogData { InInterface = match.Groups["InInterface"].Value, OutInterface = match.Groups["OutInterface"].Value, Protocol = match.Groups["Protocol"].Value, SourceIP = match.Groups["SourceIP"].Value, SourcePort = int.Parse(match.Groups["SourcePort"].Value), DestinationIP = match.Groups["DestinationIP"].Value, DestinationPort = int.Parse(match.Groups["DestinationPort"].Value) }; } } // 存储解析后字段的实体类,可直接映射到SQL表结构 public class LogData { public string InInterface { get; set; } public string OutInterface { get; set; } public string Protocol { get; set; } public string SourceIP { get; set; } public int SourcePort { get; set; } public string DestinationIP { get; set; } public int DestinationPort { get; set; } }
使用方式
在syslog监听器接收到日志后,调用ParseLogLine方法即可获取结构化数据:
string rawLog = "<46>Nov7 04:33:25 FirewallDeviceName [Some identifier...]: in:[LAN] out:[WAN], connection-state:new src-mac [aa:bb:cc:dd:ee:ff], proto UDP, 192.168.1.100:54321->8.8.8.8:53, len 32"; LogData parsedData = FirewallLogParser.ParseLogLine(rawLog); // 后续将parsedData的字段写入SQL数据库,示例(伪代码): // db.Execute("INSERT INTO FirewallLogs (InInterface, OutInterface, Protocol, SourceIP, SourcePort, DestinationIP, DestinationPort) VALUES (@InInterface, @OutInterface, @Protocol, @SourceIP, @SourcePort, @DestinationIP, @DestinationPort)", parsedData);
注意事项
- 如果日志中可能出现IPv6地址,需要调整正则中的IP匹配部分,替换为IPv6兼容的正则表达式
- 若日志格式有其他变体,可微调正则中的匹配规则(如调整
.*?的范围,或补充可选匹配项)
内容的提问来源于stack exchange,提问作者Colin Slater
相关产品推荐
相关产品推荐

