2022年5月14日土曜日

サービス監視スクリプト (Windows版)

サーバーのプロセス監視 (Windowsの場合はサービス監視) は、監視ソフトウェア(ZabbixやJP1など)を使えば当たり前のように実現できる。ただし、環境やライセンスの関係でエージェントの導入ができない場合がある。

そのような場合でも、スクリプトを使ってプロセス監視 (サービス監視) を行うことは可能となる。

今回、Windowsのサービス監視を行うスクリプトを作ってみたので、その内容を記載する。

なお、Linuxのプロセス監視のスクリプトについては、以下記事を参照いただきたい。

実現方法

本スクリプトの設計概要を図示する。

このスクリプトは、確認対象のサービスを設定ファイル(check-service.conf)に記載しておき、Get-ServiceコマンドレットにてサービスがRunningステータスであるかどうかを確認する。

サービスダウンを検知した際は、Write-EventLogコマンドレットでApplicationイベントログにエラーメッセージを出力する。エラーメッセージ出力タイミングは、サービスダウンの初回発生時のみとし、それ以外は情報メッセージとして出力する。

以下に、本スクリプトで発生するメッセージを記載する。

サービス状態 メッセージ
正常時 [INFO] Service XXX up
正常状態継続時 [INFO] Service XXX still up
ダウン時 [ERROR] Service XXX down
ダウン状態継続時 [INFO] Service XXX still down

この処理をタスクスケジューラーで1分間隔で実行するよう登録し、定期的なサービス監視を実現する。

スクリプト実行手順

1. スクリプト実行前にイベントソースを登録

Windowsイベントログにイベントを出力する際に、事前にイベントソースの登録が必要となる。事前に管理者権限でPowerShellのプロンプトを開き、以下コマンドを実行しておくこと。

PS C:\> New-EventLog -LogName Application -Source "Service Check Script"

なお、イベントソースの登録削除は、以下のコマンドとなる。

PS C:\> Remove-EventLog -Source "Service Check Script"

2. スクリプト配置

以下にスクリプトのコードを記載する。GitHubにも配置してある。

スクリプトファイル:check-service.ps1

################
# Scripts name : check-service.ps1
# Usage        : ./check-service.ps1
#                同一ディレクトリにcheck-service.confを配置し、タスクスケジューラーで定期実行する。
#                事前にAdmin権限で以下コマンドをを実行すること。
#                New-EventLog -LogName Application -Source "Service Check Script"
# Description  : Windowsサービスチェックスクリプト
# Create       : 2022/05/02 tech-mmmm (https://tech-mmmm.blogspot.com/)
# Modify       : 
################

$currentdir = Split-Path -Parent $MyInvocation.MyCommand.Path
$conffile = $currentdir + "\check-service.conf"    # 設定ファイル
$tmpfile = $currentdir + "\check-service.tmp"      # サービス情報保存用一時ファイル
$event_source = "Service Check Script"             # スクリプトソース名

# すでにDownしているサービス情報を取得
if ( Test-Path -Path $tmpfile ){
    $down_service = Get-Content $tmpfile
}
Write-Output $null | Out-File $tmpfile

# 設定ファイル読み込み
foreach ($line in (Get-Content $conffile)) {   
    # コメント行と空行を処理しない
    if ( $line -notmatch "^ *#|^$" ){
        # 現在のサービス数を取得
        $count = (Get-Service -Name $line | Where-Object { $_.Status -eq "Running" }).count
        
        # サービス数チェック
        if ( $count -lt 1 ){
            # Down時の処理
            # Downしているサービスか確認
            if ( $down_service -eq $line ){
                # すでにDown
                $message = "Service """ + $line + """ still down"
                $event_type = "Information"
            }else{
                # 初回Down
                $message = "Service """ + $line + """ down"
                $event_type = "Error"
            }
            
            # イベントログに出力
            Write-Output $message
            Write-EventLog -LogName Application -EntryType $event_type -Source $event_source -EventId 100 -Message $message

            # Donwしているサービス情報を出力
            Write-Output $line | Out-File -Append $tmpfile
        }else{
            # Up時の処理
            # Downしていたサービスか確認
            if ( $down_service -eq $line ){
                # Downだった
                $message = "Service """ + $line + """ up"
                $event_type = "Information"                
            }else{
                # すでにUp
                $message = "Service """ + $line + """ still up"
                $event_type = "Information"
            }

            # イベントログに出力
            Write-Output $message
            Write-EventLog -LogName Application -EntryType $event_type -Source $event_source -EventId 100 -Message $message
        }
    }
}

exit 0

設定ファイル例:check-service.conf

# Service mame
Netlogon
W32Time
VMTools

3. タスクスケジューラーへの登録

タスクスケジューラーにて本スクリプトを1分間隔で実行するように設定する。こちらの方法については、以下別記事を参照いただきたい。

4. 監視テスト

実際にサービスを停止させて動作確認をしてみよう。W32Timeを停止させてサービス停止を検知することを確認してみる。

PS C:\> Stop-Service -Name W32Time
PS C:\> Get-EventLog -LogName Application -Source "Service Check Script"

   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
   12652 5 03 06:27    Information Service Check Script          100 Service "VMTools" still up
   12651 5 03 06:27    Error       Service Check Script          100 Service "W32Time" down  ★停止を検知
   12650 5 03 06:27    Information Service Check Script          100 Service "Netlogon" still up
~(以下略)~

次に、復旧時の動作を確認する。

PS C:\> Start-Service -Name W32Time
PS C:\> Get-EventLog -LogName Application -Source "Service Check Script"

   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
   12655 5 03 06:29    Information Service Check Script          100 Service "VMTools" still up
   12654 5 03 06:29    Information Service Check Script          100 Service "W32Time" up ★復旧
   12653 5 03 06:29    Information Service Check Script          100 Service "Netlogon" still up
~(以下略)~

以上。

更新履歴

  • 2017/12/18 新規作成
  • 2022/05/14 全体的にスクリプトの構成を見直し

0 件のコメント:

コメントを投稿

人気の投稿