Skip to main content

Mastering Regular Expression. Part 7: Full C# Regex Application — Log File Analyzer

What We’ll Build:

  • A C# console app that parses .log files using regular expressions.
  • Extracts:
    • Timestamps
    • Error and warning levels
    • Stack traces
    • Custom events
  • Outputs:
    • Summary report to the console or file
    • Count of each log level
    • First and last timestamps
    • Pattern search (optional)

7.1 Log Format Assumption

We’ll assume a log format like:

[2025-08-04 12:01:43] [INFO] Application started.
[2025-08-04 12:01:45] [WARN] Low disk space.
[2025-08-04 12:01:47] [ERROR] System.NullReferenceException: Object reference not set to an instance of an object.
   at MyApp.Program.Main()
[2025-08-04 12:01:49] [INFO] Application ended.

7.2 Project Structure

/LogAnalyzer

  └── Program.cs

  └── LogParser.cs

  └── LogEntry.cs

  └── Sample.log


7.3 LogEntry.cs

public class LogEntry {
    public DateTime Timestamp { get; set; }
    public string Level { get; set; }
    public string Message { get; set; }
    public List<string> StackTrace { get; set; } = new();

    public override string ToString() {
        return $"[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level}] {Message}" +
               (StackTrace.Any() ? "\n" + string.Join("\n", StackTrace) : "");
    }
}

7.4 LogParser.cs

using System.Text.RegularExpressions;

public class LogParser {
    private static readonly Regex EntryPattern = new Regex(@"
        ^\[(?<timestamp>[\d\-:\s]+)\]\s
        \[(?<level>[A-Z]+)\]\s
        (?<message>.+)
    ", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);

    public static List<LogEntry> ParseLog(string[] lines) {
        var entries = new List<LogEntry>();
        LogEntry current = null;

        foreach (string line in lines) {
            Match m = EntryPattern.Match(line);

            if (m.Success) {
                current = new LogEntry {
                    Timestamp = DateTime.Parse(m.Groups["timestamp"].Value),
                    Level = m.Groups["level"].Value,
                    Message = m.Groups["message"].Value
                };
                entries.Add(current);
            }
            else if (line.StartsWith("   at") && current != null) {
                current.StackTrace.Add(line.Trim());
            }
        }

        return entries;
    }
}

7.5 Program.cs

class Program {
    static void Main(string[] args) {
        string logPath = "Sample.log";

        if (!File.Exists(logPath)) {
            Console.WriteLine($"Log file not found: {logPath}");
            return;
        }

        var lines = File.ReadAllLines(logPath);
        var entries = LogParser.ParseLog(lines);

        // Basic Stats
        var grouped = entries.GroupBy(e => e.Level);
        foreach (var group in grouped)
            Console.WriteLine($"{group.Key}: {group.Count()} entries");

        Console.WriteLine("\nFirst log: " + entries.First().Timestamp);
        Console.WriteLine("Last log: " + entries.Last().Timestamp);

        // Show all errors
        Console.WriteLine("\n--- ERROR Logs ---");
        foreach (var entry in entries.Where(e => e.Level == "ERROR"))
            Console.WriteLine(entry);
    }
}

7.6 Sample.log

[2025-08-04 12:01:43] [INFO] Application started.
[2025-08-04 12:01:45] [WARN] Low disk space.
[2025-08-04 12:01:47] [ERROR] System.NullReferenceException: Object reference not set to an instance of an object.
   at MyApp.Program.Main()
[2025-08-04 12:01:49] [INFO] Application ended.

7.7 Output Example

INFO: 2 entries
WARN: 1 entries
ERROR: 1 entries

First log: 8/4/2025 12:01:43 PM
Last log: 8/4/2025 12:01:49 PM

--- ERROR Logs ---
[2025-08-04 12:01:47] [ERROR] System.NullReferenceException: Object reference not set...
at MyApp.Program.Main(

7.8 Optional Features

๐Ÿงต Filter by date range

var recent = entries.Where(e => e.Timestamp >= DateTime.Today.AddHours(-1));

๐Ÿ” Pattern Search in Messages

string keyword = "disk";
var matches = entries.Where(e => e.Message.Contains(keyword, StringComparison.OrdinalIgnoreCase));

๐Ÿ“ค Export Report to File

File.WriteAllLines("report.txt", entries.Select(e => e.ToString()));

๐Ÿงฐ JSON Report (with System.Text.Json)

string json = JsonSerializer.Serialize(entries, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("report.json", json);

Summary

In this part, you:

Built a real-world log analyzer in C# using Regex
Parsed structured logs and extracted stack traces
Counted levels, printed summaries, and filtered messages
Learned modular and reusable design


Coming Up Next

In Part 8, we’ll explore regex testing, debugging, and tool integrations, including:

  • Visual Studio’s built-in regex testing tools
  • Regex101 and RegexStorm for .NET
  • Writing unit tests for regex
  • Debugging complex patterns with explanation tools
  • Live regex validation in C# apps

Comments

Popular posts from this blog