本記事の内容
2023年4月時点で、API 経由でのログ取り込みは、Log Ingest API の利用が推奨です。Log Ingest API については別途記事を公開していますので、合わせてご参照ください。
本記事では、Azure Log Analytics Data Collector API を使って、任意のデータを Azure Log Analytics に取り込むための手順を見ていきたいと思います。以下では特に PowerShell を用いてデータを格納していきます。
Azure Sentinel への Data Collector API の応用
Azure Sentinel では、データストレージ・検索基盤として Log Analytics を利用しているため、データの格納には Log Analytics の諸々の機能を活用します。Data Collector API は汎用性のある手法ですが、それ以外にもさまざまな手法を利用できます。詳細は、Azure Sentinel: Creating Custom Connectorsにまとめられています。
Data Collector API の仕組み
Log Analytics ワークスペース内のすべてのデータは、特定のレコード型のレコードとして保存されます。 Data Collector API に送信するデータを、JSON 形式の複数のレコードとして設定します。 データを送信すると、要求ペイロード内の各レコードに対応する個別のレコードがリポジトリ内に作成されます。
( Data Collector API の概念 より)
PowerShell から Data Collector API を利用して、データを格納する
PowerShell のサンプルを時間に関する部分だけ少し変更して実行してみます。
# Replace with your Workspace ID
$CustomerId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Replace with your Primary Key
$SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Specify the name of the record type that you'll be creating
$LogType = "MyRecordType"
# You can use an optional field to specify the timestamp from the data. If the time field is not specified, Azure Monitor assumes the time is the message ingestion time
$TimeStampField = "DateValue"
$currentUTCtime = (Get-Date).ToUniversalTime()
$logTime = $currentUTCtime | Get-Date -Format yyyy-MM-ddThh:mm:ss
$logTimeSt = $logTime.ToString()
# Create two records with the same set of properties to create
$json = @"
[{ "StringValue": "MyString1",
"NumberValue": 42,
"BooleanValue": true,
"DateValue": "$logTimeSt",
"GUIDValue": "9909ED01-A74C-4874-8ABF-D2678E3AE23D"
},
{ "StringValue": "MyString2",
"NumberValue": 43,
"BooleanValue": false,
"DateValue": "$logTimeSt",
"GUIDValue": "8809ED01-A74C-4874-8ABF-D2678E3AE23D"
}]
"@
# Create the function to create the authorization signature
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
}
# Create the function to create and post the request
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;
"time-generated-field" = $TimeStampField;
}
$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
return $response.StatusCode
}
# Submit the data to the API endpoint
Post-LogAnalyticsData -customerId $customerId -sharedKey $sharedKey -body ([System.Text.Encoding]::UTF8.GetBytes($json)) -logType $logType
Log Analytics 側で検索してみる
サンプルの検索結果として下記のクエリを実行します。(Project-away は単に表示しない列を指定しているだけなので、本質的には不要です。上記 PowerShell では $LogType = "MyRecordType" が指定されていましたが、テーブル名はカスタムログである_CLが付き、MyRecordType_CLとなります。また各プロパティ名には_sが付きます。
MyRecordType_CL
| where TimeGenerated > ago(365d)
| project-away Computer, RawData, _ResourceId
まとめ
Data Collector API を使い、簡単に PowerShell から Log Analytics にデータを送れることを確認できました。 Data Collector API では C# や Python の SDK も公開しているため、使いなれた言語でデータの送信が可能です。
*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。