C#: Log parsing date/time with regex, when there&#

2019-08-21 01:54发布

I've written up a program in C# that helps me parse large logs (~2 GBs or more). So far, I've made it output only the time:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LogParser
{
class Program
{
    static void Main(string[] args)
    {
        int counter = 0;
        string line;
        System.IO.StreamReader file = new System.IO.StreamReader(@"C:\\Users\\Jan\\Desktop\\api_fiter_sql.log");
        Console.WriteLine("Profesionalno branje logov se začenja: ");
        System.Threading.Thread.Sleep(2500);
        while ((line = file.ReadLine()) != null)
        {
            counter++;
            var regex = new Regex(@"\d{2}\:\d{2}:\d{2}.\d{4}");
            foreach (Match m in regex.Matches(line))
            {
                DateTime dt;
                if (DateTime.TryParseExact(m.Value, "HH:mm:ss.ffff", null, DateTimeStyles.None, out dt))
                {
                    Console.WriteLine(dt.ToString("HH:mm:ss.ffff"));
                }
            }
        }
        Console.WriteLine("Branje logov je končano. Prebrali smo: " + counter + " vrstic");
        Console.ReadKey();
    }
}
}

Now, one line of the logs looks like this:

<SQL > <TID: 0000000449> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER:                                              > <Overlay-Group: 0         > /* Mon Feb 26 2018 13:52:08.4510 */ OK

What I would like to do is; when there's a timeout (more than one second in between two times), I would like the program to export that data (of both lines; for example 10:10:10.0000 -> 10:10:15.0000) to let's say a .csv or a .txt (doesn't matter).

How would I go about doing that? I've thought about using if statements, but I've got no idea where to start.

2条回答
Lonely孤独者°
2楼-- · 2019-08-21 02:14

I've solved it! This is how the code looks like now, if anyone would like to learn. A friend helped me out greatly.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LogParser
{
class Program
{
    static void Main(string[] args)
    {
        Console.OutputEncoding = System.Text.Encoding.UTF8;
        int counterLine = 0;
        int counterTimeout = 0;
        string line = String.Empty;
        string previousLine = String.Empty;
        DateTime previousDt = DateTime.MaxValue;
        Regex regex = new Regex(@"\d{2}:\d{2}:\d{2}\.\d{4}");

        try
        {
            System.IO.StreamReader file = new 
 System.IO.StreamReader(args[0]);
            Console.WriteLine("Profesionalno branje logov se začenja:\n");
            StreamWriter writer = new 
 StreamWriter("C:\\Users\\Jan\\Desktop\\log.txt", true);

            while ((line = file.ReadLine()) != null)
            {
                counterLine++;
                foreach (Match m in regex.Matches(line))
                {
                    DateTime dt = new DateTime();
                    if (DateTime.TryParseExact(m.Value, "HH:mm:ss.ffff", null, DateTimeStyles.None, out dt))
                    {
                        if ((dt - previousDt).TotalSeconds > 1)
                        {
                            counterTimeout++;
                            Console.WriteLine(previousLine);
                            Console.WriteLine(line);
                            writer.WriteLine(previousLine);
                            writer.WriteLine(line);
                        }
                        previousLine = line;
                        previousDt = dt;
                    }
                }
            }
            file.Close();
            writer.Close();
            Console.WriteLine("\nBranje logov je končano. Prebrali smo: {0} vrstic ter izpisali " +
                              "{1} vrstic, kjer je bil timeout v datoteko.", counterLine, counterTimeout);
        }
        catch (Exception e)
        {
            Console.OpenStandardError();
            Console.WriteLine(e.Message);
        }
        if (args.Length < 1)
        {
            Console.OpenStandardError();
            Console.WriteLine("Uporaba: {0} LOG_FILE", AppDomain.CurrentDomain.FriendlyName);
            Console.ReadKey();
            return;
        }
    }
}
}
查看更多
放我归山
3楼-- · 2019-08-21 02:35

you could use a variable defined outside the while loop and at the end of the while you put in the current line, the previous variables could always be a little class object with the line and dt already parsed somewhat. Below some psuedo code

string previousLine;
DateTime previousDt;
var timeOutList = new List<Tuple<string, string>>();
while ((line = file.ReadLine()) != null) {
  //regex parsing, cast to DateTime

  if ((dt-previousDt).TotalSeconds > 5)
  {
     timeOutList.Add(new Tuple<string, string>(previousLine, line));
  }

  previousLine = line;
  previousDt = dt;
}

//do something with the timeOutList like saving it to a file
查看更多
登录 后发表回答