Skip to content

Commit 5e7d1cd

Browse files
Merge pull request #5 from EvotecIT/add-documentation-to-iisparser-project
2 parents 6e5238a + c08e0d9 commit 5e7d1cd

File tree

5 files changed

+220
-0
lines changed

5 files changed

+220
-0
lines changed

IISParser.PowerShell/AsyncPSCmdlet.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,66 @@
77

88
namespace IISParser.PowerShell;
99

10+
/// <summary>
11+
/// Base class for asynchronous PowerShell cmdlets that exposes asynchronous equivalents
12+
/// of the standard <see cref="PSCmdlet"/> lifecycle methods.
13+
/// </summary>
1014
public abstract class AsyncPSCmdlet : PSCmdlet, IDisposable {
1115
private readonly CancellationTokenSource _cancelSource = new();
1216

1317
private BlockingCollection<(object?, PipelineType)>? _currentOutPipe;
1418
private BlockingCollection<object?>? _currentReplyPipe;
1519

20+
/// <summary>
21+
/// Gets a cancellation token that is triggered when the cmdlet is stopped.
22+
/// </summary>
1623
protected internal CancellationToken CancelToken => _cancelSource.Token;
1724

25+
/// <inheritdoc />
1826
public void Dispose() {
1927
_cancelSource?.Dispose();
2028
}
2129

30+
/// <inheritdoc />
2231
protected override void BeginProcessing() {
2332
RunBlockInAsync(BeginProcessingAsync);
2433
}
2534

35+
/// <summary>
36+
/// Asynchronously performs initialization before record processing begins.
37+
/// </summary>
38+
/// <returns>A task representing the asynchronous operation.</returns>
2639
protected virtual Task BeginProcessingAsync() {
2740
return Task.CompletedTask;
2841
}
2942

43+
/// <inheritdoc />
3044
protected override void ProcessRecord() {
3145
RunBlockInAsync(ProcessRecordAsync);
3246
}
3347

48+
/// <summary>
49+
/// Asynchronously processes each record.
50+
/// </summary>
51+
/// <returns>A task representing the asynchronous operation.</returns>
3452
protected virtual Task ProcessRecordAsync() {
3553
return Task.CompletedTask;
3654
}
3755

56+
/// <inheritdoc />
3857
protected override void EndProcessing() {
3958
RunBlockInAsync(EndProcessingAsync);
4059
}
4160

61+
/// <summary>
62+
/// Asynchronously performs cleanup after processing is complete.
63+
/// </summary>
64+
/// <returns>A task representing the asynchronous operation.</returns>
4265
protected virtual Task EndProcessingAsync() {
4366
return Task.CompletedTask;
4467
}
4568

69+
/// <inheritdoc />
4670
protected override void StopProcessing() {
4771
_cancelSource?.Cancel();
4872
}
@@ -100,46 +124,85 @@ private void RunBlockInAsync(Func<Task> task) {
100124
blockTask.GetAwaiter().GetResult();
101125
}
102126

127+
/// <summary>
128+
/// Determines whether the cmdlet should continue processing.
129+
/// </summary>
130+
/// <param name="target">The target of the operation.</param>
131+
/// <param name="action">The action to be performed.</param>
132+
/// <returns><c>true</c> if processing should continue; otherwise, <c>false</c>.</returns>
103133
public new bool ShouldProcess(string target, string action) {
104134
ThrowIfStopped();
105135
_currentOutPipe?.Add(((target, action), PipelineType.ShouldProcess));
106136
return (bool)_currentReplyPipe?.Take(CancelToken)!;
107137
}
108138

139+
/// <summary>
140+
/// Writes an object to the output pipeline.
141+
/// </summary>
142+
/// <param name="sendToPipeline">The object to write.</param>
109143
public new void WriteObject(object? sendToPipeline) {
110144
WriteObject(sendToPipeline, false);
111145
}
112146

147+
/// <summary>
148+
/// Writes an object to the output pipeline with optional enumeration of collections.
149+
/// </summary>
150+
/// <param name="sendToPipeline">The object to write.</param>
151+
/// <param name="enumerateCollection">Whether to enumerate the object if it is a collection.</param>
113152
public new void WriteObject(object? sendToPipeline, bool enumerateCollection) {
114153
ThrowIfStopped();
115154
_currentOutPipe?.Add((sendToPipeline, enumerateCollection ? PipelineType.OutputEnumerate : PipelineType.Output));
116155
}
117156

157+
/// <summary>
158+
/// Writes an error record to the error pipeline.
159+
/// </summary>
160+
/// <param name="errorRecord">The error to write.</param>
118161
public new void WriteError(ErrorRecord errorRecord) {
119162
ThrowIfStopped();
120163
_currentOutPipe?.Add((errorRecord, PipelineType.Error));
121164
}
122165

166+
/// <summary>
167+
/// Writes a warning message to the warning pipeline.
168+
/// </summary>
169+
/// <param name="message">The warning message.</param>
123170
public new void WriteWarning(string message) {
124171
ThrowIfStopped();
125172
_currentOutPipe?.Add((message, PipelineType.Warning));
126173
}
127174

175+
/// <summary>
176+
/// Writes a verbose message to the verbose pipeline.
177+
/// </summary>
178+
/// <param name="message">The verbose message.</param>
128179
public new void WriteVerbose(string message) {
129180
ThrowIfStopped();
130181
_currentOutPipe?.Add((message, PipelineType.Verbose));
131182
}
132183

184+
/// <summary>
185+
/// Writes a debug message to the debug pipeline.
186+
/// </summary>
187+
/// <param name="message">The debug message.</param>
133188
public new void WriteDebug(string message) {
134189
ThrowIfStopped();
135190
_currentOutPipe?.Add((message, PipelineType.Debug));
136191
}
137192

193+
/// <summary>
194+
/// Writes information to the information pipeline.
195+
/// </summary>
196+
/// <param name="informationRecord">The information record.</param>
138197
public new void WriteInformation(InformationRecord informationRecord) {
139198
ThrowIfStopped();
140199
_currentOutPipe?.Add((informationRecord, PipelineType.Information));
141200
}
142201

202+
/// <summary>
203+
/// Writes a progress record to the progress pipeline or directly if asynchronous output is not active.
204+
/// </summary>
205+
/// <param name="progressRecord">The progress record.</param>
143206
public new void WriteProgress(ProgressRecord progressRecord) {
144207
ThrowIfStopped();
145208
if (_currentOutPipe != null) {
@@ -155,6 +218,10 @@ internal void ThrowIfStopped() {
155218
}
156219
}
157220

221+
/// <summary>
222+
/// Retrieves the effective <see cref="ActionPreference"/> for error handling.
223+
/// </summary>
224+
/// <returns>The resolved <see cref="ActionPreference"/>.</returns>
158225
protected ActionPreference GetErrorActionPreference() {
159226
if (MyInvocation.BoundParameters.ContainsKey("ErrorAction")) {
160227
string? errorActionString = MyInvocation.BoundParameters["ErrorAction"]?.ToString();
@@ -175,6 +242,12 @@ protected ActionPreference GetErrorActionPreference() {
175242
return ActionPreference.Continue;
176243
}
177244

245+
/// <summary>
246+
/// Ensures that the specified file exists, writing a warning or terminating error as appropriate.
247+
/// </summary>
248+
/// <param name="path">The file path to check.</param>
249+
/// <param name="errorAction">The action preference determining error handling.</param>
250+
/// <returns><c>true</c> if the file exists; otherwise, <c>false</c>.</returns>
178251
protected bool EnsureFileExists(string path, ActionPreference errorAction) {
179252
if (File.Exists(path)) {
180253
return true;

IISParser.PowerShell/CmdletGetIISParsedLog.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,47 @@
77

88
namespace IISParser.PowerShell;
99

10+
/// <summary>
11+
/// PowerShell cmdlet that parses an IIS log file and returns the parsed entries.
12+
/// </summary>
1013
[Cmdlet(VerbsCommon.Get, "IISParsedLog", DefaultParameterSetName = "Default")]
1114
public class CmdletGetIISParsedLog : AsyncPSCmdlet {
1215
private ParserEngine? _parser;
1316

17+
/// <summary>
18+
/// Gets or sets the path to the IIS log file.
19+
/// </summary>
1420
[Parameter(Mandatory = true, ParameterSetName = "Default")]
1521
[Parameter(Mandatory = true, ParameterSetName = "FirstLastSkip")]
1622
[Parameter(Mandatory = true, ParameterSetName = "SkipLast")]
1723
[Alias("LogPath")]
1824
public string FilePath { get; set; } = string.Empty;
1925

26+
/// <summary>
27+
/// Gets or sets the number of records to take from the start of the log.
28+
/// </summary>
2029
[Parameter(ParameterSetName = "FirstLastSkip")]
2130
public int? First { get; set; }
2231

32+
/// <summary>
33+
/// Gets or sets the number of records to take from the end of the log.
34+
/// </summary>
2335
[Parameter(ParameterSetName = "FirstLastSkip")]
2436
public int? Last { get; set; }
2537

38+
/// <summary>
39+
/// Gets or sets the number of records to skip from the start of the log.
40+
/// </summary>
2641
[Parameter(ParameterSetName = "FirstLastSkip")]
2742
public int? Skip { get; set; }
2843

44+
/// <summary>
45+
/// Gets or sets the number of records to skip from the end of the log.
46+
/// </summary>
2947
[Parameter(ParameterSetName = "SkipLast")]
3048
public int? SkipLast { get; set; }
3149

50+
/// <inheritdoc />
3251
protected override Task BeginProcessingAsync() {
3352
ActionPreference pref = GetErrorActionPreference();
3453
if (EnsureFileExists(FilePath, pref)) {
@@ -37,6 +56,7 @@ protected override Task BeginProcessingAsync() {
3756
return Task.CompletedTask;
3857
}
3958

59+
/// <inheritdoc />
4060
protected override Task ProcessRecordAsync() {
4161
if (_parser == null) {
4262
return Task.CompletedTask;
@@ -66,6 +86,7 @@ protected override Task ProcessRecordAsync() {
6686
return Task.CompletedTask;
6787
}
6888

89+
/// <inheritdoc />
6990
protected override Task EndProcessingAsync() {
7091
_parser?.Dispose();
7192
return Task.CompletedTask;

IISParser/IISLogEvent.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,117 @@
33

44
namespace IISParser;
55

6+
/// <summary>
7+
/// Represents a single entry in an IIS log file.
8+
/// </summary>
69
public class IISLogEvent {
10+
/// <summary>
11+
/// Gets or sets the timestamp of the log entry.
12+
/// </summary>
713
public DateTime DateTimeEvent { get; set; }
14+
15+
/// <summary>
16+
/// Gets or sets the site name reported by the server (<c>s-sitename</c>).
17+
/// </summary>
818
public string? sSitename { get; set; }
19+
20+
/// <summary>
21+
/// Gets or sets the computer name for the server (<c>s-computername</c>).
22+
/// </summary>
923
public string? sComputername { get; set; }
24+
25+
/// <summary>
26+
/// Gets or sets the server IP address (<c>s-ip</c>).
27+
/// </summary>
1028
public string? sIp { get; set; }
29+
30+
/// <summary>
31+
/// Gets or sets the HTTP method used by the request (<c>cs-method</c>).
32+
/// </summary>
1133
public string? csMethod { get; set; }
34+
35+
/// <summary>
36+
/// Gets or sets the requested resource path (<c>cs-uri-stem</c>).
37+
/// </summary>
1238
public string? csUriStem { get; set; }
39+
40+
/// <summary>
41+
/// Gets or sets the query portion of the requested URI (<c>cs-uri-query</c>).
42+
/// </summary>
1343
public string? csUriQuery { get; set; }
44+
45+
/// <summary>
46+
/// Gets or sets the server port (<c>s-port</c>).
47+
/// </summary>
1448
public int? sPort { get; set; }
49+
50+
/// <summary>
51+
/// Gets or sets the authenticated user name (<c>cs-username</c>).
52+
/// </summary>
1553
public string? csUsername { get; set; }
54+
55+
/// <summary>
56+
/// Gets or sets the client IP address (<c>c-ip</c>).
57+
/// </summary>
1658
public string? cIp { get; set; }
59+
60+
/// <summary>
61+
/// Gets or sets the protocol version (<c>cs-version</c>).
62+
/// </summary>
1763
public string? csVersion { get; set; }
64+
65+
/// <summary>
66+
/// Gets or sets the user agent string (<c>cs(User-Agent)</c>).
67+
/// </summary>
1868
public string? csUserAgent { get; set; }
69+
70+
/// <summary>
71+
/// Gets or sets the HTTP cookie value (<c>cs(Cookie)</c>).
72+
/// </summary>
1973
public string? csCookie { get; set; }
74+
75+
/// <summary>
76+
/// Gets or sets the referrer URL (<c>cs(Referer)</c>).
77+
/// </summary>
2078
public string? csReferer { get; set; }
79+
80+
/// <summary>
81+
/// Gets or sets the host header value (<c>cs-host</c>).
82+
/// </summary>
2183
public string? csHost { get; set; }
84+
85+
/// <summary>
86+
/// Gets or sets the HTTP status code (<c>sc-status</c>).
87+
/// </summary>
2288
public int? scStatus { get; set; }
89+
90+
/// <summary>
91+
/// Gets or sets the substatus error code (<c>sc-substatus</c>).
92+
/// </summary>
2393
public int? scSubstatus { get; set; }
94+
95+
/// <summary>
96+
/// Gets or sets the Windows status code (<c>sc-win32-status</c>).
97+
/// </summary>
2498
public long? scWin32Status { get; set; }
99+
100+
/// <summary>
101+
/// Gets or sets the number of bytes sent (<c>sc-bytes</c>).
102+
/// </summary>
25103
public int? scBytes { get; set; }
104+
105+
/// <summary>
106+
/// Gets or sets the number of bytes received (<c>cs-bytes</c>).
107+
/// </summary>
26108
public int? csBytes { get; set; }
109+
110+
/// <summary>
111+
/// Gets or sets the time taken to service the request, in milliseconds (<c>time-taken</c>).
112+
/// </summary>
27113
public int? timeTaken { get; set; }
114+
115+
/// <summary>
116+
/// Gets a dictionary containing all fields from the log line keyed by their original names.
117+
/// </summary>
28118
public Dictionary<string, string?> Fields { get; } = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
29119
}

0 commit comments

Comments
 (0)