X

記憶域スペース/記憶域プールの正常性をメールで監視する

記憶域スペース/記憶域プールは非常に柔軟性の高いSDSソリューションですが、サーバーの異常は管理者がサーバーダッシュボードを頻繁に確認しないことにはなかなか気がつきにくく、普段クライアントコンピューターから利用しているだけだと致命的な症状が現れて初めて気がつき、そのときにはすでに手遅れということも往々にしてあり得ます。

記憶域プール/記憶域スペースに障害が発生した場合の見え方

たとえば、記憶域プールに接続されている物理ディスクが一台認識されなくなったケースをみてみます。

サーバーマネージャー

ダッシュボード

サーバーマネージャーを開いて一番最初に表示されるダッシュボードでは、物理ディスクが認識されなくなっても何も警告やエラーは表示されず、オールグリーンの状態です。

ファイルサービスと記憶域サービス>記憶域プール

サーバーマネージャーから、[ファイルサービスと記憶域サービス]>[記憶域プール]を開くと、ようやくここで警告が表示されていることが確認できます。問題が表示されている記憶域プール、仮想ディスク、物理ディスクに警告マークが表示されています。

アクションセンター

タスクバーのアクションセンターアイコンには、通知があることが表示されます。

アイコンをクリックすると、「[記憶域]で問題を確認してください」と表示されます。

コントロールパネル

[コントロールパネル]>[システムとセキュリティ]>[記憶域]を開くと、警告が表示されているのが確認できます。

イベントビューアー

記憶域スペース/記憶域プールのイベントログは、[アプリケーションとサービス ログ]>[Microsoft]>[Windows]>[StorageSpaces-Driver]から確認できます。今回はディスクを認識できないイベントですので、304が記録されていますが、たとえば物理ディスクのセクター障害のような場合だと、203が記録されるなど内容が変わります。

イベントビューアーに表示されるイベントの詳細は、「Windows Server 2012 R2 記憶域スペースのアーキテクチャと設計・管理のベストプラクティス」に記載されています。

問題はこれで気がつけるのかということ

記憶域スペース/記憶域プールに関するエラーは、確かにいくつかの場所に表示され確認することができますが、果たして通常の運用の中で管理者がこれに気がつけるのかということが問題になるでしょう。これは特に記憶域スペースに特化して生じる問題ではありませんが。

通常、ミッションクリティカルな運用をしている現場では、JP1/Baseなどでイベントを監視するのでしょうが、そうでない場合はこういったエラーは気がつかれず放置されて、致命的な障害が発生するまでそのままになってしまうケースが多いのではないでしょうか。

個人や中小環境でも、こういったエラーを早めに察知し、致命的になる前に対処するにはどうしたらよいのでしょうか。いくつか方法はあると思いますが、今回は2つの方法を紹介します。

イベントビューアからメールを送信するタスクを構成する

対象のイベントログを右クリックすると、[このイベントにタスクを設定]を押下し、

[電子メールの送信]を押下します。

電子メールの送信内容を設定します。

PowerShellを使ってメール通知させる

PowerShellからメールを送信する方法もあります。

