Private/Send-Logs.ps1

function Hide-PrivateEndpointUrlsInLogMessage {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Message
    )

    if ([string]::IsNullOrEmpty($Message)) {
        return $Message
    }

    # The tenant logs API gateway rejects payloads containing private-IP URLs.
    $privateHostPattern = '(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})'
    return [regex]::Replace($Message, "https?://$privateHostPattern(?::\d+)?[^\s]*", '[redacted-url]', 'IgnoreCase')
}

function Send-Logs {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$NutanixEnvironment,

        [Parameter(Mandatory = $true)]
        [string]$Version,

        [Parameter(Mandatory = $true)]
        [string]$LogsApiHost,

        [Parameter(Mandatory = $true)]
        [string]$LoginHost,

        [Parameter(Mandatory = $true)]
        [string]$NexthinkTarget
    )

    if ($script:IN_MEMORY_LOGS.Count -eq 0) {
        return
    }

    $logsUrl = "https://$LogsApiHost/vdi/vdi-log-ingestion-api/api/v1/logs/entries"
    $traceId = [Guid]::NewGuid().ToString()

    try {
        $jwt = Get-Jwt -LoginHost $LoginHost -Target $NexthinkTarget

        $logsForApi = foreach ($entry in $script:IN_MEMORY_LOGS) {
            @{
                timestamp = $entry.timestamp
                level     = $entry.level
                message   = Hide-PrivateEndpointUrlsInLogMessage -Message $entry.message
            }
        }

        $logsPayload = @{
            source              = "nutanix-hypervisor-on-prem-connector"
            customerEnvironment = $NutanixEnvironment
            version             = $Version
            logs                = @($logsForApi)
        }

        $logsJsonPayload = $logsPayload | ConvertTo-Json -Depth 10 -Compress

        $headers = @{
            'Content-Type'                 = 'application/json'
            'Authorization'                = "Bearer $jwt"
            'x-nexthink-vdi-logs-trace-id' = $traceId
        }

        $response = Invoke-WebRequestWithLogging -Uri $logsUrl -Method 'POST' -Headers $headers -Body $logsJsonPayload -UseBasicParsing
        Write-CustomLog -Message "[$traceId] Successfully sent $($script:IN_MEMORY_LOGS.Count) log entries to Logs API. Response code: $($response.StatusCode)" -Severity 'INFO' -NoCache
    }
    catch {
        Write-CustomLog -Message "[$traceId] Error sending logs to Logs API. Details: $($_.Exception.Message)" -Severity 'ERROR' -NoCache
    }
}