Kevin Kempf's Blog

June 10, 2011

Rotating Listener Logs without Bouncing the Listener

Filed under: 10g, 11g, Oracle — kkempf @ 9:38 am

It's too big!

The Trouble with Listener Logs

Is that over time, they’re easily forgotten about.  Then they get ginormous, and really unmanageable.  I think there used to be a 2gb limit, after which they’d just kind of stop writing, but I haven’t seen that recently.  Perhaps that was a 32-bit limitation, or a 9i limitation, unsure.  Regardless, I thought I’d share a nifty little shell script for linux which helps manage this issue.

There’s a basic problem with the listener log in Linux: while you can move/rename it, it won’t start a new log file until the listener is bounced.  This is because the listener data is written to the inode, and doesn’t take your change into effect until the listener is bounced.

This fix is based on the premise that you can use lsnrctl to set log_status off, which allows you to manipulate the underlying log file.  You can then set it back to on, and it will continue happily logging connections.

rotate_listener_log.sh

There’s a few assumptions which you may need to tweak for your environment.  First, that you set your environment in the first line for the RDBMS; this essentially is just a call to invoke the $ORACLE_HOME/SID_host.env file.   You can easily hard code this to your needs.  Second, that you have a named listener which has the same name as your SID.  Finally, that you have the zip utility somewhere in your base path.

In case you were wondering, why the %s in the datestamp?  It basically makes the filename it creates reasonably unique, so that in case you accidentally (or intentionally, while testing) run this script multiple times in one day, you don’t lose your logs.

Parameters: The first parameter is simply the database SID, represented as ${1} which is used to invoke the database environment, and also to turn off/on the logging of the listener by the same name.  The second parameter is the full path to the current listener log.

# rotate_listener_log.sh
. ~/env/${1}_ORACLE
LOGFILE=${2}
DATE_STAMP=`date +%m%d%y%s`

lsnrctl <<END
set current_listener ${1}
set log_status off
exit
END
mv $LOGFILE $LOGFILE.${DATE_STAMP}
lsnrctl <<END
set current_listener ${1}
set log_status on
exit
END
zip $LOGFILE.${DATE_STAMP}.zip $LOGFILE.${DATE_STAMP}
rm $LOGFILE.${DATE_STAMP}

Script in Action

$ ls -ltr $LISTENER_LOG_HOME
total 41316
-rw-rw-r-- 1 oradevl dba     2663 Jun 10 10:23 dev.log.0610111307715830.zip
-rw-rw---- 1 oradevl dba      888 Jun 10 10:23 dev.log
$ ./rotate_listener_log.sh DEV /u01/appdevl/oracle/devdb/11.1.0/log/diag/tnslsnr/myhost/dev/trace/dev.log

LSNRCTL for Linux: Version 11.1.0.7.0 - Production on 10-JUN-2011 10:24:59

Copyright (c) 1991, 2008, Oracle.  All rights reserved.

Welcome to LSNRCTL, type "help" for information.

LSNRCTL> Current Listener is DEV
LSNRCTL> Connecting to (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROCDEV))
DEV parameter "log_status" set to OFF
The command completed successfully
LSNRCTL>
LSNRCTL for Linux: Version 11.1.0.7.0 - Production on 10-JUN-2011 10:24:59

Copyright (c) 1991, 2008, Oracle.  All rights reserved.

Welcome to LSNRCTL, type "help" for information.

LSNRCTL> Current Listener is DEV
LSNRCTL> Connecting to (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROCDEV))
DEV parameter "log_status" set to ON
The command completed successfully
LSNRCTL>   adding: u01/appdevl/oracle/devdb/11.1.0/log/diag/tnslsnr/myhost/dev/trace/dev.log.0610111307715899 (deflated 80%)
$ ls -ltr $LISTENER_LOG_HOME
total 41320
-rw-rw-r-- 1 oradevl dba     2663 Jun 10 10:23 dev.log.0610111307715830.zip
-rw-rw-r-- 1 oradevl dba      579 Jun 10 10:24 dev.log.0610111307715899.zip
-rw-rw---- 1 oradevl dba      931 Jun 10 10:25 dev.log

Throw it in cron, and you’re done!

For those not too good with cron

  • the first entry says at 0315 on the first day of the month, remove anything from the trace directory over a year old
  • the second entry runs the aforementioned script to rotate the listener logs at 00:00 (midnight) on the first of the month for the DEV db and affects the shown log
crontab -l
# cleanup listener logs
15 3 1 * * /usr/bin/find /u01/appdevl/oracle/devdb/11.1.0/log/diag/tnslsnr/myhost/dev/trace  -mtime +365 -exec rm -rf {} \;
# rotate listener logs
0 0 1 * * /scratch/oracle/dba/scripts/rotate_listener_log.sh DEV /u01/appdevl/oracle/devdb/11.1.0/log/diag/tnslsnr/myhost/dev/trace/dev.log

I know this should go without saying, but..

Test this script in a non-production environment and understand it before you use it!

Advertisements

2 Comments

  1. this works for me:

    cd $ListenerLogDir
    cp -p $LOGFILE $LOGFILE_`date ‘+%Y%m%d’`
    cat /dev/null >$LOGFILE
    zip $LOGFILE_`date ‘+%Y%m%d’`

    don’t need to touch the listener. There is however a chance of losing some log entries between the cp and cat.

    Comment by Ahmed — September 8, 2011 @ 4:50 am

    • That works as well, though you’re manipulating the logfile from the OS, instead of from the listener itself.

      Comment by kkempf — September 8, 2011 @ 7:29 am


RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Blog at WordPress.com.