Oracleのリスナーログのローテーション

※2009/09/28 「当月が3〜12月の時の処理」に不備あり、修正

Windows限定だけども、Oracleのリスナーログをローテーションするバッチを作ってみた。
ちょくちょく使いそうなので、ここに保持しておくことに。
ほどよいのがあれば、流用したんだろうけども。


条件・特徴などは以下の通り。

・Windows2003ServerのOracle10gで確認
・過去1ヶ月分のログを保持
・1ヶ月以上前のログは削除
Oracleの各サービスの停止不要
・OSのタスクで毎日実行すると良いかも
・秒単位でリネームするので、一日に何回実行してもログは保持される*1

※注意 日付計算は手抜きです。


動作は以下のような感じ。

例:今日(6/23)実行した場合

・「listener.log」を「listener_YYYYMMDDhhmmss.log」にリネーム
・5/23分のログを削除
・4月分すべてのログを削除

日付計算は手抜きと言えども、毎日1回でも実行されれば、確実に先月同日のログは削除されます。
また、2月は28日(29日)までしかないので、1月29〜30日のログは削除されませんが、3月になれば2ヶ月前(1月)分をまとめて削除するので、問題なしと考えてます。


一応、環境にツッコむ前に、デバッグしてみてください。
リスナーログの出力先フォルダ*2に、「listener_YYYYMMDDhhmmss.log」形式で適当なファイルを作ってどうぞ。
※当バッチ名を「hogehoge.bat」とし、C:\直下に置き、2009年6月23日に実行させたと仮定

C:\> hogehoge.bat 20090623


で、以下がそのソース。
「set ORA_LOG=〜〜」の部分を、各環境のリスナーログの出力先に書き換えてください。
また、ソースに間違いがあったり、疑問などがあったら、コメント下され。

rem ******** リスナーログのリネームと削除 START ********
setlocal

rem リスナーログの出力先
set ORA_LOG=C:\oracle\product\10.2.0\db_1\NETWORK\log
rem 現在日付をYYYYMMDD形式で取得
set THIS_DATE=%date:/=%
  rem ※デバッグ用 引数に任意の日付をYYYYMMDD形式で指定
  set TEST_DATE=%1
  if defined TEST_DATE set THIS_DATE=%TEST_DATE%
set THIS_Y=%THIS_DATE:~0,4%
set THIS_M=%THIS_DATE:~4,2%
set THIS_D=%THIS_DATE:~6,2%
rem 現在時刻をhhmmss形式で取得
set THIS_T=%time:~0,8%
set THIS_T=%THIS_T::=%
set THIS_T=%THIS_T:.=%
set THIS_T=%THIS_T: =0%

rem リスナーログの出力先を一時的に「listener_tmp.log」に変更
lsnrctl set log_file listener_tmp.log

rem ======== リスナーログのリネーム START ========
rem 現在日時をYYYYMMDDhhmmss形式で取得
set TIME_TMP=%THIS_DATE%%THIS_T%
rem 「listener.log」を「listener_YYYYMMDDhhmmss.log」にリネーム
rename %ORA_LOG%\listener.log listener_%TIME_TMP%.log
rem リスナーログの出力先を「listener.log」に修正
lsnrctl set log_file listener.log
rem 「listener_tmp.log」に吐かれたログを「listener_%TIME_TMP%.log」に追記
type %ORA_LOG%\listener_tmp.log >> %ORA_LOG%\listener_%TIME_TMP%.log
rem 不要になった「listener_tmp.log」を削除
del %ORA_LOG%\listener_tmp.log
rem ======== リスナーログのリネーム END ========

rem ======== 一ヶ月前のリスナーログを削除 START ========
rem 当月が1月の時の処理
set /a DAY_DEL_Y=%THIS_Y%-1
set /a MONTH_DEL_Y=%THIS_Y%-1
set DAY_DEL_M=12
set MONTH_DEL_M=11
if %THIS_M% == 01 goto _LOGDEL
rem 当月が2月の時の処理
set DAY_DEL_Y=%THIS_Y%
set /a MONTH_DEL_Y=%THIS_Y%-1
set DAY_DEL_M=01
set MONTH_DEL_M=12
if %THIS_M% == 02 goto _LOGDEL
rem 当月が3〜12月の時の処理
if %THIS_M% LSS 10 set THIS_M=%THIS_M:0=%
set DAY_DEL_Y=%THIS_Y%
set MONTH_DEL_Y=%THIS_Y%set /a DAY_DEL_M=%THIS_M%-1
if %DAY_DEL_M% LSS 10 set DAY_DEL_M=0%DAY_DEL_M%
set /a MONTH_DEL_M=%THIS_M%-2
if %MONTH_DEL_M% LSS 10 set MONTH_DEL_M=0%MONTH_DEL_M%
:_LOGDEL
rem 1ヶ月前の日付を取得
set DAY_DEL_DATE=%DAY_DEL_Y%%DAY_DEL_M%%THIS_D%
rem 2ヶ月前の月を取得
set MONTH_DEL_DATE=%MONTH_DEL_Y%%MONTH_DEL_M%
rem 1ヶ月前の日のログを全て削除
del /Q %ORA_LOG%\listener_%DAY_DEL_DATE%*.log
rem 2ヶ月前の月のログを全て削除
del /Q %ORA_LOG%\listener_%MONTH_DEL_DATE%*.log
rem ======== 一ヶ月前のリスナーログを削除 END ========

endlocal
rem ******** リスナーログのリネームと削除 END ********

*1:無茶な実行の仕方をしなければね

*2:デフォルトだと「C:\oracle\product\10.2.0\db_1\NETWORK\log」。10.2.0の部分はバージョンによって?