src/REST/RequestLog.ps1
# Copyright 2019, Adam Edwards # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. . (import-script ../client/GraphConnection) . (import-script RESTRequest) . (import-script RESTResponse) . (import-script RequestLogEntry) enum RequestLogLevel { None Error Basic FullRequest FullResponse Full } ScriptClass RequestLog { $maxEntries = 0 $logPath = $null $logLevel = [RequestLogLevel]::Basic $requestIndex = $null $entries = @{} static { const MAX_ENTRIES_DEFAULT 131072 $defaultLogger = $null function GetDefault { if ( ! $this.defaultLogger ) { $this.defaultLogger = new-so RequestLog } $this.defaultLogger } function SetDefault([RequestLogLevel] $logLevel = [RequestLogLevel]::Basic, [string] $logPath) { $this.defaultLogger = new-so RequestLog $logLevel $logPath } } function __initialize([RequestLogLevel] $logLevel = [RequestLogLevel]::Basic, [string] $logPath) { $this.logPath = $logPath $this.logLevel = $logLevel $this |=> SetSize $this.scriptclass.MAX_ENTRIES_DEFAULT } function NewLogEntry( [PSTypeName('GraphConnection')] $connection, [PSTypeName('RESTRequest')] $request ) { if ( $this.LogLevel -eq 'None' ) { return } try { $newIndex = __GetNextLogIndex new-so RequestLogEntry $connection $request $this.loglevel } catch { $_ | write-debug } } function CommitLogEntry( [PSTypeName('RequestLogEntry')] $logEntry ) { if ( ! $logEntry -or ( $this.logLevel -eq 'Error' -and ! $logEntry.isError ) ) { return } $newIndex = __GetNextLogIndex $this.requestIndex = $newIndex $this.entries[$newIndex] = $logEntry } function GetLogEntries($start, $count, $startFromOldest, $allEntries, $errorFilter) { $startIndex = 0; $endIndex = 0; # Using the parens around __Get* matters -- seems like might think we are passing parameters! $increment = if ( $startFromOldest ) { $startIndex = ( __GetOldestLogIndex ) + $start 1 } else { $startIndex = ( __GetLatestLogIndex ) - $start -1 } $entryCount = 0 $current = $startIndex $targetCount = if ( $allEntries ) { $this.entries.count } else { $count } while ( $entryCount -lt $targetCount -and $entryCount -lt $this.entries.count ) { $currentEntry = $this.entries[$current] # We've indexed outside the table, so we must have run out of entries # in either direction if ( ! $currentEntry ) { break } $emitEntry = $errorFilter -eq $null -or ( ( $errorFilter -and $currentEntry.isError ) -or ( ! $errorFilter -and ! $currentEntry.isError ) ) if ( $emitEntry ) { $this.entries[$current] } $currentUnbounded = $current + $increment $current = if ( $currentUnbounded -lt 0 ) { $this.maxEntries - 1 } elseif ( $currentUnbounded -ge $this.maxEntries ) { 0 } else { $currentUnbounded } if ( $emitEntry ) { $entryCount++ } } } function Clear { $this.requestIndex = -1 $this.entries.clear() } function SetSize([uint32] $newSize) { $entriesToSave = [Math]::Min($this.entries.count, [int] $newSize) $entries = GetLogEntries 0 $this.entries.count $false $true $this.Clear() $this.maxEntries = [int] $newSize for ( $current = $entriesToSave - 1; $current -ge 0; $current-- ) { CommitLogEntry $entries[$current] } } function __GetNextLogIndex { ( $this.requestIndex + 1 ) % $this.maxEntries } function __GetOldestLogIndex { if ( $this.entries.count -eq 0 ) { -1 } elseif ( $this.entries.count -eq $this.maxEntries ) { $this.requestCount % $this.maxEntries } else { 0 } } function __GetLatestLogIndex { $this.requestIndex } function __AdvanceIndex { $this.requestIndex = ($this.requestIndex + 1) % $this.maxEntries } } |