Windows
PowerShell

Powershell 基礎勉強会の課題回答

課題回答


<# コメント開始

作成:ヤマゾン
作成日:2017/10/30
スクリプト名:Check_Oracle_listener_hanging_or_not_when_the_service_started.ps1
配置場所:E:¥xxxxx¥


    1. スクリプト作成の背景
      Listener サービスの起動後、Listener サービスが Listener.logに、
      下記文言を出力していない場合、内部で起動ハングしています。
      文言:「Listener completed notification to CRS on start」
      文言を出力していない場合には検知し、対処としてサービスを再起動する必要があります。


    2. スクリプト動作の前提条件となっている事項
      Listener サービスの起動後、Listener サービスはListener.logにまず、
      「pid=xxxxで起動しました。」と出力します。※ xxxx はプロセスID
      文言:「Listener completed notification to CRS on start」
      を出力する行は、「pid=xxxxで起動しました。」と出力している行から 3 行後です。

      Listener.log には、前回・前々回の起動など、複数回の出力が含まれています。
      そのため、今回の起動(一番最後の起動)によるハングを検知するには、
      Listener.log 内で一番最後に出力している、
      「pid=xxxxで起動しました。」を探す必要があります。
      そして、3行先に該当文言が出ている場合に "OK" を、
      出ていない場合 "NG" と返します。

      本来であれば、該当文言が出ていれば終了コード 0 を返し、
      出ていない場合はListener サービスの再起動をしますが、
      勉強会の課題であるため、"OK"または"NG"を出力するのみの実装とします。




          #### Listener.log の例示 ここから############################


          2015-07-05 13:38:18.674000 +09:00
          システム・パラメータ・ファイルは/u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.oraです。
          ログ・メッセージを/u01/app/oracle/diag/tnslsnr/oraclelinux/listener/alert/log.xmlに書き込みました。
          トレース情報を/u01/app/oracle/diag/tnslsnr/oraclelinux/listener/trace/ora_4467_140172889650944.trcに書き込みました。
          トレース・レベルは現在0です。

          pid=4467で起動しました
          リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
          リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oraclelinux.onefact.jp)(PORT=1521)))
          Listener completed notification to CRS on start


          05-7月 -2015 13:41:35 * service_update * orcl * 0
          2015-07-05 13:41:37.360000 +09:00
          05-7月 -2015 13:41:37 * service_update * orcl * 0
          2015-07-05 13:41:40.363000 +09:00
          05-7月 -2015 13:41:40 * service_update * orcl * 0


          2015-07-06 13:48:18.674000 +09:00
          システム・パラメータ・ファイルは/u01/app/oracle/product/11.2.0.4/db_1/network/admin/listener.oraです。
          ログ・メッセージを/u01/app/oracle/diag/tnslsnr/oraclelinux/listener/alert/log.xmlに書き込みました。
          トレース情報を/u01/app/oracle/diag/tnslsnr/oraclelinux/listener/trace/ora_4467_140172889650944.trcに書き込みました。
          トレース・レベルは現在0です。

          pid=4467で起動しました
          リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
          リスニングしています: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oraclelinux.onefact.jp)(PORT=1521)))
          Listener completed notification to CRS on start

          2015-07-06 13:49:40.363000 +09:00
          05-7月 -2015 13:49:40 * service_update * orcl * 0


          #### Listener.log の例示 ここまで############################




    3. 本スクリプトで行う処理(①②)
         ① 今回の起動(一番最後の起動)でのハングを検知するために、
            Listener.log 内で一番最後に出力している、「pid=xxxxで起動しました。」を探して行番号を取得します。

         ② ①で取得した行の3行後 (①の行番号+3) に下記文言が出ているかどうかを判定し、出ていれば "OK" 出ていない場合 "NG" と返します。
            文言:「Listener completed notification to CRS on start」


    4. 処理開始

コメント終了 #>

function check-listenerstart ($listener_log) {

  try {

      <# memo
           ① Listener.log 内で一番最後に出力している、「pid=xxxxで起動しました。」を探し、行番号を取得。
            「pid=xxxxで起動しました。」が出力されていない場合、異常終了。
      #>

          $dbstart_message                    = "^pid=[0-9]+で起動しました$"

          $check_dbstart                      = Select-String -Path $listener_log -Pattern $dbstart_message -encoding default -erroraction "stop"

          $last_line_of_dbstart_message       = $check_dbstart[-1]

          $last_linenumber_of_dbstart_message = ($last_line_of_dbstart_message).linenumber




      <# memo
           ② ①で取得した行の3行後 (①の行番号+3) に下記文言が出ているかどうかを判定。出ていれば "OK" 出ていない場合 "NG" と返します。
           文言:「Listener completed notification to CRS on start」
      #>

        $linenumber_of_checkstring = $last_linenumber_of_dbstart_message + 3

        $linenumber_of_checkstring = $linenumber_of_checkstring - 1    <# memo
                                                                          (gc xxxx.txt)[n] において、nは 0で開始するため、
                                                                          取得した行番号から-1する。
                                                                       #>

        $result_string             = (gc $listener_log  -erroraction "stop")[$linenumber_of_checkstring]

        $check_string              = "Listener completed notification to CRS on start"

        $check                     = $result_string.contains($check_string)

        if ($check) {return "OK"} else {return "NG"}


  } catch {
  get-date # 仮に例外がある場合に、エラーを補足するためのブロック
  $error
  }


# 関数(check-listenerstart)終了
}


# Listener.log 定義
  $listener_log1 = "C:\trace\Listener.log"

# 関数(check-listenerstart)実行
  check-listenerstart $listener_log1