SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

Azure Arc Enabled Managed Instance の間接接続のログをデコードする

leave a comment

Azure Arc Enabled Managed Instance を「間接モード」で実行している場合、Azure との連携はファイルベースで実施する必要があり、連携用のファイルをエクスポートして Azure にアップロードするという作業が必要となります。(直接接続モードの場合は自動的に収集とアップロードが実施されます)

アップロード対象の情報は「使用状況 (usage)」「メトリック (metrics)」「ログ (logs)」の 3 種類があり、それぞれのエクスポート用のサブコマンドでファイルを出力し、アップロードを実施します。

このエクスポートデータの中の「ログ」について、調査する機会があったのでその時の作業内容を残しておきたいと思います。

logs のエクスポートデータをデコードする

logs のデータについては、「az arcdata dc export –type logs –path logs.json –force」で指定したパスにログをエクスポートすることができます。

指定したディレクトリに次のように「logs.json」「logs-0.json」のようなファイル名でログが出力されるのですが、今回のターゲットとなるのは「logs-0.json」になります。

image

logs-0.json の内容は次のようになります。

image

JSON で情報が出力されており、今回デコードをしたいと思っているのが「data.logs」の情報です。logs には、Arc MI のログの情報が出力されており、SQL Server の ERRORLOG 相当の情報が出力されています。

この logs がどのようなエンコードが行われているのかについては「%USERPROFILE%\.Azure\cliextensions\arcdata\azext_arcdata\dc\export_util.py」の「logs_upload」から確認できます。

image

「BASE64 エンコード + Deflate 圧縮」が行われているので、これを実装すれば任意のコードでデコードができます。

ということで PowerShell で実装すると次のようなスクリプトになるかと。

$logs = (Get-Content -Path C:\work\export\logs-0.json | ConvertFrom-Json).data.logs

[byte[]]$bytes = [System.Convert]::FromBase64String($logs)
$stream = New-Object System.IO.Compression.DeflateStream((New-Object System.IO.MemoryStream(,$bytes)) ,[System.IO.Compression.CompressionMode]::Decompress)

$results = New-Object byte[]($bytes.Length)
[void]$stream.Read($results,0,$bytes.Length) 
[System.Text.Encoding]::UTF8.GetString($results)

logs の内容がデコードできていますね。

image

何でデコードしようと思ったか?

なぜ、logs の内容に何が含まれているかを確認しようと思ったかというと Arc MI を日本語環境で構築した場合、logs のアップロードがエラーとなるという事象が発生したからです。

間接モードの Arc MI ですが、次のようなコマンドで、日本語環境に合わせた設定 (言語 / タイムゾーン / 照合時順序を日本語をベースに設定) で展開を行うことができます。

$ENV:AZDATA_USERNAME="xxxxxxxxx"
$ENV:AZDATA_PASSWORD="xxxxxxxx"
az sql mi-arc create -n mi-01 --k8s-namespace arc --use-k8s --time-zone "Asia/Tokyo" --cores-request 1  --agent-enabled true --dev --collation "Japanese_XJIS_140_CI_AS_UTF8" --language "1041" --debug --verbose

language を 1041 にすることで、日本語版の SQL Server のように導入をすることができるのですが、ここに落とし穴があります。

日本語環境の SQL Server でインストールした場合、ERRORLOG に「Default collation: Japanese_XJIS_140_CI_AS_UTF8 (日本語 1041)」というようなメッセージが出力されます。

logs のデータには、ERRORLOG の内容が含まれますので、エクスポートしたデータにも次のように「日本語 1041」というようなメッセージが出力されます。

image

このようなダブルバイトの文字が含まれている logs をアップロードすると、投稿を書いている時点の AZ CLI のアップロードコマンドで「UnicodeEncodeError: ‘latin-1’ codec can’t encode characters in position xxxx-xxxx: Body (‘日本語’) is not valid Latin-1. Use body.encode(‘utf-8’) if you want to send it encoded in UTF-8.」のエラーが発生し、アップロードを行うことができません。

アップロードについても「%USERPROFILE%\.Azure\cliextensions\arcdata\azext_arcdata\dc\export_util.py」で実行されているのですが、エラーが出る環境では、次のような内容となっているかと思います。

image

body にエンコードの指定が行われていないので、エラーメッセージ内容のとおり、UTF-8 のエンコード指定を追加してあげます。

image

これでアップロードできるようになるかと思います。

この問題については報告済みの内容となっているので、そのうち修正されるかと思いますが、アップロードがエラーにある場合は、本投稿のような内容を見直すとよいかと思います。

Share

Written by Masayuki.Ozawa

10月 21st, 2021 at 8:48 pm

Posted in 未分類

Leave a Reply