You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#日志正则解析:超时场景下捕获分散线程ID(TID)的方法咨询

嘿,作为C#新手能自己搞定正则解析日志的问题已经超棒啦!针对你现在的需求,我来一步步给你捋清楚怎么实现~

核心思路拆解

首先我们要明确目标:先定位到超时相关的日志行,提取出对应的线程ID(TID),再检索整个日志文件中所有属于该TID的条目。下面分步骤说具体实现:

第一步:精准捕获超时对应的TID

首先得明确你的超时日志特征——你提到“对应上一行日志”,那我们分两种常见情况处理:

情况1:超时日志本身包含TID

比如你的超时日志格式类似:

2024-05-20 14:30:00 [TID:1234] 操作完成,耗时1.2秒(超时)

那你可以调整正则,同时匹配日期、TID和超时标记:

// 请根据你的实际日志格式调整正则表达式
var timeoutRegex = new Regex(@"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[TID:(\d+)\].*(超时|耗时大于1秒)");

当匹配到目标行时,通过match.Groups[2].Value就能直接拿到对应的TID字符串。

情况2:超时日志的上一行包含TID

如果超时行本身不带TID,触发超时的操作日志在上一行,比如:

2024-05-20 14:29:58 [TID:1234] 开始执行XX操作
2024-05-20 14:30:00 操作超时,耗时超过1秒

那你需要在扫描日志时记录上一行内容,当检测到超时行时,从上一行提取TID:

string previousLine = null;
var tidRegex = new Regex(@"\[TID:(\d+)\]");
var timeoutTids = new HashSet<string>(); // 用HashSet去重,避免重复处理同一TID

using (var reader = new StreamReader("your-log-file.log"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        // 检测当前行是否是超时行
        if (line.Contains("超时") || line.Contains("耗时大于1秒"))
        {
            if (!string.IsNullOrEmpty(previousLine))
            {
                var tidMatch = tidRegex.Match(previousLine);
                if (tidMatch.Success)
                {
                    timeoutTids.Add(tidMatch.Groups[1].Value);
                }
            }
        }
        previousLine = line;
    }
}

第二步:检索同一TID的所有日志条目

拿到所有需要关注的TID后,有两种高效的处理方式:

方式一:双遍扫描(适合超大日志文件,节省内存)

如果日志文件特别大,不想一次性加载到内存,就分两次扫描:

  1. 第一遍:收集所有超时相关的TID(就是上面的代码);
  2. 第二遍:遍历每一行日志,检查TID是否在目标集合中,是的话就写入新文件。

示例代码:

string outputPath = "timeout-related-logs.log";

using (var reader = new StreamReader("your-log-file.log"))
using (var writer = new StreamWriter(outputPath))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        var tidMatch = tidRegex.Match(line);
        if (tidMatch.Success && timeoutTids.Contains(tidMatch.Groups[1].Value))
        {
            writer.WriteLine(line);
        }
    }
}

方式二:内存加载(适合小文件,代码更简洁)

如果日志文件不大,可以一次性把所有行加载到内存,再筛选:

var allLines = File.ReadAllLines("your-log-file.log").ToList();
var targetLines = allLines.Where(line => 
{
    var tidMatch = tidRegex.Match(line);
    return tidMatch.Success && timeoutTids.Contains(tidMatch.Groups[1].Value);
});

File.WriteAllLines("timeout-related-logs.log", targetLines);

几个实用小提示

  • 正则要灵活调整:一定要根据你的实际日志格式修改正则,比如如果TID是字母+数字的组合,就把\d+改成\w+;
  • 性能优化:对于GB级别的超大日志,双遍扫描的方式更稳妥,避免内存溢出;
  • 测试边界情况:比如同一TID多次触发超时,用HashSet存TID可以自动去重,避免重复检索;如果日志末尾就是超时行,要确保不会因为上一行为空而报错。

内容的提问来源于stack exchange,提问作者GhostyIs1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:05:31