Centralize log collection with a custom REST API
Use case
Function code
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
$logtype = $Request.Body.logtype
$logbody = $Request.Body.logbody
$customerId = ""
$sharedKey = ""
Function Build-Signature ($customerId, $sharedKey, $date, $contentLength, $method, $contentType, $resource){
$xHeaders = "x-ms-date:" + $date
$stringToHash = $method + "`n" + $contentLength + "`n" + $contentType + "`n" + $xHeaders + "`n" + $resource
$bytesToHash = [Text.Encoding]::UTF8.GetBytes($stringToHash)
$keyBytes = [Convert]::FromBase64String($sharedKey)
$sha256 = New-Object System.Security.Cryptography.HMACSHA256
$sha256.Key = $keyBytes
$calculatedHash = $sha256.ComputeHash($bytesToHash)
$encodedHash = [Convert]::ToBase64String($calculatedHash)
$authorization = 'SharedKey {0}:{1}' -f $customerId,$encodedHash
return $authorization
}
Function Post-LogAnalyticsData ($customerId, $sharedKey, $body, $logType){
$method = "POST"
$contentType = "application/json"
$resource = "/api/logs"
$rfc1123date = ([DateTime]::UtcNow).ToString("r")
$contentLength = $body.Length
$signature = Build-Signature -customerId $customerId -sharedKey $sharedKey -date $rfc1123date -contentLength $contentLength -method $method -contentType $contentType -resource $resource
$uri = "https://" + $customerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
$headers = @{
"Authorization" = $signature;
"Log-Type" = $logType;
"x-ms-date" = $rfc1123date;
}
$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
return $response.StatusCode
}
$logbodyjson = ConvertTo-JSON $logbody -Depth 10
#Submit the data to the API endpoint
$params = @{
CustomerId = $customerId
SharedKey = $sharedKey
Body = ([System.Text.Encoding]::UTF8.GetBytes($logbodyjson))
LogType = $LogType
}
$LogResponse = Post-LogAnalyticsData @params
$LogResponse
if($LogResponse -eq 200){
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $LogResponse
})
}
Send logs via PowerShell script
Function Send-Logs(){
param (
[String]$LogType,
$LogBodyList
)
$url="<functionurl>"
$LogBodyJSON = @"
{
"logtype": "$LogType",
"logbody": {}
}
"@
$LogBodyObject = ConvertFrom-JSON $LogBodyJSON
Foreach($Log in $LogBodyList.GetEnumerator()){
$LogBodyObject.logbody | Add-Member -MemberType NoteProperty -Name $log.key -Value $log.value
}
$Body = ConvertTo-JSON $LogBodyObject
$Response = Invoke-Restmethod -uri $url -Body $Body -Method POST -ContentType "application/json"
return $Response
}
$Logs = @{
"<logmember1>"="<logvalue1>"
"<logmember2>"="<logvalue2>"
}
Send-Logs -LogType "<logtype>" -LogBodyList $Logs