| | | 1 | | <# |
| | | 2 | | .SYNOPSIS |
| | | 3 | | Adds Apache style common access logging to the Kestrun server. |
| | | 4 | | .DESCRIPTION |
| | | 5 | | Configures the Common Access Log middleware which emits request logs formatted like the |
| | | 6 | | Apache HTTPD common/combined log. The logs are written via the active Serilog pipeline so |
| | | 7 | | any configured sinks receive the access log entries. |
| | | 8 | | .PARAMETER Server |
| | | 9 | | The target Kestrun server instance. When omitted the current server is resolved automatically. |
| | | 10 | | .PARAMETER Level |
| | | 11 | | The Serilog log level used when emitting access log entries. Defaults to Information. |
| | | 12 | | .PARAMETER Logger |
| | | 13 | | The Serilog logger instance that should receive the access log entries. When not supplied the |
| | | 14 | | middleware uses the application's default logger from dependency injection. |
| | | 15 | | This parameter is mutually exclusive with LoggerName. |
| | | 16 | | .PARAMETER LoggerName |
| | | 17 | | The name of a registered logger that should receive the access log entries. When supplied |
| | | 18 | | the logger with this name is used instead of the default application logger. |
| | | 19 | | This parameter is mutually exclusive with Logger. |
| | | 20 | | .PARAMETER ExcludeQueryString |
| | | 21 | | Indicates whether the request query string should be excluded from the logged request line. Defaults to $true. |
| | | 22 | | .PARAMETER ExcludeProtocol |
| | | 23 | | Indicates whether the request protocol (for example HTTP/1.1) should be excluded from the logged request line. D |
| | | 24 | | .PARAMETER IncludeElapsedMilliseconds |
| | | 25 | | Appends the total request duration in milliseconds to the access log entry when set to $true. Defaults to $false |
| | | 26 | | .PARAMETER UseUtcTimestamp |
| | | 27 | | When specified the timestamp in the log entry is written in UTC instead of local server time. |
| | | 28 | | .PARAMETER TimestampFormat |
| | | 29 | | Optional custom timestamp format string. When omitted the Apache default "dd/MMM/yyyy:HH:mm:ss zzz" is used. |
| | | 30 | | .PARAMETER ClientAddressHeader |
| | | 31 | | Optional HTTP header name that contains the original client IP (for example X-Forwarded-For). |
| | | 32 | | When supplied the first value from the header is used instead of the socket address. |
| | | 33 | | .PARAMETER PassThru |
| | | 34 | | Returns the server instance to enable fluent pipelines when specified. |
| | | 35 | | .EXAMPLE |
| | | 36 | | Add-KrCommonAccessLogMiddleware -LoggerName 'myLogger' -UseUtcTimestamp |
| | | 37 | | |
| | | 38 | | Adds the Common Access Log middleware to the current Kestrun server using the named logger 'myLogger' |
| | | 39 | | and configures it to log timestamps in UTC. |
| | | 40 | | .EXAMPLE |
| | | 41 | | $server = New-KrServer -Name "My Server" | |
| | | 42 | | Add-KrListener -Port 8080 -IPAddress ([IPAddress]::Any) | |
| | | 43 | | Add-KrCommonAccessLogMiddleware -LoggerName 'myLogger' -PassThru |
| | | 44 | | |
| | | 45 | | Creates a new Kestrun server instance, adds a listener on port 8080 and the PowerShell runtime, |
| | | 46 | | then adds the Common Access Log middleware using the named logger 'myLogger' and returns the |
| | | 47 | | server instance in the $server variable. |
| | | 48 | | #> |
| | | 49 | | function Add-KrCommonAccessLogMiddleware { |
| | | 50 | | [KestrunRuntimeApi('Definition')] |
| | | 51 | | [CmdletBinding(DefaultParameterSetName = 'Logger')] |
| | | 52 | | [OutputType([Kestrun.Hosting.KestrunHost])] |
| | | 53 | | param( |
| | | 54 | | [Parameter(ValueFromPipeline = $true)] |
| | | 55 | | [Kestrun.Hosting.KestrunHost]$Server, |
| | | 56 | | |
| | | 57 | | [Parameter()] |
| | | 58 | | [Serilog.Events.LogEventLevel]$Level = [Serilog.Events.LogEventLevel]::Information, |
| | | 59 | | |
| | | 60 | | [Parameter(Mandatory = $false, ParameterSetName = 'Logger')] |
| | | 61 | | [Serilog.ILogger]$Logger, |
| | | 62 | | |
| | | 63 | | [Parameter(Mandatory = $true, ParameterSetName = 'LoggerName')] |
| | | 64 | | [string]$LoggerName, |
| | | 65 | | |
| | | 66 | | [Parameter()] |
| | | 67 | | [switch]$ExcludeQueryString, |
| | | 68 | | |
| | | 69 | | [Parameter()] |
| | | 70 | | [switch]$ExcludeProtocol, |
| | | 71 | | |
| | | 72 | | [Parameter()] |
| | | 73 | | [switch]$IncludeElapsedMilliseconds, |
| | | 74 | | |
| | | 75 | | [Parameter()] |
| | | 76 | | [switch]$UseUtcTimestamp, |
| | | 77 | | |
| | | 78 | | [Parameter()] |
| | | 79 | | [string]$TimestampFormat, |
| | | 80 | | |
| | | 81 | | [Parameter()] |
| | | 82 | | [string]$ClientAddressHeader, |
| | | 83 | | |
| | | 84 | | [Parameter()] |
| | | 85 | | [switch]$PassThru |
| | | 86 | | ) |
| | | 87 | | begin { |
| | 0 | 88 | | $Server = Resolve-KestrunServer -Server $Server |
| | | 89 | | |
| | | 90 | | # If Logger is not provided, use the default logger or the named logger |
| | 0 | 91 | | if ($Null -eq $Logger) { |
| | 0 | 92 | | if ([string]::IsNullOrEmpty($LoggerName)) { |
| | 0 | 93 | | $Logger = [Serilog.Log]::Logger |
| | | 94 | | } else { |
| | | 95 | | # If LoggerName is specified, get the logger with that name |
| | 0 | 96 | | $Logger = [Kestrun.Logging.LoggerManager]::Get($LoggerName) |
| | | 97 | | } |
| | | 98 | | } |
| | | 99 | | } |
| | | 100 | | process { |
| | | 101 | | |
| | 0 | 102 | | $timestampFormatSet = $PSBoundParameters.ContainsKey('TimestampFormat') |
| | 0 | 103 | | $clientHeaderSet = $PSBoundParameters.ContainsKey('ClientAddressHeader') |
| | | 104 | | |
| | 0 | 105 | | $options = [Kestrun.Middleware.CommonAccessLogOptions]::new() |
| | 0 | 106 | | $options.Level = $Level |
| | 0 | 107 | | $options.IncludeQueryString = -not $ExcludeQueryString.IsPresent |
| | 0 | 108 | | $options.IncludeProtocol = -not $ExcludeProtocol.IsPresent |
| | 0 | 109 | | $options.IncludeElapsedMilliseconds = $IncludeElapsedMilliseconds.IsPresent |
| | 0 | 110 | | $options.UseUtcTimestamp = $UseUtcTimestamp.IsPresent |
| | | 111 | | |
| | 0 | 112 | | if ($timestampFormatSet) { |
| | 0 | 113 | | $options.TimestampFormat = $TimestampFormat |
| | | 114 | | } |
| | | 115 | | |
| | 0 | 116 | | if ($clientHeaderSet -and -not [string]::IsNullOrWhiteSpace($ClientAddressHeader)) { |
| | 0 | 117 | | $options.ClientAddressHeader = $ClientAddressHeader |
| | | 118 | | } |
| | | 119 | | |
| | 0 | 120 | | $options.Logger = $Logger |
| | | 121 | | |
| | 0 | 122 | | [Kestrun.Hosting.KestrunHttpMiddlewareExtensions]::AddCommonAccessLog($Server, $options) | Out-Null |
| | | 123 | | |
| | 0 | 124 | | if ($PassThru.IsPresent) { |
| | 0 | 125 | | return $Server |
| | | 126 | | } |
| | | 127 | | } |
| | | 128 | | } |