diff --git a/OneSTechLog.sln b/OneSTechLog.sln index fb5edb8..7f1c1e6 100644 --- a/OneSTechLog.sln +++ b/OneSTechLog.sln @@ -5,6 +5,11 @@ VisualStudioVersion = 16.0.29318.209 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OneSTechLog", "OneSTechLog\OneSTechLog.csproj", "{BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneSTechLogTest", "OneSTechLogTest\OneSTechLogTest.csproj", "{0FA99F0C-E533-46CB-A2BE-D83BDC6D4698}" + ProjectSection(ProjectDependencies) = postProject + {BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD} = {BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +20,10 @@ Global {BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC6E4DCE-2722-4E6F-BCBC-8945DE1127DD}.Release|Any CPU.Build.0 = Release|Any CPU + {0FA99F0C-E533-46CB-A2BE-D83BDC6D4698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FA99F0C-E533-46CB-A2BE-D83BDC6D4698}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FA99F0C-E533-46CB-A2BE-D83BDC6D4698}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FA99F0C-E533-46CB-A2BE-D83BDC6D4698}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/OneSTechLog/TechLogParser.cs b/OneSTechLog/TechLogParser.cs index 1f8fe53..e2a68a9 100644 --- a/OneSTechLog/TechLogParser.cs +++ b/OneSTechLog/TechLogParser.cs @@ -29,53 +29,32 @@ namespace OneSTechLog /// public Action> EventHandler { get => eventHandler; set => eventHandler = value; } - public TechLogParser( - string folder, - Action> eventHandler, - ExecutionDataflowBlockOptions readBlockOptions = null, - ExecutionDataflowBlockOptions parseBlockOptions = null, - ExecutionDataflowBlockOptions eventHandlerBlockOptions = null) + /// + /// Creates a new instance of TechLogParser class + /// + /// + /// + public TechLogParser(string folder, Action> eventHandler) { Folder = folder; EventHandler = eventHandler; - if (readBlockOptions == null) + readBlockOptions = new ExecutionDataflowBlockOptions { - this.readBlockOptions = new ExecutionDataflowBlockOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount - }; - } - else - { - this.readBlockOptions = readBlockOptions; - } + MaxDegreeOfParallelism = Environment.ProcessorCount + }; - if (parseBlockOptions == null) + parseBlockOptions = new ExecutionDataflowBlockOptions { - this.parseBlockOptions = new ExecutionDataflowBlockOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount, - BoundedCapacity = 10000 - }; - } - else - { - this.parseBlockOptions = parseBlockOptions; - } + MaxDegreeOfParallelism = Environment.ProcessorCount, + BoundedCapacity = 10000 + }; - if (eventHandlerBlockOptions == null) + eventHandlerBlockOptions = new ExecutionDataflowBlockOptions { - this.eventHandlerBlockOptions = new ExecutionDataflowBlockOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount, - BoundedCapacity = 10000 - }; - } - else - { - this.eventHandlerBlockOptions = eventHandlerBlockOptions; - } + MaxDegreeOfParallelism = Environment.ProcessorCount, + BoundedCapacity = 10000 + }; } /// @@ -86,7 +65,7 @@ namespace OneSTechLog { var eventHandlerBlock = new ActionBlock>(EventHandler, eventHandlerBlockOptions); var parseEventBlock = new TransformBlock>(ParseEventData, parseBlockOptions); - var readFileBlock = new ActionBlock(async (filePath) => await ReadFile(filePath, parseEventBlock), readBlockOptions); + var readFileBlock = new ActionBlock((filePath) => ReadFile(filePath, parseEventBlock), readBlockOptions); parseEventBlock.LinkTo(eventHandlerBlock); @@ -94,7 +73,7 @@ namespace OneSTechLog foreach (var filePath in files) { - await SendDataToNextBlock(filePath, readFileBlock); + SendDataToNextBlock(filePath, readFileBlock); } var readBlockTask = readFileBlock.Completion.ContinueWith(c => parseEventBlock.Complete()); @@ -105,7 +84,7 @@ namespace OneSTechLog await Task.WhenAll(readBlockTask, parseEventBlockTask, eventHandlerBlock.Completion); } - private async Task ReadFile(string filePath, ITargetBlock nextBlock) + private void ReadFile(string filePath, ITargetBlock nextBlock) { using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) using (var reader = new StreamReader(stream)) @@ -119,7 +98,7 @@ namespace OneSTechLog { var currentLine = reader.ReadLine(); - if (Regex.IsMatch(currentLine, @"^\d\d:\d\d\.\d+", RegexOptions.Compiled)) + if (Regex.IsMatch(currentLine, @"^\d\d:\d\d\.", RegexOptions.Compiled)) { if (firstEvent) { @@ -127,38 +106,37 @@ namespace OneSTechLog } else { - await SendDataToNextBlock(fileDateTime + ":" + currentEvent.ToString(), nextBlock); + SendDataToNextBlock(fileDateTime + ":" + currentEvent.ToString(), nextBlock); currentEvent.Clear(); } - currentEvent.Append(currentLine); + currentEvent.AppendLine(currentLine); } else { - currentEvent.Append(currentLine); + currentEvent.AppendLine(currentLine); } } while (!reader.EndOfStream); - await SendDataToNextBlock(fileDateTime + ":" + currentEvent.ToString(), nextBlock); + SendDataToNextBlock(fileDateTime + ":" + currentEvent.ToString(), nextBlock); } } private Dictionary ParseEventData(string eventData) { var properties = new Dictionary { - ["EventName"] = Regex.Match(eventData, @",.*?,", RegexOptions.IgnoreCase | RegexOptions.Compiled).ToString().Trim(','), - ["DateTime"] = Regex.Match(eventData, @"^.*?\.\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled).ToString(), - ["Duration"] = Regex.Match(eventData, @"-\d+?,", RegexOptions.IgnoreCase | RegexOptions.Compiled).ToString().Trim('-', ',') + ["EventName"] = Regex.Match(eventData, @",.*?,", RegexOptions.Compiled).ToString().Trim(','), + ["DateTime"] = Regex.Match(eventData, @"^.*?\.\d+", RegexOptions.Compiled).ToString(), + ["Duration"] = Regex.Match(eventData, @"-\d+?,", RegexOptions.Compiled).ToString().Trim('-', ',') }; - var props = Regex.Matches(eventData, @",[\w:]+=.*?(?=(,[\w:]+=|$))", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled); + var props = Regex.Matches(eventData, @",[\w:]+=.*?(?=(,[\w:]+=|$))", RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.Compiled); for (int x = 0; x < props.Count; x++) { - var prop = props[x]; - var propText = prop.ToString(); + var propText = props[x].ToString(); var splInd = propText.IndexOf('='); var propName = propText.Substring(0, splInd).Trim(','); var propVal = propText.Substring(splInd + 1).Trim('\'', '"'); @@ -168,9 +146,9 @@ namespace OneSTechLog return properties; } - private async Task SendDataToNextBlock(T data, ITargetBlock nextBlock) + private void SendDataToNextBlock(T data, ITargetBlock nextBlock) { - while (!await nextBlock.SendAsync(data)) ; + while (!nextBlock.Post(data)) ; } private string[] GetTechLogFiles() { diff --git a/OneSTechLogTest/App.config b/OneSTechLogTest/App.config new file mode 100644 index 0000000..731f6de --- /dev/null +++ b/OneSTechLogTest/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/OneSTechLogTest/OneSTechLogTest.csproj b/OneSTechLogTest/OneSTechLogTest.csproj new file mode 100644 index 0000000..12e2244 --- /dev/null +++ b/OneSTechLogTest/OneSTechLogTest.csproj @@ -0,0 +1,64 @@ + + + + + Debug + AnyCPU + {0FA99F0C-E533-46CB-A2BE-D83BDC6D4698} + Exe + OneSTechLogTest + OneSTechLogTest + v4.6.1 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + full + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + ..\packages\System.Threading.Tasks.Dataflow.4.10.0\lib\netstandard2.0\System.Threading.Tasks.Dataflow.dll + + + + + + + + + + + + + + + + + + + {bc6e4dce-2722-4e6f-bcbc-8945de1127dd} + OneSTechLog + + + + \ No newline at end of file diff --git a/OneSTechLogTest/Program.cs b/OneSTechLogTest/Program.cs new file mode 100644 index 0000000..722b42a --- /dev/null +++ b/OneSTechLogTest/Program.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OneSTechLog; +using System.Diagnostics; + +namespace OneSTechLogTest +{ + class Program + { + static object locker = new object(); + static int i = 0; + + static async Task Main(string[] args) + { + var parser = new TechLogParser(@"C:\Users\akpaev.e.ENTERPRISE\Desktop\ExpertTools\tl", EventHandler); + + var watch = new Stopwatch(); + watch.Start(); + + await parser.Parse(); + + watch.Stop(); + + Console.WriteLine($"Считано событий: {i}"); + Console.WriteLine($"Время выполнения: {watch.Elapsed}"); + Console.ReadKey(); + } + + private static void EventHandler(Dictionary eventData) + { + lock(locker) + { + i++; + } + } + } +} diff --git a/OneSTechLogTest/Properties/AssemblyInfo.cs b/OneSTechLogTest/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f3481f3 --- /dev/null +++ b/OneSTechLogTest/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("OneSTechLogTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("HP Inc.")] +[assembly: AssemblyProduct("OneSTechLogTest")] +[assembly: AssemblyCopyright("Copyright © HP Inc. 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("0fa99f0c-e533-46cb-a2be-d83bdc6d4698")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OneSTechLogTest/packages.config b/OneSTechLogTest/packages.config new file mode 100644 index 0000000..472d95f --- /dev/null +++ b/OneSTechLogTest/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file