PowerShellからメール送信を可能とするモジュールを導入

  1. Githubで公開されている、blachniet-psutilsをダウンロードして、解凍します。
  2. C:\windows\system32\WindowsPowerShell\v1.0\Modules\に1で解凍したフォルダーを保存します。
  3. 標準のモジュールでは、Get-Eventlog からイベントログを拾うようになっていますが、このままでは記憶域スペースに関するイベントを表示できないため、Get-Wineventを利用するようにし、併せて表示内容を調整するため、Send-EventEntryEmail.psm1をコピーして、Send-WinEventEntryEmail.psm1に名前を変更し、内容も以下のように修正します。
    Function Send-WinEventEntryEmail{
    
        [CmdletBinding()]
        param(
            [Parameter()]
            [string] $LogName = "Microsoft-Windows-StorageSPaces-Driver*",
        
        #    [Parameter(Mandatory=$true)]
        #    [string] $Source,
        
           [Parameter()]
            [int] $Maxevents = 1,
        
        #    [Parameter()]
        #    [string[]] $EntryType = "Error",
        
            [Parameter(Mandatory=$true)]
            [string] $SmtpUser,
        
            [Parameter(Mandatory=$true)]
            [string] $SmtpPassword,
        
            [Parameter()]
            [int] $SmtpPort = 587,
        
            [Parameter()]
            [string] $SmtpServer = "smtp.gmail.com",
        
            [Parameter(Mandatory=$true)]
            [string] $MailFrom,
        
            [Parameter(Mandatory=$true)]
            [string] $MailTo,
        
            [Parameter()]
            [string] $Subject = "EventLogAlert"
        )
    
        # Get the event entries.
        $eventEntries = Get-Winevent -LogName $LogName -MaxEvents $Maxevents
    
        # Create a table row for each entry.
        $rows = ""
        foreach ($eventEntry in $eventEntries){
            $rows += @"
            <tr>
                <td style="text-align: center; padding: 5px;">$($eventEntry.TimeCreated)</td>
                <td style="text-align: center; padding: 5px;">$($eventEntry.LevelDisplayName)</td>
                <td style="padding: 5px;">$($eventEntry.Message)</td>
            </tr>
    "@
        }
    
        # Create the email.
        $email = New-Object System.Net.Mail.MailMessage( $MailFrom , $MailTo )
        $email.Subject = $Subject
        $email.IsBodyHtml = $true
        $email.Body = @"
        <table style="width:100%;border">
            <tr>
                <th style="text-align: center; padding: 5px;">Time</th>
                <th style="text-align: center; padding: 5px;">Type</th>
                <th style="text-align: center; padding: 5px;">Message</th>
            </tr>
        
        $rows
    
        </table>
    "@
    
        # Send the email.
        $SMTPClient=New-Object System.Net.Mail.SmtpClient( $SmtpServer , $SmtpPort )
        $SMTPClient.EnableSsl=$true
        $SMTPClient.Credentials=New-Object System.Net.NetworkCredential( $SmtpUser , $SmtpPassword );
        $SMTPClient.Send( $email )
    }
    
    Export-ModuleMember Send-WinEventEntryEmail

    blachniet-psutils.psd1 を開き、’Send-WinEventEntryEmail’を以下のようにモジュールに追加します。

    # Modules to import as nested modules of the module specified in ModuleToProcess
    NestedModules = 'Get-WebItem', 'Send-EventEntryEmail','Send-WinEventEntryEmail'

    また、この設定ではGoogleのSMTPサーバーを利用する設定になっていますが、SMTPサーバーを変更したい場合はスクリプト内のSMTPサーバーとポート番号を変更します。

  4. Powershellを管理者権限で開き、Import-Module blachniet-psutils を実行します。

 

イベントビューアーでカスタムビューを作成する

  1. イベントビューアーから[アプリケーションとサービス ログ]>[Microsoft]>[Windows]>[StorageSpaces-Driver]を開きます。
  2. 左側ペインの[StorageSpaces-Driver]を右クリックし[カスタムビューの作成]でイベントレベルの[重大][警告][エラー][情報]にチェックをつけ、[OK]を押下します。
  3. カスタムビューに名前をつけて保存します。
  4. 作成したカスタムビューは、イベントビューアーの[カスタムビュー]配下に表示されます。右クリックして、[このカスタムビューにタスクを設定]を押下します。
  5. 基本タスクの作成ウィザードが表示されます。[名前]や[説明]を入力して[次へ]を押下します。
  6. [イベントのログへの記録時]では[次へ]を押下します。
  7. [操作]で、[プログラムの開始]を選択し、[次へ]を押下します。
  8. スクリプトの場所や引数を入力して、[次へ]を押下し、完了画面で[完了]を押下します。
    プログラム/スクリプト:Powershell.exe
    引数の追加: Send-WinEventEntryEmail –SmtpUser ‘SMTP送信ユーザーアカウント’ -SmtpPassword ‘SMTPユーザーパスワード’ -MailFrom ‘FROMアドレス’ -MailTo ‘送信先アドレス’
    開始:C:\Windows\System32\WindowsPowerShell\v1.0\

タスクスケジューラーで設定を編集

タスクスケジューラーを開き、ログオンしていない場合にも実行されるよう設定します。

うまく動かない場合は

  • AD環境ではグループポリシーを確認して、タスクの実行時に使うユーザーアカウントが、[バッチジョブとしてログオン]の権利が割り当てられていることを確認します。
  • 遅延時間を30秒設定するとうまくイベントログの情報を拾ってくれそうです。遅延時間を設定するには、プロパティから、トリガータブを開き、編集を押下します。

PowerShellからメールの通知

記憶域スペースに障害が発生した場合、以下のようにメールが通知されます。件名などを編集したい場合は、PowerShellのモジュールを適宜修正してください。

 

カスタムビューで[情報]にチェックをつけておくことで、ディスクがオンラインに復帰した場合、情報として通知させることができます。

 

物理ディスクを監視したい場合

今回は記憶域プールやスペースに関してイベントが発生した場合をトリガーにしていますが、物理ディスクへのIO障害等をトリガーにしたい場合は、disk に関するイベントをトリガーにして、またPowerShellで ProviderNameがdiskのログを引っ張ってくるとよいでしょう。

環境によってはメールからITSへのチケット登録など工夫の余地あり

中小規模の環境であれば、まずは電子メールでの通知でも十分かもしれません。より大きな規模やSIerさんの立場ならITSへの登録をという場合もあるでしょうし、そもそも冒頭に書いたようなJP1/Baseなどが入っている環境なら、ここで記載した情報をもとに監視してもよいでしょう。イベント情報から監視への応用の余地は多数あるのではないでしょうか。

ださっち: