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