Azure Automation(PowerShell)からApplication Insightsへログを出力する

# はじめに

Azure Automationでは、LogAnalyticsへログを出力することができますが、Application Insightsへは標準で出力する方法がありません（たぶん）。

そこでApplication Insightsへログを出力するPowerShellモジュールを作成してみました。

必要なファイルは以下の3つで、これをzipに固めてAutomationに登録します。

・Microsoft.ApplicationInsights.dll(ApplicationInsightsのDLL)
・ApplicationInsightsCustomTrace.psm1(モジュールのソース)
・ApplicationInsightsCustomTrace.psd1(モジュールマニフェスト)

Application InsightsへEventを出力する以下のモジュールを参考にして作成しました。

 ApplicationInsightsCustomEvents 1.0 
https://www.powershellgallery.com/packages/ApplicationInsightsCustomEvents/1.0


# Microsoft.ApplicationInsights.dll(ApplicationInsightsのDLL)

まず、ApplicationInsightsのDLLである、「Microsoft.ApplicationInsights.dll」を持ってきます。
Azureの開発しているPCであれば既にPCのどこかに「Microsoft.ApplicationInsights.dll」がインストールされているはずなので、検索すれば見つかるはずです。
私の環境には10数個ほど見つかりました・・・

今回は、以下に入っていた「Microsoft.ApplicationInsights.dll」を使用しています。
「Azure PowerShell」をインストールしていればファイルがあるはずです。

　C:\Program Files\WindowsPowerShell\Modules\Azure.Storage\4.6.1


# PowerShellモジュールのソース作成

次にApplication Insightsへログを出力するPowerShellを作成します。

・Export-ModuleMemberで、公開するFunctionを指定します。
・引数はInsightsインストルメンテーションキー、出力するログ（TraceMsg）、ログレベル（SeverityLevel）の3つです。
・ログレベルは、"Critical"、"Error"、"Information"、"Verbose"、"Warning"の5つになります。
・「\$TelClient.TrackTrace(\$TraceMsg, \$SeverityLevel)」でログをAIに出力しています。
・ログの出力はバッファされますが、「\$TelClient.Flush()」で強制的に出力しています。ログの出力回数が多い場合は、バッファした方が良いと思われます。


```ApplicationInsightsCustomTrace.psm1
function Write-ApplicationInsightsTrace
{
    [CmdletBinding()]
    param(
            [Parameter(Mandatory=$true)][string] $InstrumentationKey,
            [Parameter(Mandatory=$true)][string] $TraceMsg,
            [Parameter(Mandatory=$true)][string] $SeverityLevel
            )
    try
    {
	    $TelClient = New-Object -TypeName Microsoft.ApplicationInsights.TelemetryClient
	    $TelClient.InstrumentationKey = $InstrumentationKey
	    $TelClient.TrackTrace($TraceMsg, $SeverityLevel)
	    $TelClient.Flush()
    }
    catch
    {
        Write-Output "Exception while logging into Application Insights: $($_.Exception.Message)"
    }
}

Export-ModuleMember -Function Write-ApplicationInsightsTrace
```


# PowerShellモジュールマニフェスト作成

次に、先ほど作成したモジュールファイルのマニフェストを作成します。
重要なのは以下の2行です。

・マニフェストに関連付けられているモジュールファイルを指定します。
RootModule = 'ApplicationInsightsCustomTrace.psm1'
・モジュールで使用するDLLを指定します。
NestedModules = @('.\Microsoft.ApplicationInsights.dll') 


```ApplicationInsightsCustomTrace.psd1

@{

    # Script module or binary module file associated with this manifest.
    RootModule = 'ApplicationInsightsCustomTrace.psm1'
    
    # Version number of this module.
    ModuleVersion = '1.0.0'
    
    # Author of this module
    Author = 'mkyz08'
    
    # Company or vendor of this module
    CompanyName = ''
    
    # Copyright statement for this module
    Copyright = ''
    
    # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
    NestedModules = @('.\Microsoft.ApplicationInsights.dll') 
    
    # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
    FunctionsToExport = @('*')
    
    # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
    CmdletsToExport = @('*')
    
    # Variables to export from this module
    VariablesToExport = '*'
    
    # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
    AliasesToExport = @()
    
    # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
    PrivateData = @{
    
        PSData = @{
    
        } # End of PSData hashtable
    
    } # End of PrivateData hashtable
    
    }    
```


# PowerShellモジュールをAutomationに登録する

前述の3つのファイルをzipに固めたPowerShellモジュールをAutomationに登録します。

まず、Automationアカウントから「共有リソース」－「モジュール」を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/c274bd2a-c869-7b56-acd9-fa15ccd8e0c8.png)

次に、「モジュールの追加」から、先ほど作成したzipファイルを登録します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/14bc5129-ff43-11eb-16ec-4453ca2ddd0d.png)

登録が終わると以下のように、作成したモジュールが表示されます。状態が「使用可能」になっていれば準備完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/d4278ae7-6c25-3815-c348-074ac1ed9bb7.png)


# AutomationからApplication Insightsへログを出力する

テスト用のRunbookを作成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/cde561d8-a80a-e1db-5fd8-20c2ad51bcd4.png)

作成したRunbookに以下のコードを書きます。
$InstrumentationKeyはApplication Insightsのプロパティからインストルメンテーションキーを確認して書きます。

```ps1
Param
(
)

$InstrumentationKey	= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Write-ApplicationInsightsTrace $InstrumentationKey "Critical TEST" "Critical"
Write-ApplicationInsightsTrace $InstrumentationKey "Error TEST" "Error"
Write-ApplicationInsightsTrace $InstrumentationKey "Information TEST" "Information"
Write-ApplicationInsightsTrace $InstrumentationKey "Verbose TEST" "Verbose"
Write-ApplicationInsightsTrace $InstrumentationKey "Warning TEST" "Warning"
```

「テストウィンドウ」で「開始」を選択すると、以下のように実行されます。
Application Insightsに出力しているだけなので、「完了」とだけ表示されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/7643f7b0-8b4a-883d-2210-8a7102695483.png)



# Application Insightsでログを確認する

Application Insightsにアクセスしてログを検索すると、以下のように5つのログが出力されていることを確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/76b42ef4-9a21-7454-9499-fc4e6599572c.png)


# 参考

[ApplicationInsightsCustomEvents 1.0](https://www.powershellgallery.com/packages/ApplicationInsightsCustomEvents/1.0)
[PowerShell のモジュール詳解とモジュールへのコマンドレット配置手法を考える](http://tech.guitarrapc.com/entry/2013/12/03/014013#Export-ModuleMember-%E3%81%AB%E3%82%88%E3%82%8B%E5%85%AC%E9%96%8B%E3%81%99%E3%82%8B%E3%83%95%E3%82%A1%E3%83%B3%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E9%81%B8%E6%8A%9E)
[Windows PowerShell: パラメーターを定義する](https://docs.microsoft.com/ja-jp/previous-versions/technet-magazine/jj554301(v=msdn.10))