Public/Start-TcsTelemetry.ps1
|
<# .SYNOPSIS Starts timing one run of a command for telemetry and returns a token for Complete-TcsTelemetry. .DESCRIPTION The Start-TcsTelemetry function is the first half of the telemetry wrapper for commands in tcs modules. Call it once at the start of a command (in the begin block of a pipeline function), keep the token it returns, and pass the token to Complete-TcsTelemetry when the command ends. For commands without begin/process/end blocks, Invoke-TcsCommand does both in one call. The command, module and version are taken from the calling command when they are not given. Only the outermost run is reported. When an exported command calls another exported command of the same module, the inner run returns a token with IsOutermost = $false and sends nothing, so one user action is one event. Commands of other modules are reported separately. Telemetry never breaks the caller: if anything goes wrong, a token is still returned and the failure is written to the verbose stream. Nothing is sent when telemetry is turned off; see Invoke-TelemetryCollection. .PARAMETER CommandName The name reported for the command. Defaults to the name of the calling command. .PARAMETER ModuleName The module the command belongs to. Defaults to the module of the calling command. .PARAMETER ModuleVersion The module version. Defaults to the version of the calling command's module. .INPUTS None This function does not accept pipeline input. .OUTPUTS Tcs.TelemetryToken Id, CommandName, ModuleName, ModuleVersion, IsOutermost, Failed, Completed and Exception. Assign it to a variable so it is not written to the pipeline. .EXAMPLE function Get-Widget { [CmdletBinding()] param([Parameter(ValueFromPipeline)][string]$Name) begin { $telemetry = Start-TcsTelemetry } process { Invoke-TcsCommand -Token $telemetry -ScriptBlock { Get-Item -Path $Name } } end { Complete-TcsTelemetry -Token $telemetry } } A pipeline function: one event is sent for the whole pipeline run. Invoke-TcsCommand -Token records errors in each process block; a terminating error completes the run as failed. .EXAMPLE begin { $telemetry = Start-TcsTelemetry } process { try { Set-Thing -Name $Name -ErrorAction Stop } catch { Complete-TcsTelemetry -Token $telemetry -ErrorRecord $_; throw } } end { Complete-TcsTelemetry -Token $telemetry } Completes the run by hand, as failed when an error is caught. .NOTES Author: Nigel Tatschner Company: TheCodeSaiyan .LINK Complete-TcsTelemetry .LINK Invoke-TcsCommand #> function Start-TcsTelemetry { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Only starts an in-memory timer; nothing on the system is changed.')] [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(HelpMessage = 'Name reported for the command.')] [string]$CommandName, [Parameter(HelpMessage = 'Module the command belongs to.')] [string]$ModuleName, [Parameter(HelpMessage = 'Version of the module.')] [string]$ModuleVersion ) $invocation = $null try { $callStack = @(Get-PSCallStack) if ($callStack.Count -gt 1) { $invocation = $callStack[1].InvocationInfo } return (New-TcsTelemetryToken -Invocation $invocation -CommandName $CommandName -ModuleName $ModuleName -ModuleVersion $ModuleVersion) } catch { Write-Verbose "Telemetry could not be started: $($_.Exception.Message)" # A token that sends nothing, so the caller's Complete-TcsTelemetry still works return [PSCustomObject]@{ PSTypeName = 'Tcs.TelemetryToken' Id = [guid]::NewGuid().ToString() CommandName = $CommandName ModuleName = $ModuleName ModuleVersion = $ModuleVersion IsOutermost = $false Failed = $false Completed = $false Exception = $null } } } |