├── .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 | [](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 | 
7 | 
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 |
--------------------------------------------------------------------------------