├── .gitignore ├── Bin └── Setup.exe ├── BuildInstaller.bat ├── EximLogAnalyzer.sln ├── EximLogAnalyzer ├── App.config ├── Application.ico ├── Config.cs ├── Data.cs ├── EximLogAnalyzer.csproj ├── EximLogAnalyzer.csproj.user ├── InnoSetupBuildScript.iss ├── Libs │ ├── Syncfusion.Grid.Base.dll │ ├── Syncfusion.Grid.Grouping.Base.dll │ ├── Syncfusion.Grid.Grouping.Windows.XmlSerializers.dll │ ├── Syncfusion.Grid.Grouping.Windows.dll │ ├── Syncfusion.Grid.Windows.XmlSerializers.dll │ ├── Syncfusion.Grid.Windows.dll │ ├── Syncfusion.Grouping.Base.dll │ ├── Syncfusion.Shared.Base.dll │ └── Syncfusion.Shared.Windows.dll ├── LogParser.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Models │ ├── DeliveryStatus.cs │ └── Mail.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── packages.config ├── README.md ├── Screenshots ├── Screenshot-01.png └── Screenshot-02.png └── appveyor.yml /.gitignore: -------------------------------------------------------------------------------- 1 | EximLogAnalyzer/bin/ 2 | EximLogAnalyzer/obj/ 3 | packages/ 4 | .vs/EximLogAnalyzer/v14/.suo 5 | .vs/ 6 | -------------------------------------------------------------------------------- /Bin/Setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/Bin/Setup.exe -------------------------------------------------------------------------------- /BuildInstaller.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\Inno Setup 6\Compil32.exe" /cc "%APPVEYOR_BUILD_FOLDER%\EximLogAnalyzer\InnoSetupBuildScript.iss" -------------------------------------------------------------------------------- /EximLogAnalyzer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1267 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EximLogAnalyzer", "EximLogAnalyzer\EximLogAnalyzer.csproj", "{4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /EximLogAnalyzer/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Application.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Application.ico -------------------------------------------------------------------------------- /EximLogAnalyzer/Config.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Xml.Serialization; 3 | 4 | namespace EximLogAnalyzer 5 | { 6 | public class Config 7 | { 8 | public string Hostname; 9 | 10 | public string Login; 11 | 12 | public string Password; 13 | 14 | public string LogPath; 15 | 16 | public Config() 17 | { 18 | LogPath = "/var/log/exim4"; 19 | } 20 | 21 | public static Config LoadConfig(string fileName) 22 | { 23 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(Config)); 24 | if (File.Exists(fileName)) 25 | { 26 | using (FileStream fs = File.OpenRead(fileName)) 27 | return (Config)xmlSerializer.Deserialize(fs); 28 | } 29 | else 30 | { 31 | throw new FileNotFoundException(); 32 | } 33 | } 34 | 35 | public static void SaveConfig(Config config, string fileName) 36 | { 37 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(Config)); 38 | xmlSerializer.Serialize(File.Create(fileName), config); 39 | } 40 | 41 | public static void Create(string fileName) 42 | { 43 | XmlSerializer xmlSerializer = new XmlSerializer(typeof(Config)); 44 | Config config = new Config(); 45 | xmlSerializer.Serialize(File.Create(fileName), config); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Data.cs: -------------------------------------------------------------------------------- 1 | namespace EximLogAnalyzer 2 | { 3 | internal class Data 4 | { 5 | public string Id { get; set; } 6 | public string StartTime { get; set; } 7 | public string SenderAddress { get; set; } 8 | public string Subject { get; set; } 9 | public string RecipientAddress { get; set; } 10 | public string Status { get; set; } 11 | public string SenderHostname { get; set; } 12 | public string SenderIpAddress { get; set; } 13 | 14 | public string Size { get; set; } 15 | public string Completed { get; set; } 16 | public string Delivered { get; set; } // ** delivery failed; address bounced 17 | public string Deferred { get; set; } // == delivery deferred; temporary problem 18 | public string EndTime { get; set; } 19 | 20 | 21 | public string QueryTime { get; set; } 22 | public string DeliveryTime { get; set; } 23 | public string DeliveredTime { get; set; } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /EximLogAnalyzer/EximLogAnalyzer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4B1A24BE-9CC1-4AB5-9E53-9F9D8F3C366A} 8 | WinExe 9 | Properties 10 | EximLogAnalyzer 11 | EximLogAnalyzer 12 | v4.6.1 13 | 512 14 | 15 | false 16 | C:\Users\Admin\Desktop\WebSite\ 17 | true 18 | Disk 19 | false 20 | Foreground 21 | 7 22 | Days 23 | false 24 | false 25 | true 26 | 1 27 | 1.0.0.%2a 28 | false 29 | true 30 | true 31 | 32 | 33 | AnyCPU 34 | true 35 | full 36 | false 37 | bin\Debug\ 38 | DEBUG;TRACE 39 | prompt 40 | 4 41 | false 42 | 43 | 44 | AnyCPU 45 | pdbonly 46 | true 47 | bin\Release\ 48 | TRACE 49 | prompt 50 | 4 51 | false 52 | 53 | 54 | Application.ico 55 | 56 | 57 | 84929697AD2CFE5CA9D2447B3A679361AFC6035E 58 | 59 | 60 | EximLogParser_TemporaryKey.pfx 61 | 62 | 63 | true 64 | 65 | 66 | false 67 | 68 | 69 | 70 | ..\packages\SSH.NET.2016.1.0\lib\net40\Renci.SshNet.dll 71 | 72 | 73 | False 74 | Libs\Syncfusion.Grid.Base.dll 75 | 76 | 77 | False 78 | Libs\Syncfusion.Grid.Grouping.Base.dll 79 | 80 | 81 | False 82 | Libs\Syncfusion.Grid.Grouping.Windows.dll 83 | 84 | 85 | False 86 | Libs\Syncfusion.Grid.Grouping.Windows.XmlSerializers.dll 87 | 88 | 89 | False 90 | Libs\Syncfusion.Grid.Windows.dll 91 | 92 | 93 | False 94 | Libs\Syncfusion.Grid.Windows.XmlSerializers.dll 95 | 96 | 97 | False 98 | Libs\Syncfusion.Grouping.Base.dll 99 | 100 | 101 | False 102 | Libs\Syncfusion.Shared.Base.dll 103 | 104 | 105 | False 106 | Libs\Syncfusion.Shared.Windows.dll 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | ..\packages\Yandex.Metrica.3.5.1\lib\net45\Yandex.Metrica.NET.dll 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | Form 136 | 137 | 138 | MainForm.cs 139 | 140 | 141 | 142 | 143 | MainForm.cs 144 | 145 | 146 | ResXFileCodeGenerator 147 | Resources.Designer.cs 148 | Designer 149 | 150 | 151 | True 152 | Resources.resx 153 | True 154 | 155 | 156 | 157 | 158 | SettingsSingleFileGenerator 159 | Settings.Designer.cs 160 | 161 | 162 | True 163 | Settings.settings 164 | True 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | False 182 | Microsoft .NET Framework 4.6 %28x86 and x64%29 183 | true 184 | 185 | 186 | False 187 | .NET Framework 3.5 SP1 188 | false 189 | 190 | 191 | 192 | 193 | if $(ConfigurationName) == Release "C:\Program Files (x86)\Inno Setup 6\Compil32.exe" /cc "$(ProjectDir)\InnoSetupBuildScript.iss" 194 | 195 | 202 | -------------------------------------------------------------------------------- /EximLogAnalyzer/EximLogAnalyzer.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ShowAllFiles 5 | 6 | 7 | 8 | 9 | 10 | 11 | en-US 12 | false 13 | 14 | -------------------------------------------------------------------------------- /EximLogAnalyzer/InnoSetupBuildScript.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Setup Script Wizard. 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3 | 4 | [Setup] 5 | ; NOTE: The value of AppId uniquely identifies this application. 6 | ; Do not use the same AppId value in installers for other applications. 7 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) 8 | AppId={{ED2B9A47-372F-47D9-8998-3C36BC7FAF78} 9 | AppName=Exim Log Analyzer 10 | AppVersion=1.0.22.0203 11 | ;AppVerName=Exim Log Analyzer 1.0.22.0203 12 | AppPublisher=Dmxengine, Inc. 13 | AppPublisherURL=http://www.dmxengine.com/ 14 | AppSupportURL=http://www.dmxengine.com/ 15 | AppUpdatesURL=http://www.dmxengine.com/ 16 | DefaultDirName={sd}\Exim Log Analyzer 17 | DisableProgramGroupPage=yes 18 | OutputDir=C:\Projects\EximLogAnalyzer\Bin 19 | OutputBaseFilename=Setup 20 | SetupIconFile=C:\Projects\EximLogAnalyzer\EximLogAnalyzer\Application.ico 21 | Compression=lzma 22 | SolidCompression=yes 23 | 24 | [Languages] 25 | Name: "english"; MessagesFile: "compiler:Default.isl" 26 | Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" 27 | 28 | [Tasks] 29 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked 30 | 31 | [Files] 32 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\EximLogAnalyzer.exe"; DestDir: "{app}"; Flags: ignoreversion 33 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Renci.SshNet.dll"; DestDir: "{app}"; Flags: ignoreversion 34 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Base.dll"; DestDir: "{app}"; Flags: ignoreversion 35 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Grouping.Base.dll"; DestDir: "{app}"; Flags: ignoreversion 36 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Grouping.Windows.dll"; DestDir: "{app}"; Flags: ignoreversion 37 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Grouping.Windows.XmlSerializers.dll"; DestDir: "{app}"; Flags: ignoreversion 38 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Windows.dll"; DestDir: "{app}"; Flags: ignoreversion 39 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grid.Windows.XmlSerializers.dll"; DestDir: "{app}"; Flags: ignoreversion 40 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Grouping.Base.dll"; DestDir: "{app}"; Flags: ignoreversion 41 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Shared.Base.dll"; DestDir: "{app}"; Flags: ignoreversion 42 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Syncfusion.Shared.Windows.dll"; DestDir: "{app}"; Flags: ignoreversion 43 | Source: "C:\Projects\EximLogAnalyzer\EximLogAnalyzer\bin\Release\Yandex.Metrica.NET.dll"; DestDir: "{app}"; Flags: ignoreversion 44 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files 45 | 46 | [Icons] 47 | Name: "{commonprograms}\Exim Log Analyzer"; Filename: "{app}\EximLogAnalyzer.exe" 48 | Name: "{commondesktop}\Exim Log Analyzer"; Filename: "{app}\EximLogAnalyzer.exe"; Tasks: desktopicon 49 | 50 | [Run] 51 | Filename: "{app}\EximLogAnalyzer.exe"; Description: "{cm:LaunchProgram,Exim Log Analyzer}"; Flags: nowait postinstall skipifsilent 52 | 53 | [UninstallDelete] 54 | Type: files; Name: "{app}\Config.xml" 55 | Type: files; Name: "{app}\Yandex.Metrica.Config.json" 56 | Type: files; Name: "{app}\Yandex.Metrica.CriticalConfig.json" 57 | Type: files; Name: "{app}\Yandex.Metrica.LiteMetricaService.json" 58 | Type: files; Name: "{app}\Yandex.Metrica.MigrationData.json" -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Base.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Base.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Windows.XmlSerializers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Windows.XmlSerializers.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Windows.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Grouping.Windows.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Windows.XmlSerializers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Windows.XmlSerializers.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grid.Windows.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grid.Windows.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Grouping.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Grouping.Base.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Shared.Base.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Shared.Base.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/Libs/Syncfusion.Shared.Windows.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/EximLogAnalyzer/Libs/Syncfusion.Shared.Windows.dll -------------------------------------------------------------------------------- /EximLogAnalyzer/LogParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using EximLogAnalyzer.Models; 8 | 9 | namespace EximLogAnalyzer 10 | { 11 | public class LogParser 12 | { 13 | private int _currentLogLineNumber; 14 | public List BounceMessages = new List(); 15 | public List DeliveryDeferred = new List(); 16 | public List DovecotAuthenticatorFailed = new List(); 17 | public List IdentConnection = new List(); 18 | public List MailBoxIsFull = new List(); 19 | public List MessageIsFrozen = new List(); 20 | public List NotFullTransaction = new List(); 21 | public List NotParsedLogLines = new List(); 22 | public List RetryTimeNotReachedForAnyHost = new List(); 23 | public List SorryWeAreNotOpenRelay = new List(); 24 | public List TlsErrorOnConnection = new List(); 25 | private Dictionary _parsedLogLines = new Dictionary(); 26 | public Dictionary ResultDict = new Dictionary(); 27 | 28 | private void ClearResults() 29 | { 30 | BounceMessages.Clear(); 31 | DeliveryDeferred.Clear(); 32 | DovecotAuthenticatorFailed.Clear(); 33 | IdentConnection.Clear(); 34 | MailBoxIsFull.Clear(); 35 | MessageIsFrozen.Clear(); 36 | NotFullTransaction.Clear(); 37 | NotParsedLogLines.Clear(); 38 | RetryTimeNotReachedForAnyHost.Clear(); 39 | SorryWeAreNotOpenRelay.Clear(); 40 | TlsErrorOnConnection.Clear(); 41 | _parsedLogLines.Clear(); 42 | _currentLogLineNumber = 0; 43 | ResultDict.Clear(); 44 | } 45 | 46 | public void ParseEximMainLog(Stream inputStream) 47 | { 48 | ClearResults(); 49 | inputStream.Seek(0, SeekOrigin.Begin); 50 | var streamReader = new StreamReader(inputStream, true); 51 | while (!streamReader.EndOfStream) 52 | { 53 | _currentLogLineNumber++; 54 | var logLine = streamReader.ReadLine(); 55 | ParseLogLine(logLine); 56 | if (!_parsedLogLines.ContainsKey(_currentLogLineNumber)) 57 | { 58 | NotParsedLogLines.Add(logLine); 59 | } 60 | } 61 | } 62 | 63 | private void ParseLogLine(string logLine) 64 | { 65 | if (logLine.Contains("cwd=/var/spool/exim4") || logLine.Contains("DKIM:") || 66 | logLine.Contains("Start queue run:") || logLine.Contains("End queue run:") || 67 | logLine.Contains("no host name found for IP address")) 68 | { 69 | MarkCurrentLogLineAsParsed(); 70 | return; 71 | } 72 | 73 | if (logLine.Contains("SMTP connection from")) 74 | { 75 | MarkCurrentLogLineAsParsed(); 76 | return; 77 | } 78 | 79 | if (logLine.Contains("dovecot_login authenticator failed")) 80 | { 81 | MarkCurrentLogLineAsParsed(); 82 | DovecotAuthenticatorFailed.Add(logLine); 83 | return; 84 | } 85 | 86 | if (logLine.Contains("dovecot_gssapi authenticator failed ")) 87 | { 88 | MarkCurrentLogLineAsParsed(); 89 | DovecotAuthenticatorFailed.Add(logLine); 90 | return; 91 | } 92 | 93 | if (logLine.Contains("TLS error on connection")) 94 | { 95 | MarkCurrentLogLineAsParsed(); 96 | TlsErrorOnConnection.Add(logLine); 97 | return; 98 | } 99 | 100 | if (logLine.Contains("ident connection")) 101 | { 102 | MarkCurrentLogLineAsParsed(); 103 | IdentConnection.Add(logLine); 104 | return; 105 | } 106 | 107 | if (logLine.Contains("Message is frozen")) 108 | { 109 | MarkCurrentLogLineAsParsed(); 110 | MessageIsFrozen.Add(logLine); 111 | return; 112 | } 113 | 114 | if (logLine.Contains("retry time not reached for any host") || 115 | logLine.Contains("Retry time not yet reached")) 116 | { 117 | MarkCurrentLogLineAsParsed(); 118 | RetryTimeNotReachedForAnyHost.Add(logLine); 119 | return; 120 | } 121 | 122 | if (logLine.Contains("mailbox is full")) 123 | { 124 | MarkCurrentLogLineAsParsed(); 125 | MailBoxIsFull.Add(logLine); 126 | } 127 | 128 | if (logLine.Contains("Sorry, we are not open relay")) 129 | { 130 | MarkCurrentLogLineAsParsed(); 131 | SorryWeAreNotOpenRelay.Add(logLine); 132 | return; 133 | } 134 | 135 | var regex = 136 | new Regex( 137 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) (<=|=>|->|Completed|\*\*|==) (<>)?"); 138 | var match = regex.Match(logLine); 139 | if (match.Success) 140 | { 141 | Mail mail; 142 | var mailId = match.Groups[3].Value; 143 | var direction = match.Groups[4].Value; 144 | if (ResultDict.ContainsKey(mailId)) 145 | { 146 | mail = ResultDict[mailId]; 147 | if (match.Groups[5].Value == "<>") 148 | { 149 | ParseBounceMessage(logLine, mail); 150 | return; 151 | } 152 | 153 | if (direction == "=>" || direction == "->") 154 | { 155 | ParseOutputMessage(logLine, mail); 156 | return; 157 | } 158 | 159 | if (direction == "**") 160 | { 161 | ParseDeliveryFailedAddressBouncedLogLine(logLine, mail); 162 | return; 163 | } 164 | 165 | if (direction == "==") 166 | { 167 | ParseDeliveryDeferredTemporaryProblemLogLine(logLine, mail); 168 | return; 169 | } 170 | 171 | if (direction == "Completed") 172 | { 173 | MarkCurrentLogLineAsParsed(); 174 | mail.EndTime = DateTime.Parse(match.Groups[1].Value); 175 | mail.Completed = true; 176 | } 177 | } 178 | else 179 | { 180 | if (direction == "<=") 181 | { 182 | if (match.Groups[5].Value == "<>") 183 | { 184 | mail = new Mail(); 185 | ResultDict.Add(mailId, mail); 186 | mail.Id = match.Groups[3].Value; 187 | mail.StartTime = DateTime.Parse(match.Groups[1].Value); 188 | ParseBounceMessage(logLine, mail); 189 | } 190 | else 191 | { 192 | mail = new Mail(); 193 | ResultDict.Add(mailId, mail); 194 | mail.Id = match.Groups[3].Value; 195 | mail.StartTime = DateTime.Parse(match.Groups[1].Value); 196 | ParseReceivedMessage(logLine, mail); 197 | } 198 | } 199 | else 200 | { 201 | MarkCurrentLogLineAsParsed(); 202 | NotFullTransaction.Add(logLine); 203 | } 204 | } 205 | } 206 | } 207 | 208 | private void ParseDeliveryDeferredTemporaryProblemLogLine(string logLine, Mail mail) 209 | { 210 | var handled = false; 211 | var regex1 = 212 | new Regex( 213 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) == (.+?) \((.+)\) <(.+?)> R=.+defer \(-?\d{0,3}\):(.+)"); 214 | var match1 = regex1.Match(logLine); 215 | if (match1.Success) 216 | { 217 | var deliveryStatus = 218 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match1.Groups[5].Value.Trim().ToLower()) 219 | .FirstOrDefault(); 220 | if (deliveryStatus == null) 221 | { 222 | deliveryStatus = new DeliveryStatus(); 223 | deliveryStatus.RecipientAddress = match1.Groups[5].Value.Trim().ToLower(); 224 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match1.Groups[1].Value, 225 | match1.Groups[7].Value.Trim()); 226 | deliveryStatus.Deferred = true; 227 | deliveryStatus.MailId = mail.Id; 228 | mail.DeliveryStatus.Add(deliveryStatus); 229 | } 230 | else 231 | { 232 | deliveryStatus.StatusMessage += string.Format("\r\n{0}: {1}", match1.Groups[1].Value, 233 | match1.Groups[7].Value.Trim()); 234 | } 235 | handled = true; 236 | } 237 | if (handled == false) 238 | { 239 | var regex2 = 240 | new Regex( 241 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) == (.+?) <(.+?)> R=.+defer \(-?\d{0,3}\):(.+)"); 242 | var match2 = regex2.Match(logLine); 243 | if (match2.Success) 244 | { 245 | var deliveryStatus = 246 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match2.Groups[5].Value.Trim().ToLower()) 247 | .FirstOrDefault(); 248 | if (deliveryStatus == null) 249 | { 250 | deliveryStatus = new DeliveryStatus(); 251 | deliveryStatus.RecipientAddress = match2.Groups[5].Value.Trim().ToLower(); 252 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match2.Groups[1].Value, 253 | match2.Groups[6].Value.Trim()); 254 | deliveryStatus.Deferred = true; 255 | deliveryStatus.MailId = mail.Id; 256 | mail.DeliveryStatus.Add(deliveryStatus); 257 | } 258 | else 259 | { 260 | deliveryStatus.StatusMessage += string.Format("\r\n{0}: {1}", match2.Groups[1].Value, 261 | match2.Groups[6].Value.Trim()); 262 | } 263 | handled = true; 264 | } 265 | } 266 | if (handled == false) 267 | { 268 | var regex3 = 269 | new Regex( 270 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) == (.+?\s).+T=.+defer \(-?\d{0,3}\):(.+)"); 271 | var match3 = regex3.Match(logLine); 272 | if (match3.Success) 273 | { 274 | var deliveryStatus = 275 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match3.Groups[4].Value.Trim().ToLower()) 276 | .FirstOrDefault(); 277 | if (deliveryStatus == null) 278 | { 279 | deliveryStatus = new DeliveryStatus(); 280 | deliveryStatus.RecipientAddress = match3.Groups[4].Value.Trim().ToLower(); 281 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match3.Groups[1].Value, 282 | match3.Groups[5].Value.Trim()); 283 | deliveryStatus.Deferred = true; 284 | deliveryStatus.MailId = mail.Id; 285 | mail.DeliveryStatus.Add(deliveryStatus); 286 | } 287 | else 288 | { 289 | deliveryStatus.StatusMessage = deliveryStatus.StatusMessage + 290 | string.Format("\r\n{0}: {1}", match3.Groups[1].Value, 291 | match3.Groups[5].Value.Trim()); 292 | } 293 | handled = true; 294 | } 295 | } 296 | 297 | if (handled == false) 298 | { 299 | var regex = 300 | new Regex( 301 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) == (.+?\s).+defer \(-?\d{0,3}\):(.+)"); 302 | var match = regex.Match(logLine); 303 | if (match.Success) 304 | { 305 | var deliveryStatus = 306 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match.Groups[4].Value.Trim().ToLower()) 307 | .FirstOrDefault(); 308 | if (deliveryStatus == null) 309 | { 310 | deliveryStatus = new DeliveryStatus(); 311 | deliveryStatus.RecipientAddress = match.Groups[4].Value.Trim().ToLower(); 312 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match.Groups[1].Value, 313 | match.Groups[5].Value); 314 | deliveryStatus.Deferred = true; 315 | deliveryStatus.MailId = mail.Id; 316 | mail.DeliveryStatus.Add(deliveryStatus); 317 | } 318 | else 319 | { 320 | deliveryStatus.StatusMessage = deliveryStatus.StatusMessage + 321 | string.Format("\r\n{0}: {1}", match.Groups[1].Value, 322 | match.Groups[5].Value.Trim()); 323 | } 324 | handled = true; 325 | } 326 | } 327 | if (handled) 328 | { 329 | MarkCurrentLogLineAsParsed(); 330 | } 331 | DeliveryDeferred.Add(logLine); 332 | } 333 | 334 | private void ParseDeliveryFailedAddressBouncedLogLine(string logLine, Mail mail) 335 | { 336 | var handled = false; 337 | var handlerCount = 0; 338 | 339 | var regex1 = 340 | new Regex(@"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) \*\* (.+?)\s.+T=.+?:(.+)"); 341 | var match1 = regex1.Match(logLine); 342 | if (match1.Success) 343 | { 344 | var deliveryStatus = 345 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match1.Groups[4].Value.Trim().ToLower()) 346 | .FirstOrDefault(); 347 | if (deliveryStatus == null) 348 | { 349 | deliveryStatus = new DeliveryStatus(); 350 | deliveryStatus.RecipientAddress = match1.Groups[4].Value.ToLower(); 351 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match1.Groups[1].Value, 352 | match1.Groups[5].Value.Trim()); 353 | deliveryStatus.Delivered = false; 354 | deliveryStatus.Deferred = false; 355 | deliveryStatus.MailId = mail.Id; 356 | mail.DeliveryStatus.Add(deliveryStatus); 357 | } 358 | else 359 | { 360 | deliveryStatus.StatusMessage += string.Format("\r\n{0}: {1}", match1.Groups[1].Value, 361 | match1.Groups[5].Value.Trim()); 362 | } 363 | handled = true; 364 | handlerCount++; 365 | MarkCurrentLogLineAsParsed(); 366 | } 367 | 368 | if (handled == false) 369 | { 370 | var regex2 = 371 | new Regex(@"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) \*\* (.+?)\s.+?:(.+)"); 372 | var match2 = regex2.Match(logLine); 373 | if (match2.Success) 374 | { 375 | var deliveryStatus = 376 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match2.Groups[4].Value.Trim().ToLower()) 377 | .FirstOrDefault(); 378 | if (deliveryStatus == null) 379 | { 380 | deliveryStatus = new DeliveryStatus(); 381 | deliveryStatus.Deferred = false; 382 | deliveryStatus.Delivered = false; 383 | deliveryStatus.MailId = mail.Id; 384 | deliveryStatus.RecipientAddress = match2.Groups[4].Value.ToLower(); 385 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match2.Groups[1].Value, 386 | match2.Groups[5].Value.Trim()); 387 | mail.DeliveryStatus.Add(deliveryStatus); 388 | } 389 | else 390 | { 391 | deliveryStatus.StatusMessage += string.Format("\r\n{0}: {1}", match2.Groups[1].Value, 392 | match2.Groups[5].Value.Trim()); 393 | } 394 | handled = true; 395 | handlerCount++; 396 | MarkCurrentLogLineAsParsed(); 397 | } 398 | } 399 | if (handled == false) 400 | { 401 | var regex3 = 402 | new Regex(@"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) \*\* (.+?):(.+)"); 403 | var match3 = regex3.Match(logLine); 404 | if (match3.Success) 405 | { 406 | var deliveryStatus = 407 | mail.DeliveryStatus.Where(t => t.RecipientAddress == match3.Groups[4].Value.Trim().ToLower()) 408 | .FirstOrDefault(); 409 | if (deliveryStatus == null) 410 | { 411 | deliveryStatus = new DeliveryStatus(); 412 | deliveryStatus.RecipientAddress = match3.Groups[4].Value.ToLower(); 413 | deliveryStatus.StatusMessage = string.Format("{0}: {1}", match3.Groups[1].Value, 414 | match3.Groups[5].Value.Trim()); 415 | deliveryStatus.Delivered = false; 416 | deliveryStatus.Deferred = false; 417 | deliveryStatus.MailId = mail.Id; 418 | mail.DeliveryStatus.Add(deliveryStatus); 419 | } 420 | else 421 | { 422 | deliveryStatus.StatusMessage += string.Format("\r\n{0}: {1}", match3.Groups[1].Value, 423 | match3.Groups[5].Value.Trim()); 424 | } 425 | handled = true; 426 | handlerCount++; 427 | MarkCurrentLogLineAsParsed(); 428 | } 429 | } 430 | } 431 | 432 | private void ParseBounceMessage(string logLine, Mail mail) 433 | { 434 | var regex = new Regex(@"(T=""(.*?)"")? from <(.+)?> for (.+)"); 435 | var match = regex.Match(logLine); 436 | if (match.Success) 437 | { 438 | mail.RecipientAddress = match.Groups[4].Value.Trim().ToLower(); 439 | mail.SenderAddress = match.Groups[3].Value.Trim().ToLower(); 440 | mail.Subject = ConvertSubject(match.Groups[2].Value); 441 | MarkCurrentLogLineAsParsed(); 442 | } 443 | BounceMessages.Add(logLine); 444 | } 445 | 446 | private void ParseReceivedMessage(string logLine, Mail mail) 447 | { 448 | var handlerCount = 0; 449 | var regex1 = new Regex(@"H=(.+?) \[(.+?)\].+\sS=(.+?)\s"); 450 | var match1 = regex1.Match(logLine); 451 | if (match1.Success) 452 | { 453 | handlerCount++; 454 | mail.SenderHostname = match1.Groups[1].Value; 455 | mail.SenderIpAddress = match1.Groups[2].Value; 456 | mail.Size = int.Parse(match1.Groups[3].Value); 457 | } 458 | var regex2 = new Regex(@"(T=""(.*?)"")? from <(.+)?> for (.+)"); 459 | var match2 = regex2.Match(logLine); 460 | if (match2.Success) 461 | { 462 | handlerCount++; 463 | mail.RecipientAddress = match2.Groups[4].Value.Trim().ToLower(); 464 | mail.SenderAddress = match2.Groups[3].Value.Trim().ToLower(); 465 | mail.Subject = ConvertSubject(match2.Groups[2].Value); 466 | } 467 | if (handlerCount == 2) 468 | { 469 | MarkCurrentLogLineAsParsed(); 470 | } 471 | } 472 | 473 | private void ParseOutputMessage(string logLine, Mail mail) 474 | { 475 | var handled = false; 476 | var handlerCount = 0; 477 | var regex1 = 478 | new Regex( 479 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) (=>|->) ([^\s]+)\s<(.+?)> F=<"); 480 | var match1 = regex1.Match(logLine); 481 | if (match1.Success) 482 | { 483 | handlerCount++; 484 | var deliveryStatus = new DeliveryStatus(); 485 | mail.DeliveryStatus.Add(deliveryStatus); 486 | deliveryStatus.Delivered = true; 487 | deliveryStatus.MailId = mail.Id; 488 | deliveryStatus.RecipientAddress = match1.Groups[6].Value; 489 | deliveryStatus.Time = DateTime.Parse(match1.Groups[1].Value); 490 | ParseDeliveryTerm(deliveryStatus, logLine); 491 | handled = true; 492 | } 493 | if (handled == false) 494 | { 495 | var regex2 = 496 | new Regex( 497 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) (=>|->) (.+?) \((.+)\) <(.+?)> F="); 498 | var match2 = regex2.Match(logLine); 499 | if (match2.Success) 500 | { 501 | handlerCount++; 502 | var deliveryStatus = new DeliveryStatus(); 503 | mail.DeliveryStatus.Add(deliveryStatus); 504 | deliveryStatus.Delivered = true; 505 | deliveryStatus.MailId = mail.Id; 506 | deliveryStatus.RecipientAddress = match2.Groups[6].Value; 507 | deliveryStatus.Time = DateTime.Parse(match2.Groups[1].Value); 508 | ParseDeliveryTerm(deliveryStatus, logLine); 509 | handled = true; 510 | } 511 | } 512 | if (handled == false) 513 | { 514 | var regex = 515 | new Regex( 516 | @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\d.+?)] (.{6}-.{6}-.{2}) (=>|->) ([^\s]+) F=<.+C=""(.+?)"""); 517 | var match = regex.Match(logLine); 518 | if (match.Success) 519 | { 520 | var deliveryStatus = new DeliveryStatus(); 521 | mail.DeliveryStatus.Add(deliveryStatus); 522 | deliveryStatus.MailId = mail.Id; 523 | deliveryStatus.RecipientAddress = match.Groups[5].Value.Trim().ToLower(); 524 | deliveryStatus.StatusMessage = match.Groups[6].Value.Trim(); 525 | deliveryStatus.Time = DateTime.Parse(match.Groups[1].Value); 526 | if (deliveryStatus.StatusMessage.StartsWith("250")) 527 | { 528 | deliveryStatus.Delivered = true; 529 | } 530 | ParseDeliveryTerm(deliveryStatus, logLine); 531 | handled = true; 532 | } 533 | } 534 | if (handled) 535 | { 536 | MarkCurrentLogLineAsParsed(); 537 | } 538 | if (handlerCount > 1) 539 | { 540 | } 541 | } 542 | 543 | private void ParseDeliveryTerm(DeliveryStatus deliveryStatus, string logLine) 544 | { 545 | var regex = new Regex(@"QT=(.+?)\sDT=(.+)"); 546 | var match = regex.Match(logLine); 547 | if (match.Success) 548 | { 549 | deliveryStatus.QueryTime = match.Groups[1].Value; 550 | deliveryStatus.DeliveryTime = match.Groups[2].Value; 551 | } 552 | } 553 | 554 | private string ConvertSubject(string line) 555 | { 556 | var convertedLine = line; 557 | var regex1 = new Regex(@"\\\d{3}\\\d{3}"); 558 | var match1 = regex1.Matches(line); 559 | foreach (Match item in match1) 560 | { 561 | if (item.Success) 562 | { 563 | var newChar = ConvertEscapedChar(item.Value); 564 | convertedLine = convertedLine.Replace(item.Value, newChar); 565 | } 566 | } 567 | return convertedLine; 568 | } 569 | 570 | private string ConvertEscapedChar(string escapedChar) 571 | { 572 | var bytes = escapedChar.Split(new[] {'\\'}, StringSplitOptions.RemoveEmptyEntries) 573 | .Select(s => (byte) Convert.ToInt32(s, 8)) 574 | .ToArray(); 575 | return Encoding.UTF8.GetString(bytes); 576 | } 577 | 578 | private void MarkCurrentLogLineAsParsed() 579 | { 580 | if (!_parsedLogLines.ContainsKey(_currentLogLineNumber)) 581 | { 582 | _parsedLogLines.Add(_currentLogLineNumber, 1); 583 | } 584 | } 585 | } 586 | } -------------------------------------------------------------------------------- /EximLogAnalyzer/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace EximLogAnalyzer 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 33 | this.tabControl1 = new System.Windows.Forms.TabControl(); 34 | this.mailsTabPage = new System.Windows.Forms.TabPage(); 35 | this.gridGroupingControl1 = new Syncfusion.Windows.Forms.Grid.Grouping.GridGroupingControl(); 36 | this.findInLogTabPage = new System.Windows.Forms.TabPage(); 37 | this.findButton = new System.Windows.Forms.Button(); 38 | this.textBox1 = new System.Windows.Forms.TextBox(); 39 | this.findInCurrentLogRichTextBox = new System.Windows.Forms.RichTextBox(); 40 | this.mailBoxIsFullTabPage = new System.Windows.Forms.TabPage(); 41 | this.mailBoxIsFullRichTextBox = new System.Windows.Forms.RichTextBox(); 42 | this.NotParsedLogLinesTabPage = new System.Windows.Forms.TabPage(); 43 | this.notParsedLogLinesRichTextBox = new System.Windows.Forms.RichTextBox(); 44 | this.bouncedMessagesTabPage = new System.Windows.Forms.TabPage(); 45 | this.bounceMessagesRichTextBox = new System.Windows.Forms.RichTextBox(); 46 | this.dovecotAuthenticatorFailedTabPage = new System.Windows.Forms.TabPage(); 47 | this.richTextBox2 = new System.Windows.Forms.RichTextBox(); 48 | this.deliveryDeferredTabPage = new System.Windows.Forms.TabPage(); 49 | this.DeliveryDeferredRichTextBox = new System.Windows.Forms.RichTextBox(); 50 | this.logFilesComboBox = new System.Windows.Forms.ComboBox(); 51 | this.connectButton = new System.Windows.Forms.Button(); 52 | this.refreshButton = new System.Windows.Forms.Button(); 53 | this.timer1 = new System.Windows.Forms.Timer(this.components); 54 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 55 | this.portLabel = new System.Windows.Forms.Label(); 56 | this.portTextBox = new System.Windows.Forms.TextBox(); 57 | this.label1 = new System.Windows.Forms.Label(); 58 | this.logPathLabel = new System.Windows.Forms.Label(); 59 | this.logPathTextBox = new System.Windows.Forms.TextBox(); 60 | this.passwordLabel = new System.Windows.Forms.Label(); 61 | this.passwordTextBox = new System.Windows.Forms.TextBox(); 62 | this.loginLabel = new System.Windows.Forms.Label(); 63 | this.loginTextBox = new System.Windows.Forms.TextBox(); 64 | this.hostnameLabel = new System.Windows.Forms.Label(); 65 | this.hostnameTextBox = new System.Windows.Forms.TextBox(); 66 | this.menuStrip1 = new System.Windows.Forms.MenuStrip(); 67 | this.openLogFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 68 | this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 69 | this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); 70 | this.tabControl1.SuspendLayout(); 71 | this.mailsTabPage.SuspendLayout(); 72 | ((System.ComponentModel.ISupportInitialize)(this.gridGroupingControl1)).BeginInit(); 73 | this.findInLogTabPage.SuspendLayout(); 74 | this.mailBoxIsFullTabPage.SuspendLayout(); 75 | this.NotParsedLogLinesTabPage.SuspendLayout(); 76 | this.bouncedMessagesTabPage.SuspendLayout(); 77 | this.dovecotAuthenticatorFailedTabPage.SuspendLayout(); 78 | this.deliveryDeferredTabPage.SuspendLayout(); 79 | this.groupBox1.SuspendLayout(); 80 | this.menuStrip1.SuspendLayout(); 81 | this.SuspendLayout(); 82 | // 83 | // tabControl1 84 | // 85 | this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 86 | | System.Windows.Forms.AnchorStyles.Left) 87 | | System.Windows.Forms.AnchorStyles.Right))); 88 | this.tabControl1.Controls.Add(this.mailsTabPage); 89 | this.tabControl1.Controls.Add(this.findInLogTabPage); 90 | this.tabControl1.Controls.Add(this.mailBoxIsFullTabPage); 91 | this.tabControl1.Controls.Add(this.NotParsedLogLinesTabPage); 92 | this.tabControl1.Controls.Add(this.bouncedMessagesTabPage); 93 | this.tabControl1.Controls.Add(this.dovecotAuthenticatorFailedTabPage); 94 | this.tabControl1.Controls.Add(this.deliveryDeferredTabPage); 95 | this.tabControl1.Location = new System.Drawing.Point(13, 86); 96 | this.tabControl1.Name = "tabControl1"; 97 | this.tabControl1.SelectedIndex = 0; 98 | this.tabControl1.Size = new System.Drawing.Size(1000, 428); 99 | this.tabControl1.TabIndex = 9; 100 | // 101 | // mailsTabPage 102 | // 103 | this.mailsTabPage.Controls.Add(this.gridGroupingControl1); 104 | this.mailsTabPage.Location = new System.Drawing.Point(4, 22); 105 | this.mailsTabPage.Name = "mailsTabPage"; 106 | this.mailsTabPage.Size = new System.Drawing.Size(992, 402); 107 | this.mailsTabPage.TabIndex = 3; 108 | this.mailsTabPage.Text = "Mails"; 109 | this.mailsTabPage.UseVisualStyleBackColor = true; 110 | // 111 | // gridGroupingControl1 112 | // 113 | this.gridGroupingControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 114 | | System.Windows.Forms.AnchorStyles.Left) 115 | | System.Windows.Forms.AnchorStyles.Right))); 116 | this.gridGroupingControl1.BackColor = System.Drawing.SystemColors.Window; 117 | this.gridGroupingControl1.ColorStyles = Syncfusion.Windows.Forms.ColorStyles.Office2010Silver; 118 | this.gridGroupingControl1.FreezeCaption = false; 119 | this.gridGroupingControl1.GridOfficeScrollBars = Syncfusion.Windows.Forms.OfficeScrollBars.Office2007; 120 | this.gridGroupingControl1.GridVisualStyles = Syncfusion.Windows.Forms.GridVisualStyles.Office2010Silver; 121 | this.gridGroupingControl1.Location = new System.Drawing.Point(5, 5); 122 | this.gridGroupingControl1.Name = "gridGroupingControl1"; 123 | this.gridGroupingControl1.Office2007ScrollBars = true; 124 | this.gridGroupingControl1.ShowGroupDropArea = true; 125 | this.gridGroupingControl1.Size = new System.Drawing.Size(984, 394); 126 | this.gridGroupingControl1.TabIndex = 0; 127 | this.gridGroupingControl1.Text = "gridGroupingControl1"; 128 | this.gridGroupingControl1.VersionInfo = "13.4460.0.53"; 129 | // 130 | // findInLogTabPage 131 | // 132 | this.findInLogTabPage.Controls.Add(this.findButton); 133 | this.findInLogTabPage.Controls.Add(this.textBox1); 134 | this.findInLogTabPage.Controls.Add(this.findInCurrentLogRichTextBox); 135 | this.findInLogTabPage.Location = new System.Drawing.Point(4, 22); 136 | this.findInLogTabPage.Name = "findInLogTabPage"; 137 | this.findInLogTabPage.Size = new System.Drawing.Size(992, 402); 138 | this.findInLogTabPage.TabIndex = 2; 139 | this.findInLogTabPage.Text = "Find In Log"; 140 | this.findInLogTabPage.UseVisualStyleBackColor = true; 141 | // 142 | // findButton 143 | // 144 | this.findButton.Location = new System.Drawing.Point(290, 3); 145 | this.findButton.Name = "findButton"; 146 | this.findButton.Size = new System.Drawing.Size(75, 23); 147 | this.findButton.TabIndex = 5; 148 | this.findButton.Text = "Find"; 149 | this.findButton.UseVisualStyleBackColor = true; 150 | this.findButton.Click += new System.EventHandler(this.findButton_Click); 151 | // 152 | // textBox1 153 | // 154 | this.textBox1.Location = new System.Drawing.Point(5, 5); 155 | this.textBox1.Name = "textBox1"; 156 | this.textBox1.Size = new System.Drawing.Size(278, 20); 157 | this.textBox1.TabIndex = 4; 158 | // 159 | // findInCurrentLogRichTextBox 160 | // 161 | this.findInCurrentLogRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 162 | | System.Windows.Forms.AnchorStyles.Left) 163 | | System.Windows.Forms.AnchorStyles.Right))); 164 | this.findInCurrentLogRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 165 | this.findInCurrentLogRichTextBox.Location = new System.Drawing.Point(5, 31); 166 | this.findInCurrentLogRichTextBox.Name = "findInCurrentLogRichTextBox"; 167 | this.findInCurrentLogRichTextBox.Size = new System.Drawing.Size(984, 379); 168 | this.findInCurrentLogRichTextBox.TabIndex = 3; 169 | this.findInCurrentLogRichTextBox.Text = ""; 170 | // 171 | // mailBoxIsFullTabPage 172 | // 173 | this.mailBoxIsFullTabPage.Controls.Add(this.mailBoxIsFullRichTextBox); 174 | this.mailBoxIsFullTabPage.Location = new System.Drawing.Point(4, 22); 175 | this.mailBoxIsFullTabPage.Name = "mailBoxIsFullTabPage"; 176 | this.mailBoxIsFullTabPage.Size = new System.Drawing.Size(992, 402); 177 | this.mailBoxIsFullTabPage.TabIndex = 4; 178 | this.mailBoxIsFullTabPage.Text = "Mailbox Is Full"; 179 | this.mailBoxIsFullTabPage.UseVisualStyleBackColor = true; 180 | // 181 | // mailBoxIsFullRichTextBox 182 | // 183 | this.mailBoxIsFullRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 184 | | System.Windows.Forms.AnchorStyles.Left) 185 | | System.Windows.Forms.AnchorStyles.Right))); 186 | this.mailBoxIsFullRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 187 | this.mailBoxIsFullRichTextBox.Location = new System.Drawing.Point(5, 5); 188 | this.mailBoxIsFullRichTextBox.Name = "mailBoxIsFullRichTextBox"; 189 | this.mailBoxIsFullRichTextBox.Size = new System.Drawing.Size(984, 405); 190 | this.mailBoxIsFullRichTextBox.TabIndex = 1; 191 | this.mailBoxIsFullRichTextBox.Text = ""; 192 | // 193 | // NotParsedLogLinesTabPage 194 | // 195 | this.NotParsedLogLinesTabPage.Controls.Add(this.notParsedLogLinesRichTextBox); 196 | this.NotParsedLogLinesTabPage.Location = new System.Drawing.Point(4, 22); 197 | this.NotParsedLogLinesTabPage.Name = "NotParsedLogLinesTabPage"; 198 | this.NotParsedLogLinesTabPage.Padding = new System.Windows.Forms.Padding(3); 199 | this.NotParsedLogLinesTabPage.Size = new System.Drawing.Size(992, 402); 200 | this.NotParsedLogLinesTabPage.TabIndex = 1; 201 | this.NotParsedLogLinesTabPage.Text = "Not Parsed Log Lines"; 202 | this.NotParsedLogLinesTabPage.UseVisualStyleBackColor = true; 203 | // 204 | // notParsedLogLinesRichTextBox 205 | // 206 | this.notParsedLogLinesRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 207 | | System.Windows.Forms.AnchorStyles.Left) 208 | | System.Windows.Forms.AnchorStyles.Right))); 209 | this.notParsedLogLinesRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 210 | this.notParsedLogLinesRichTextBox.Location = new System.Drawing.Point(5, 5); 211 | this.notParsedLogLinesRichTextBox.Name = "notParsedLogLinesRichTextBox"; 212 | this.notParsedLogLinesRichTextBox.Size = new System.Drawing.Size(984, 405); 213 | this.notParsedLogLinesRichTextBox.TabIndex = 1; 214 | this.notParsedLogLinesRichTextBox.Text = ""; 215 | // 216 | // bouncedMessagesTabPage 217 | // 218 | this.bouncedMessagesTabPage.Controls.Add(this.bounceMessagesRichTextBox); 219 | this.bouncedMessagesTabPage.Location = new System.Drawing.Point(4, 22); 220 | this.bouncedMessagesTabPage.Name = "bouncedMessagesTabPage"; 221 | this.bouncedMessagesTabPage.Padding = new System.Windows.Forms.Padding(3); 222 | this.bouncedMessagesTabPage.Size = new System.Drawing.Size(992, 402); 223 | this.bouncedMessagesTabPage.TabIndex = 0; 224 | this.bouncedMessagesTabPage.Text = "Bounced Messages"; 225 | this.bouncedMessagesTabPage.UseVisualStyleBackColor = true; 226 | // 227 | // bounceMessagesRichTextBox 228 | // 229 | this.bounceMessagesRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 230 | | System.Windows.Forms.AnchorStyles.Left) 231 | | System.Windows.Forms.AnchorStyles.Right))); 232 | this.bounceMessagesRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 233 | this.bounceMessagesRichTextBox.Location = new System.Drawing.Point(5, 5); 234 | this.bounceMessagesRichTextBox.Name = "bounceMessagesRichTextBox"; 235 | this.bounceMessagesRichTextBox.Size = new System.Drawing.Size(984, 405); 236 | this.bounceMessagesRichTextBox.TabIndex = 0; 237 | this.bounceMessagesRichTextBox.Text = ""; 238 | // 239 | // dovecotAuthenticatorFailedTabPage 240 | // 241 | this.dovecotAuthenticatorFailedTabPage.Controls.Add(this.richTextBox2); 242 | this.dovecotAuthenticatorFailedTabPage.Location = new System.Drawing.Point(4, 22); 243 | this.dovecotAuthenticatorFailedTabPage.Name = "dovecotAuthenticatorFailedTabPage"; 244 | this.dovecotAuthenticatorFailedTabPage.Size = new System.Drawing.Size(992, 402); 245 | this.dovecotAuthenticatorFailedTabPage.TabIndex = 5; 246 | this.dovecotAuthenticatorFailedTabPage.Text = "Dovecot Authenticator Failed"; 247 | this.dovecotAuthenticatorFailedTabPage.UseVisualStyleBackColor = true; 248 | // 249 | // richTextBox2 250 | // 251 | this.richTextBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 252 | | System.Windows.Forms.AnchorStyles.Left) 253 | | System.Windows.Forms.AnchorStyles.Right))); 254 | this.richTextBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 255 | this.richTextBox2.Location = new System.Drawing.Point(5, 5); 256 | this.richTextBox2.Name = "richTextBox2"; 257 | this.richTextBox2.Size = new System.Drawing.Size(984, 405); 258 | this.richTextBox2.TabIndex = 1; 259 | this.richTextBox2.Text = ""; 260 | // 261 | // deliveryDeferredTabPage 262 | // 263 | this.deliveryDeferredTabPage.Controls.Add(this.DeliveryDeferredRichTextBox); 264 | this.deliveryDeferredTabPage.Location = new System.Drawing.Point(4, 22); 265 | this.deliveryDeferredTabPage.Name = "deliveryDeferredTabPage"; 266 | this.deliveryDeferredTabPage.Size = new System.Drawing.Size(992, 402); 267 | this.deliveryDeferredTabPage.TabIndex = 6; 268 | this.deliveryDeferredTabPage.Text = "Delivery Deferred"; 269 | this.deliveryDeferredTabPage.UseVisualStyleBackColor = true; 270 | // 271 | // DeliveryDeferredRichTextBox 272 | // 273 | this.DeliveryDeferredRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 274 | | System.Windows.Forms.AnchorStyles.Left) 275 | | System.Windows.Forms.AnchorStyles.Right))); 276 | this.DeliveryDeferredRichTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.25F); 277 | this.DeliveryDeferredRichTextBox.Location = new System.Drawing.Point(5, 5); 278 | this.DeliveryDeferredRichTextBox.Name = "DeliveryDeferredRichTextBox"; 279 | this.DeliveryDeferredRichTextBox.Size = new System.Drawing.Size(984, 405); 280 | this.DeliveryDeferredRichTextBox.TabIndex = 2; 281 | this.DeliveryDeferredRichTextBox.Text = ""; 282 | // 283 | // logFilesComboBox 284 | // 285 | this.logFilesComboBox.FormattingEnabled = true; 286 | this.logFilesComboBox.Location = new System.Drawing.Point(703, 24); 287 | this.logFilesComboBox.Name = "logFilesComboBox"; 288 | this.logFilesComboBox.Size = new System.Drawing.Size(206, 21); 289 | this.logFilesComboBox.TabIndex = 7; 290 | this.logFilesComboBox.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); 291 | // 292 | // connectButton 293 | // 294 | this.connectButton.Location = new System.Drawing.Point(391, 25); 295 | this.connectButton.Name = "connectButton"; 296 | this.connectButton.Size = new System.Drawing.Size(100, 21); 297 | this.connectButton.TabIndex = 5; 298 | this.connectButton.Text = "Connect"; 299 | this.connectButton.UseVisualStyleBackColor = true; 300 | this.connectButton.Click += new System.EventHandler(this.connectButton_Click); 301 | // 302 | // refreshButton 303 | // 304 | this.refreshButton.Enabled = false; 305 | this.refreshButton.Location = new System.Drawing.Point(915, 24); 306 | this.refreshButton.Name = "refreshButton"; 307 | this.refreshButton.Size = new System.Drawing.Size(75, 21); 308 | this.refreshButton.TabIndex = 8; 309 | this.refreshButton.Text = "Refresh"; 310 | this.refreshButton.UseVisualStyleBackColor = true; 311 | this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click); 312 | // 313 | // timer1 314 | // 315 | this.timer1.Enabled = true; 316 | this.timer1.Interval = 1000; 317 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 318 | // 319 | // groupBox1 320 | // 321 | this.groupBox1.Controls.Add(this.portLabel); 322 | this.groupBox1.Controls.Add(this.portTextBox); 323 | this.groupBox1.Controls.Add(this.label1); 324 | this.groupBox1.Controls.Add(this.logPathLabel); 325 | this.groupBox1.Controls.Add(this.logPathTextBox); 326 | this.groupBox1.Controls.Add(this.passwordLabel); 327 | this.groupBox1.Controls.Add(this.refreshButton); 328 | this.groupBox1.Controls.Add(this.passwordTextBox); 329 | this.groupBox1.Controls.Add(this.logFilesComboBox); 330 | this.groupBox1.Controls.Add(this.connectButton); 331 | this.groupBox1.Controls.Add(this.loginLabel); 332 | this.groupBox1.Controls.Add(this.loginTextBox); 333 | this.groupBox1.Controls.Add(this.hostnameLabel); 334 | this.groupBox1.Controls.Add(this.hostnameTextBox); 335 | this.groupBox1.Location = new System.Drawing.Point(13, 22); 336 | this.groupBox1.Name = "groupBox1"; 337 | this.groupBox1.Size = new System.Drawing.Size(997, 58); 338 | this.groupBox1.TabIndex = 7; 339 | this.groupBox1.TabStop = false; 340 | // 341 | // portLabel 342 | // 343 | this.portLabel.AutoSize = true; 344 | this.portLabel.Location = new System.Drawing.Point(112, 8); 345 | this.portLabel.Name = "portLabel"; 346 | this.portLabel.Size = new System.Drawing.Size(29, 13); 347 | this.portLabel.TabIndex = 11; 348 | this.portLabel.Text = "Port:"; 349 | // 350 | // portTextBox 351 | // 352 | this.portTextBox.Location = new System.Drawing.Point(115, 25); 353 | this.portTextBox.Name = "portTextBox"; 354 | this.portTextBox.Size = new System.Drawing.Size(58, 20); 355 | this.portTextBox.TabIndex = 2; 356 | // 357 | // label1 358 | // 359 | this.label1.AutoSize = true; 360 | this.label1.Location = new System.Drawing.Point(700, 8); 361 | this.label1.Name = "label1"; 362 | this.label1.Size = new System.Drawing.Size(52, 13); 363 | this.label1.TabIndex = 9; 364 | this.label1.Text = "Log Files:"; 365 | // 366 | // logPathLabel 367 | // 368 | this.logPathLabel.AutoSize = true; 369 | this.logPathLabel.Location = new System.Drawing.Point(494, 9); 370 | this.logPathLabel.Name = "logPathLabel"; 371 | this.logPathLabel.Size = new System.Drawing.Size(53, 13); 372 | this.logPathLabel.TabIndex = 8; 373 | this.logPathLabel.Text = "Log Path:"; 374 | // 375 | // logPathTextBox 376 | // 377 | this.logPathTextBox.Location = new System.Drawing.Point(497, 25); 378 | this.logPathTextBox.Name = "logPathTextBox"; 379 | this.logPathTextBox.Size = new System.Drawing.Size(200, 20); 380 | this.logPathTextBox.TabIndex = 6; 381 | // 382 | // passwordLabel 383 | // 384 | this.passwordLabel.AutoSize = true; 385 | this.passwordLabel.Location = new System.Drawing.Point(282, 9); 386 | this.passwordLabel.Name = "passwordLabel"; 387 | this.passwordLabel.Size = new System.Drawing.Size(56, 13); 388 | this.passwordLabel.TabIndex = 5; 389 | this.passwordLabel.Text = "Password:"; 390 | // 391 | // passwordTextBox 392 | // 393 | this.passwordTextBox.Location = new System.Drawing.Point(285, 25); 394 | this.passwordTextBox.Name = "passwordTextBox"; 395 | this.passwordTextBox.Size = new System.Drawing.Size(100, 20); 396 | this.passwordTextBox.TabIndex = 4; 397 | this.passwordTextBox.UseSystemPasswordChar = true; 398 | // 399 | // loginLabel 400 | // 401 | this.loginLabel.AutoSize = true; 402 | this.loginLabel.Location = new System.Drawing.Point(176, 9); 403 | this.loginLabel.Name = "loginLabel"; 404 | this.loginLabel.Size = new System.Drawing.Size(36, 13); 405 | this.loginLabel.TabIndex = 3; 406 | this.loginLabel.Text = "Login:"; 407 | // 408 | // loginTextBox 409 | // 410 | this.loginTextBox.Location = new System.Drawing.Point(179, 25); 411 | this.loginTextBox.Name = "loginTextBox"; 412 | this.loginTextBox.Size = new System.Drawing.Size(100, 20); 413 | this.loginTextBox.TabIndex = 3; 414 | // 415 | // hostnameLabel 416 | // 417 | this.hostnameLabel.AutoSize = true; 418 | this.hostnameLabel.Location = new System.Drawing.Point(6, 9); 419 | this.hostnameLabel.Name = "hostnameLabel"; 420 | this.hostnameLabel.Size = new System.Drawing.Size(58, 13); 421 | this.hostnameLabel.TabIndex = 1; 422 | this.hostnameLabel.Text = "Hostname:"; 423 | // 424 | // hostnameTextBox 425 | // 426 | this.hostnameTextBox.Location = new System.Drawing.Point(9, 25); 427 | this.hostnameTextBox.Name = "hostnameTextBox"; 428 | this.hostnameTextBox.Size = new System.Drawing.Size(100, 20); 429 | this.hostnameTextBox.TabIndex = 1; 430 | // 431 | // menuStrip1 432 | // 433 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 434 | this.openLogFileToolStripMenuItem}); 435 | this.menuStrip1.Location = new System.Drawing.Point(0, 0); 436 | this.menuStrip1.Name = "menuStrip1"; 437 | this.menuStrip1.Size = new System.Drawing.Size(1025, 24); 438 | this.menuStrip1.TabIndex = 10; 439 | this.menuStrip1.Text = "menuStrip1"; 440 | // 441 | // openLogFileToolStripMenuItem 442 | // 443 | this.openLogFileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 444 | this.openToolStripMenuItem}); 445 | this.openLogFileToolStripMenuItem.Name = "openLogFileToolStripMenuItem"; 446 | this.openLogFileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); 447 | this.openLogFileToolStripMenuItem.Text = "File"; 448 | // 449 | // openToolStripMenuItem 450 | // 451 | this.openToolStripMenuItem.Name = "openToolStripMenuItem"; 452 | this.openToolStripMenuItem.Size = new System.Drawing.Size(112, 22); 453 | this.openToolStripMenuItem.Text = "Open..."; 454 | this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); 455 | // 456 | // MainForm 457 | // 458 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 459 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 460 | this.ClientSize = new System.Drawing.Size(1025, 526); 461 | this.Controls.Add(this.groupBox1); 462 | this.Controls.Add(this.tabControl1); 463 | this.Controls.Add(this.menuStrip1); 464 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 465 | this.MainMenuStrip = this.menuStrip1; 466 | this.Name = "MainForm"; 467 | this.Text = "DmxEngine EximLogAnalyzer v1.0.20220203"; 468 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); 469 | this.Load += new System.EventHandler(this.MainForm_Load); 470 | this.tabControl1.ResumeLayout(false); 471 | this.mailsTabPage.ResumeLayout(false); 472 | ((System.ComponentModel.ISupportInitialize)(this.gridGroupingControl1)).EndInit(); 473 | this.findInLogTabPage.ResumeLayout(false); 474 | this.findInLogTabPage.PerformLayout(); 475 | this.mailBoxIsFullTabPage.ResumeLayout(false); 476 | this.NotParsedLogLinesTabPage.ResumeLayout(false); 477 | this.bouncedMessagesTabPage.ResumeLayout(false); 478 | this.dovecotAuthenticatorFailedTabPage.ResumeLayout(false); 479 | this.deliveryDeferredTabPage.ResumeLayout(false); 480 | this.groupBox1.ResumeLayout(false); 481 | this.groupBox1.PerformLayout(); 482 | this.menuStrip1.ResumeLayout(false); 483 | this.menuStrip1.PerformLayout(); 484 | this.ResumeLayout(false); 485 | this.PerformLayout(); 486 | 487 | } 488 | 489 | #endregion 490 | private System.Windows.Forms.TabControl tabControl1; 491 | private System.Windows.Forms.TabPage bouncedMessagesTabPage; 492 | private System.Windows.Forms.RichTextBox bounceMessagesRichTextBox; 493 | private System.Windows.Forms.TabPage NotParsedLogLinesTabPage; 494 | private System.Windows.Forms.RichTextBox notParsedLogLinesRichTextBox; 495 | private System.Windows.Forms.TabPage findInLogTabPage; 496 | private System.Windows.Forms.Button findButton; 497 | private System.Windows.Forms.TextBox textBox1; 498 | private System.Windows.Forms.RichTextBox findInCurrentLogRichTextBox; 499 | private System.Windows.Forms.TabPage mailsTabPage; 500 | private Syncfusion.Windows.Forms.Grid.Grouping.GridGroupingControl gridGroupingControl1; 501 | private System.Windows.Forms.ComboBox logFilesComboBox; 502 | private System.Windows.Forms.Button connectButton; 503 | private System.Windows.Forms.TabPage mailBoxIsFullTabPage; 504 | private System.Windows.Forms.RichTextBox mailBoxIsFullRichTextBox; 505 | private System.Windows.Forms.TabPage dovecotAuthenticatorFailedTabPage; 506 | private System.Windows.Forms.RichTextBox richTextBox2; 507 | private System.Windows.Forms.TabPage deliveryDeferredTabPage; 508 | private System.Windows.Forms.RichTextBox DeliveryDeferredRichTextBox; 509 | private System.Windows.Forms.Button refreshButton; 510 | private System.Windows.Forms.Timer timer1; 511 | private System.Windows.Forms.GroupBox groupBox1; 512 | private System.Windows.Forms.Label passwordLabel; 513 | private System.Windows.Forms.TextBox passwordTextBox; 514 | private System.Windows.Forms.Label loginLabel; 515 | private System.Windows.Forms.TextBox loginTextBox; 516 | private System.Windows.Forms.Label hostnameLabel; 517 | private System.Windows.Forms.TextBox hostnameTextBox; 518 | private System.Windows.Forms.TextBox logPathTextBox; 519 | private System.Windows.Forms.Label label1; 520 | private System.Windows.Forms.Label logPathLabel; 521 | private System.Windows.Forms.Label portLabel; 522 | private System.Windows.Forms.TextBox portTextBox; 523 | private System.Windows.Forms.MenuStrip menuStrip1; 524 | private System.Windows.Forms.ToolStripMenuItem openLogFileToolStripMenuItem; 525 | private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; 526 | private System.Windows.Forms.OpenFileDialog openFileDialog1; 527 | } 528 | } 529 | 530 | -------------------------------------------------------------------------------- /EximLogAnalyzer/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.IO.Compression; 7 | using System.Linq; 8 | using System.Windows.Forms; 9 | using EximLogAnalyzer.Models; 10 | using Renci.SshNet; 11 | using Yandex.Metrica; 12 | 13 | namespace EximLogAnalyzer 14 | { 15 | public partial class MainForm : Form 16 | { 17 | private SshClient _sshClient; 18 | private Stream _currentLogStream; 19 | private LogParser _logParser = new LogParser(); 20 | private Config _config; 21 | 22 | private Color defaultColor; 23 | 24 | public MainForm() 25 | { 26 | InitializeComponent(); 27 | YandexMetricaFolder.SetCurrent(""); 28 | YandexMetrica.Activate("eafbf946-7082-4f83-aef3-6e99c1911a62"); 29 | AppDomain.CurrentDomain.UnhandledException += Application_ThreadException; 30 | defaultColor = hostnameTextBox.BackColor; 31 | } 32 | 33 | private void Application_ThreadException(object sender, UnhandledExceptionEventArgs e) 34 | { 35 | Exception ex = (Exception)e.ExceptionObject; 36 | YandexMetrica.ReportError(ex.Message, ex); 37 | MessageBox.Show(ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 38 | } 39 | 40 | private void DisplayResult() 41 | { 42 | ArrayList al = new ArrayList(); 43 | 44 | foreach (KeyValuePair value in _logParser.ResultDict) 45 | { 46 | Mail mail = value.Value; 47 | if (mail.DeliveryStatus.Count == 0) 48 | { 49 | Data data = new Data(); 50 | data.Id = mail.Id; 51 | data.SenderAddress = mail.SenderAddress; 52 | data.SenderHostname = mail.SenderHostname; 53 | data.SenderIpAddress = mail.SenderIpAddress; 54 | data.Completed = mail.Completed.ToString(); 55 | data.StartTime = mail.StartTime.ToString(); 56 | data.EndTime = mail.EndTime.ToString(); 57 | data.Subject = mail.Subject; 58 | data.Delivered = "True/Manual"; 59 | data.RecipientAddress = mail.RecipientAddress; 60 | data.Size = mail.Size.ToString(); 61 | al.Add(data); 62 | } 63 | foreach (DeliveryStatus status in mail.DeliveryStatus) 64 | { 65 | Data data = new Data(); 66 | data.Id = mail.Id; 67 | data.SenderAddress = mail.SenderAddress; 68 | data.SenderHostname = mail.SenderHostname; 69 | data.SenderIpAddress = mail.SenderIpAddress; 70 | data.Completed = mail.Completed.ToString(); 71 | data.Deferred = status.Deferred.ToString(); 72 | data.StartTime = mail.StartTime.ToString(); 73 | data.EndTime = mail.EndTime.ToString(); 74 | data.Subject = mail.Subject; 75 | data.Delivered = status.Delivered.ToString(); 76 | data.RecipientAddress = status.RecipientAddress; 77 | data.QueryTime = status.QueryTime; 78 | data.DeliveryTime = status.DeliveryTime; 79 | data.Status = status.StatusMessage; 80 | data.DeliveredTime = status.Time.ToString(); 81 | data.Size = mail.Size.ToString(); 82 | al.Add(data); 83 | } 84 | } 85 | gridGroupingControl1.DataSource = al; 86 | } 87 | 88 | private void DisplayNotParsedLines() 89 | { 90 | notParsedLogLinesRichTextBox.Clear(); 91 | foreach (var line in _logParser.NotParsedLogLines) 92 | { 93 | notParsedLogLinesRichTextBox.AppendText(line + "\r\n"); 94 | notParsedLogLinesRichTextBox.AppendText("\r\n"); 95 | } 96 | } 97 | 98 | private void DisplayMailBoxIsFull() 99 | { 100 | mailBoxIsFullRichTextBox.Clear(); 101 | foreach (var line in _logParser.MailBoxIsFull) 102 | { 103 | mailBoxIsFullRichTextBox.AppendText(line + "\r\n"); 104 | mailBoxIsFullRichTextBox.AppendText("\r\n"); 105 | } 106 | } 107 | 108 | private void DisplayBounceMessages() 109 | { 110 | bounceMessagesRichTextBox.Clear(); 111 | foreach (var line in _logParser.BounceMessages) 112 | { 113 | bounceMessagesRichTextBox.AppendText(line + "\r\n"); 114 | bounceMessagesRichTextBox.AppendText("\r\n"); 115 | } 116 | } 117 | 118 | private void DisplayDeliveryDeferredMessages() 119 | { 120 | DeliveryDeferredRichTextBox.Clear(); 121 | foreach (var line in _logParser.DeliveryDeferred) 122 | { 123 | DeliveryDeferredRichTextBox.AppendText(line + "\r\n"); 124 | DeliveryDeferredRichTextBox.AppendText("\r\n"); 125 | } 126 | } 127 | 128 | private void DisplayDovecotLoginAuthenticatorFailed() 129 | { 130 | richTextBox2.Clear(); 131 | foreach (var line in _logParser.DovecotAuthenticatorFailed) 132 | { 133 | richTextBox2.AppendText(line + "\r\n"); 134 | richTextBox2.AppendText("\r\n"); 135 | } 136 | } 137 | 138 | private void findButton_Click(object sender, EventArgs e) 139 | { 140 | findInCurrentLogRichTextBox.Clear(); 141 | if (_currentLogStream != null) 142 | { 143 | _currentLogStream.Seek(0, SeekOrigin.Begin); 144 | StreamReader sr = new StreamReader(_currentLogStream); 145 | while (!sr.EndOfStream) 146 | { 147 | string logLine = sr.ReadLine(); 148 | if (logLine != null && logLine.Contains(textBox1.Text)) 149 | { 150 | findInCurrentLogRichTextBox.AppendText(logLine + "\r\n\r\n"); 151 | } 152 | } 153 | } 154 | } 155 | 156 | private void connectButton_Click(object sender, EventArgs e) 157 | { 158 | bool formInvalid = false; 159 | 160 | if (string.IsNullOrWhiteSpace(hostnameTextBox.Text)) 161 | { 162 | formInvalid = true; 163 | hostnameTextBox.BackColor = Color.Pink; 164 | } 165 | else 166 | { 167 | hostnameTextBox.BackColor = defaultColor; 168 | } 169 | 170 | if (!int.TryParse(portTextBox.Text.Trim(), out int port)) 171 | { 172 | formInvalid = true; 173 | portTextBox.BackColor = Color.Pink; 174 | } 175 | else 176 | { 177 | portTextBox.BackColor = defaultColor; 178 | } 179 | 180 | if (string.IsNullOrWhiteSpace(loginTextBox.Text)) 181 | { 182 | formInvalid = true; 183 | loginTextBox.BackColor = Color.Pink; 184 | } 185 | else 186 | { 187 | loginTextBox.BackColor = defaultColor; 188 | } 189 | 190 | if (string.IsNullOrWhiteSpace(passwordTextBox.Text)) 191 | { 192 | formInvalid = true; 193 | passwordTextBox.BackColor = Color.Pink; 194 | } 195 | else 196 | { 197 | passwordTextBox.BackColor = defaultColor; 198 | } 199 | 200 | if (formInvalid) 201 | { 202 | return; 203 | } 204 | 205 | if (_sshClient == null || _sshClient.IsConnected == false) 206 | { 207 | _sshClient = new SshClient(hostnameTextBox.Text, port, loginTextBox.Text, passwordTextBox.Text); 208 | try 209 | { 210 | _sshClient.Connect(); 211 | GetLogList(logPathTextBox.Text); 212 | } 213 | catch (Exception ex) 214 | { 215 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 216 | } 217 | return; 218 | } 219 | if (_sshClient.IsConnected) 220 | { 221 | logFilesComboBox.Items.Clear(); 222 | _sshClient.Disconnect(); 223 | } 224 | } 225 | 226 | private void GetLogList(string path) 227 | { 228 | path = path.TrimEnd('/'); 229 | logFilesComboBox.Items.Clear(); 230 | if (_sshClient != null && _sshClient.IsConnected) 231 | { 232 | try 233 | { 234 | SshCommand sshCommand = _sshClient.CreateCommand(string.Format("ls {0}", path)); 235 | List result = sshCommand.Execute().Split().ToList(); 236 | foreach (string item in result) 237 | { 238 | logFilesComboBox.Items.Add(item); 239 | } 240 | } 241 | catch (Exception ex) 242 | { 243 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 244 | } 245 | } 246 | } 247 | 248 | private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 249 | { 250 | try 251 | { 252 | _currentLogStream = new MemoryStream(); 253 | string logPath = logPathTextBox.Text.TrimEnd('/'); 254 | SftpClient sftpClient = new SftpClient(hostnameTextBox.Text, loginTextBox.Text, passwordTextBox.Text); 255 | sftpClient.Connect(); 256 | sftpClient.DownloadFile(string.Format("{0}/{1}", logPath, logFilesComboBox.Text), _currentLogStream); 257 | _currentLogStream.Seek(0, SeekOrigin.Begin); 258 | MemoryStream decompressedStream; 259 | if (logFilesComboBox.Text.Contains(".gz")) 260 | { 261 | decompressedStream = DecompressStream(_currentLogStream); 262 | _currentLogStream = decompressedStream; 263 | _logParser.ParseEximMainLog(decompressedStream); 264 | } 265 | else 266 | { 267 | _logParser.ParseEximMainLog(_currentLogStream); 268 | } 269 | DisplayResult(); 270 | DisplayMailBoxIsFull(); 271 | DisplayNotParsedLines(); 272 | DisplayBounceMessages(); 273 | DisplayDovecotLoginAuthenticatorFailed(); 274 | DisplayDeliveryDeferredMessages(); 275 | } 276 | catch (Exception ex) 277 | { 278 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 279 | } 280 | } 281 | 282 | private MemoryStream DecompressStream(Stream inputStream) 283 | { 284 | GZipStream stream = new GZipStream(inputStream, CompressionMode.Decompress); 285 | const int size = 4096; 286 | byte[] buffer = new byte[size]; 287 | MemoryStream memory = new MemoryStream(); 288 | int count; 289 | do 290 | { 291 | count = stream.Read(buffer, 0, size); 292 | if (count > 0) 293 | { 294 | memory.Write(buffer, 0, count); 295 | } 296 | } 297 | while (count > 0); 298 | memory.Seek(0, SeekOrigin.Begin); 299 | return memory; 300 | } 301 | 302 | private void timer1_Tick(object sender, EventArgs e) 303 | { 304 | if (_sshClient == null || _sshClient.IsConnected == false) 305 | { 306 | connectButton.Text = "Connect"; 307 | refreshButton.Enabled = false; 308 | } 309 | 310 | if (_sshClient != null && _sshClient.IsConnected) 311 | { 312 | connectButton.Text = "Disconnect"; 313 | refreshButton.Enabled = true; 314 | } 315 | } 316 | 317 | private void refreshButton_Click(object sender, EventArgs e) 318 | { 319 | GetLogList(logPathTextBox.Text); 320 | } 321 | 322 | private void MainForm_Load(object sender, EventArgs e) 323 | { 324 | _config = new Config(); 325 | if (File.Exists("Config.xml")) 326 | { 327 | _config = Config.LoadConfig("Config.xml"); 328 | } 329 | hostnameTextBox.Text = _config.Hostname; 330 | loginTextBox.Text = _config.Login; 331 | passwordTextBox.Text = _config.Password; 332 | logPathTextBox.Text = _config.LogPath; 333 | } 334 | 335 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 336 | { 337 | _config.Hostname = hostnameTextBox.Text; 338 | _config.Login = loginTextBox.Text; 339 | _config.Password = passwordTextBox.Text; 340 | _config.LogPath = logPathTextBox.Text; 341 | try 342 | { 343 | Config.SaveConfig(_config, "Config.xml"); 344 | } 345 | catch (Exception ex) 346 | { 347 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 348 | } 349 | } 350 | 351 | private void openToolStripMenuItem_Click(object sender, EventArgs e) 352 | { 353 | try 354 | { 355 | if (openFileDialog1.ShowDialog() == DialogResult.OK) 356 | { 357 | if (File.Exists(openFileDialog1.FileName)) 358 | { 359 | using (FileStream logFileStream = File.Open(openFileDialog1.FileName, FileMode.Open)) 360 | { 361 | _logParser.ParseEximMainLog(logFileStream); 362 | DisplayResult(); 363 | DisplayMailBoxIsFull(); 364 | DisplayNotParsedLines(); 365 | DisplayBounceMessages(); 366 | DisplayDovecotLoginAuthenticatorFailed(); 367 | DisplayDeliveryDeferredMessages(); 368 | } 369 | } 370 | } 371 | } 372 | catch (Exception ex) 373 | { 374 | MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 375 | } 376 | } 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Models/DeliveryStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EximLogAnalyzer.Models 4 | { 5 | public class DeliveryStatus 6 | { 7 | public string MailId { get; set; } 8 | public string RecipientAddress { get; set; } 9 | public string StatusMessage { get; set; } 10 | public bool Delivered { get; set; } 11 | public bool Deferred { get; set; } // == delivery deferred; temporary problem 12 | public string QueryTime { get; set; } 13 | public string DeliveryTime { get; set; } 14 | public DateTime Time { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Models/Mail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace EximLogAnalyzer.Models 5 | { 6 | public class Mail 7 | { 8 | public string Id { get; set; } 9 | public DateTime StartTime { get; set; } 10 | public DateTime EndTime { get; set; } 11 | public string SenderAddress { get; set; } 12 | public string SenderHostname { get; set; } 13 | public string SenderIpAddress { get; set; } 14 | public string Subject { get; set; } 15 | public int Size{ get; set; } 16 | public bool Completed { get; set; } 17 | 18 | 19 | public string RecipientAddress { get; set; } 20 | public List DeliveryStatus { get; set; } 21 | 22 | public Mail() 23 | { 24 | DeliveryStatus = new List(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace EximLogAnalyzer 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new MainForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("EximLogAnalyzer")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("DmxEngine")] 11 | [assembly: AssemblyProduct("EximLogAnalyzer")] 12 | [assembly: AssemblyCopyright("Copyright © 2017")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("4b1a24be-9cc1-4ab5-9e53-9f9d8f3c366a")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.2020.1109")] 35 | [assembly: AssemblyFileVersion("1.0.2020.1109")] 36 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace EximLogAnalyzer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EximLogAnalyzer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace EximLogAnalyzer.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EximLogAnalyzer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EximLogAnalyzer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/6bm79qrkmsfd4g7l?svg=true)](https://ci.appveyor.com/project/dmxengine/eximloganalyzer) 2 | # Exim Log Analyzer (log parser) 3 | 4 | This tool help you quickly tell what going on your mail server. Who and when sended or receive mail, delivery status, errors etc. 5 | 6 | ![Exim Log Analyzer Screenshot](https://github.com/dmxengine/EximLogAnalyzer/blob/master/Screenshots/Screenshot-01.png) 7 | ![Exim Log Analyzer Screenshot](https://github.com/dmxengine/EximLogAnalyzer/blob/master/Screenshots/Screenshot-02.png) 8 | -------------------------------------------------------------------------------- /Screenshots/Screenshot-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/Screenshots/Screenshot-01.png -------------------------------------------------------------------------------- /Screenshots/Screenshot-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmxengine/EximLogAnalyzer/e6fe082c6f71b7b5a1875a257523d1d22debd987/Screenshots/Screenshot-02.png -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | before_build: 2 | - nuget restore 3 | 4 | install: 5 | - cinst InnoSetup 6 | 7 | after_build: 8 | - cmd: BuildInstaller.bat 9 | 10 | artifacts: 11 | - path: \Bin\Setup.exe 12 | 13 | configuration: 14 | - Release 15 | --------------------------------------------------------------------------------