# DConet.ctl:122:Collects Oracle Net Information # $Id: DConet.ctl,v 1.13 2015/08/21 15:35:34 RDA Exp $ # ARCS: $Header: /home/cvs/cvs/RDA_8/src/scripting/lib/collect/OS/DConet.ctl,v 1.13 2015/08/21 15:35:34 RDA Exp $ # # Change History # 20150821 MSC Improve time consistency. =head1 NAME OS:DConet - Collects Oracle Net Information =head1 DESCRIPTION This module collects Oracle Net information. The following reports can be generated and are regrouped under C: =cut use Limit echo tput('bold'),'Processing OS.ONET module ...',tput('off') echo tput('bold'),'Listener checks may take a few minutes. \ Be patient...',tput('off') # Initialization var $ORACLE_HOME = ${SET.RDA.BEGIN.D_ORACLE_HOME:''} var $LIMIT = ${SET.RDA.CONFIG.W_LIMIT:'D'} var $SIZE = ${N_LOG_SIZE:1048576} var $TAIL = ${DFT.N_TAIL:1000} var $TNS_ADMIN = ${ENV.TNS_ADMIN:catDir($ORACLE_HOME,'network','admin')} var $TRC_SIZE = ${R_TRACE_SIZE/T:10} var $TRC_AGE = ${R_TRACE_AGE/T:15} var $TOC = '%TOC%' var $TOP = '[[#Top][Back to top]]' toc '1:Oracle Net' # Identify extra TNS admin directories var @TNS = () loop $key (${CUR.O_SETUP}->grep('^D_EXTRA_TNSADMIN$','r')) {loop $dir (${CUR.O_SETUP}->get_value($key)) {next grep(@TNS,code(sameDir($dir,last)),'f') call push(@TNS,$dir) } } # Load the common macros run RDA:library() # Get the 'ps' command var $PS_ARG var $PS_EF var $PS_ELF run &{check($osn = getOsName(),'aix', 'OS:OSaix',\ 'darwin', 'OS:OSdarwin',\ 'dec_osf', 'OS:OSosf',\ 'dynixptx', 'OS:OSptx',\ 'hpux', 'OS:OShpux',\ 'linux', 'OS:OSlinux',\ 'solaris', 'OS:OSsunos',\ cond(isUnix(),'OS:OSunix',\ isVms(), 'OS:OSvms'))}('PS') =head2 adapters - Adapters Output Executes the F<$ORACLE_HOME/bin/adapters> command. =cut report adapters var $pgm = catFile($ORACLE_HOME,'bin','adapters') if ?testFile('x',$pgm) {debug ' Inside ONET module, about to run adapters command' var $pgm = lastCommand() write '---+!! Output from Adapters in $ORACLE_HOME/bin' write $TOC write '---+ Installed Protocol Adapters' call writeCommand($pgm) write $TOP write '---+ Protocol Adapters for Oracle Executable' call writeCommand(join(' ',$pgm,catCommand($ORACLE_HOME,'bin','oracle'))) write $TOP } elsif ?testFile('f',$pgm) {debug ' Inside ONET module, adapters command not executable' write '**$ORACLE_HOME/bin/adapters not executable**%BR%\ Permissions for $ORACLE_HOME/bin/adapters are:%BR%' call statFile('b',$pgm) } if isCreated() toc '2:[[',getFile(),'][rda_report][Adapters Output]]' =pod Gets the Oracle Net (formerly called SQL*Net) configuration information. Some of the Oracle Net files can reside in multiple well-known locations. =cut var $HOM = getEnv('HOME') toc '2:Oracle Net Configuration' call cat_search('cman.ora',true,'sqlnet_') call cat_search('endpoints_listener.ora',false,'sqlnet_',\ '^(PASSWORDS_\w*\s*=).*$','%R:PASSWORD%') call cat_search('ldap.ora',true,'sqlnet_') call cat_search('listener.ora',false,'sqlnet_','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_search('names.ora',true,'sqlnet_','(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_search('protocol.ora',true,'sqlnet_') call cat_search('sqlnet.ora',false,'sqlnet_') call cat_search('tnsnames.ora',false,'sqlnet_') call cat_search('dbsnmp.ver',true,'sqlnet_') call cat_report($HOM,'.listener.ora','dot','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_report($HOM,'.protocol.ora','dot') call cat_report($HOM,'.sqlnet.ora','dot') call cat_report($HOM,'.tnsnames.ora','dot') if isVms() {# List the present files report sys_login_net prefix write '---+ SYS$LOGIN Oracle Net (SQL*Net) Files' var @tbl = grepDir($HOM,'\.ora$','inp') call statFile('b',@tbl) if isCreated(true) toc '2:[[',getFile(),'][rda_report][SYS$LOGIN Oracle Net Files]]' # Collect some of them call cat_report($HOM,'listener.ora','home_','^(PASSWORDS_\w*\s*=).*$',\ '%R:PASSWORD%') call cat_report($HOM,'protocol.ora','home_') call cat_report($HOM,'sqlnet.ora','home_') call cat_report($HOM,'tnsnames.ora','home_') } =pod Captures the Oracle Names configuration. =cut pretoc '2:Oracle Names Configuration' if loadCommand('namesctl exit 2>/dev/null') {if !grepLastFile('NNL-00018\:','f') {debug ' Inside ONET module, looking for Oracle Names server' report names write '---+ Oracle Names Server' call writeCommand('namesctl show server') write '---+ Oracle Names Status' call writeCommand('namesctl show status',false,0.5) unpretoc toc '2:[[',getFile(),'][rda_report][Oracle Names Configuration]]' } } var $dir = catDir($ORACLE_HOME,'network','names') call cat_report($dir,'sdns.ora','names_') call cat_report($HOM,'.sdns.ora','dot') unpretoc =pod Retrieves the Heterogeneous Services configuration and log files. =cut pretoc '2:Heterogeneous Services Configuration' var $dir = catDir($ORACLE_HOME,'hs','admin') loop $nam (grepDir($dir,'\.ora$','in')) call cat_report($dir,$nam,'hs_') unpretoc pretoc '2:Heterogeneous Services Log Files' call sort_files(3,$TAIL,\ grepDir(catDir($ORACLE_HOME,'hs','log'),'.','r'),\ grepDir(catDir($ORACLE_HOME,'hs','trace'),'.','r')) unpretoc =for stopwords sqlnet =head2 sqlnet_log - sqlnet.log Extracts the last 1000 lines of F<$ORACLE_HOME/network/log/sqlnet.log>. It searches for F in other usual locations for Oracle Database 11g and later. =cut pretoc '2:sqlnet.log Files' debug ' Inside ONET module, processing sqlnet.log' call tail_report(catDir($ORACLE_HOME,'network','log'),'sqlnet.log',$TAIL,\ 'sqlnet') if or(isWindows(),isCygwin()) {if getEnv('USERPROFILE') call sort_files(3,$TAIL,grepDir(catDir(last,'oracle'),'sqlnet\.log','ir',10)) } elsif getEnv('ORACLE_BASE') call sort_files(3,$TAIL,grepDir(catDir(last,'diag','clients'),'sqlnet\.log',\ 'ir',10)) unpretoc =head2 lstatus - Listener Status and Services It is possible that more than one listener can be started with the same name using a different Oracle home. For UNIX, because the listeners cannot be queried individually using the F that started them, it removes duplicate listener names to query the status of each one once only. For Windows, the listener list is extracted from the F file. C can hang, causing the script to hang. To prevent this, the request is limited to 30 seconds when C is supported in the Perl version. Passwords found in the F file are used. It analyzes the log file and collects existing trace files. =cut debug ' Inside ONET module, looking for running listeners' var ($ctx,$cmd) = ('the Oracle home directory') if ${F_LISTENER_ORA} var $lsn = catFile(last) elsif and(${SET.DB.ASM.B_IN_USE},compare('eq',${W_PREF},'asm')) {var $dir = ${SET.DB.ASM.D_ORACLE_HOME:''} var $sid = ${SET.DB.ASM.T_ORACLE_SID/P} if compare('eq',$sid,'*') run DB:ASMinit(\$dir,\$sid) var $lsn = catFile($dir,'network','admin','listener.ora') var $hom = setLocalEnv('ORACLE_HOME',$dir) if cond(isUnix(),grepDir(catDir($dir,'bin'),'^lsnrctl$','fp'),\ isVms() ,list('lsnrctl'),\ grepDir(catDir($dir,'bin'),'^lsnrctl\.exe$','fip')) var ($ctx,$cmd) = ('the ASM home directory',testFile('f',last)) } else var $lsn = catFile($ORACLE_HOME,'network','admin','listener.ora') if or(isWindows(),isCygwin()) {# Extract the listener list from listener.ora debug ' Inside ONET module, analyzing listener.ora' loop $lin (grepFile($lsn,'^sid_list_','i')) var $listeners{substr(key($lin),9)} = 1 loop $dir (@TNS) {loop $lin (grepFile(catFile($dir,'listener.ora'),'^sid_list_','i')) var $listeners{substr(key($lin),9)} = 1 } # Extract the listener list from task list in CVS format to avoid line splits loop $lin (grepCommand('tasklist /svc /FO csv',\ '\b(CMADMIN|TNSLSNR)\.EXE\b','i')) {if match($lin,'TNSListener([^"]*)',true) {var ($nam) = last if length($nam) var $listeners{$nam} = 1 else var $listeners{'LISTENER'} = 1 } elsif match($lin,'CMAdmin([^"]+)',true) var $cman{last} = 1 } loop $nam (keys(%cman)) delete $listeners{$nam} # Determine the listener command var $cmd = nvl($cmd,cond(testDir('d',catDir($ORACLE_HOME,'net80','admin')),\ 'lsnrctl80.exe','lsnrctl.exe')) } elsif isUnix() {# Extract the listener list if loadCommand($PS_ARG) {# When ps -o works on the platform, use it to get the listener name. debug ' Inside ONET module, using ps -o to find listener name' loop $lin (grepLastFile('tnslsnr')) {next match($lin,'ifile=',true) var $listeners{field('\s+',2,$lin)} = 1 } } elsif match($osn,'linux') {# On linux, ps elf must be used to get the listener name # (short listing does not provide the extra output) debug ' Inside ONET module, using ps -elf to find listener name' if grepDir('/etc','suse.*release','i') var $off = 6 else var $off = 7 loop $lin (grepCommand($PS_ELF,'tnslsnr.*inherit')) var $listeners{field('\s+',$off,substr($lin,39))} = 1 } elsif match($osn,'aix') {# Output from aix ps, the listener name is in a different spot debug ' Inside ONET module, using ps -ef to find listener name on AIX' loop $lin (grepCommand($PS_EF,'tnslsnr')) {next match($lin,'ifile=',true) var $listeners{field('\s+',3,substr($lin,39))} = 1 } } else {debug ' Inside ONET module, using ps -ef to find listener name' loop $lin (grepCommand($PS_EF,'tnslsnr')) {next match($lin,'ifile=',true) var $listeners{field('\s+',2,substr($lin,42))} = 1 } } # Determine the listener command var $cmd = nvl($cmd,'lsnrctl') } elsif isVms() {# Macro to resolve listener process name: ORA_NNN macro resolve_alias {var ($ref) = @arg var $pat = '(SID_LIST_|STARTUP_WAIT_TIME_|STOP_|CONNECT_TIMEOUT_|\ LOG_DIRECTORY_|LOG_LEVEL_|LOG_FILE_|TRACE_DIRECTORY_|\ TRACE_LEVEL_|TRACE_FILE_)' loop $lin (grepFile('TNS_ADMIN:LISTENER.ORA',$ref,'i')) {next match($lin,'^#') var $key = key($lin) if match($key,concat('^',$pat,'(.*)$'),true) {var (undef,$nam) = (last) if compare('eq',uc(substr($nam,-8)),$ref) return $nam } elsif compare('eq',uc(substr($key,-8)),$ref) return $key } return undef } # Get processes currently using the Listener program loop $lin (grepCommand('show device/file ora_root/nosys',\ 'TNSLSNR(_64)?.EXE','i')) {var $nam = field('\s',0,$lin) var $lgt = length($nam) decr $lgt,7 if ?resolve_alias(substr($nam,4,$lgt)) var $listeners{last} = 1 } # Determine the listener command var $cmd = 'lsnrctl' } else {var $cmd = undef } # Extract the passwords loop $lin (grepFile($lsn,'^passwords_\w*\s*=','i')) {var ($key) = match(key($lin),'passwords_(.*)',true) var $pwd{$key} = trim(value($lin),'\W+') } loop $dir (@TNS) {loop $lin (grepFile(catFile($dir,'listener.ora'),'^passwords_\w*\s*=','i')) {var ($key) = match(key($lin),'passwords_(.*)',true) if missing($pwd{$key}) var $pwd{$key} = trim(value($lin),'\W+') } } # Define macro to load command output macro load_lsn {var ($cmd,$req,$lsn,$pwd) = @arg if $pwd {var $tmp = createTemp('lsn') call writeTemp('lsn','set password ',$pwd) call writeTemp('lsn',$req,' ',$lsn) call writeTemp('lsn','exit') call closeTemp('lsn') call loadCommand(join(' <',$cmd,$tmp)) call unlinkTemp('lsn') } else call loadCommand(join(' ',$cmd,$req,$lsn)) } # Loop through all listeners debug ' Inside ONET module, going to get the listener status' report lstatus if ?getCodePage() write '' write '---+!! Listener Status, Log, Trace, and Services Information' write $TOC write write '%BR%**Are the listeners running?**%BR%\ If no information appears, either there are no listeners running or \ there are no listeners running from ',$ctx,'%BR%' write toc '2:[[',getFile(),'][rda_report][Listener Status and Services]]' if testCommand(join(' ',$cmd,'exit')) {var $siz = sprintf('%d',expr('/',$SIZE,1024)) loop $lsn (keys(%listeners)) {# Get the status echo ' Processing listener ',$lsn debug ' Inside ONET module, getting the listener status for ',$lsn write '---' write '#T_',$lsn toc '3:[[',getFile(),'#T_',$lsn,'][rda_report][',replace($lsn,'^$',' '),']]' write '---+ Status for ',$lsn call load_lsn($cmd,'status',$lsn,$pwd{$lsn}) call writeLastFile() write $TOP # Determine the trace file location debug ' Inside ONET module, getting the listener trace file location' var ($lin) = grepLastFile('Listener Trace File','f') var (undef,undef,undef,$trc) = split('\s+',$lin,4) if $trc {var ($trc,$rot) = match($trc,'^(.*?)(\d*)\.trc\s*$',true) if length($rot) var $rot = '\d+' } else {# If the trace file is not diaplyed, get the name from the parameter file var ($lin) = grepLastFile('Listener Parameter File','f') var (undef,undef,undef,$par) = split('\s+',trim($lin),4) if ?testFile('r',$par) {var ($dir,$trc,$cnt,$lgt) = (\ nvl(value(grepFile($par,concat('^\s*TRACE_DIRECTORY_',$lsn,'\b'),'if')),\ catDir($ORACLE_HOME,'network','trace')),\ nvl(value(grepFile($par,concat('^\s*TRACE_FILE_',$lsn,'\b'),'if')),$lsn),\ nvl(value(grepFile($par,concat('^\s*TRACE_FILENO_',$lsn,'\b'),'if')),1),\ value(grepFile($par,concat('^\s*TRACE_FILELEN_',$lsn,'\b'),'if'))) if and(expr('>',$cnt,1),$lgt) var ($trc,$rot) = (catFile($dir,$trc),'\d+') else var ($trc,$rot) = (catFile($dir,replace($trc,'\.[Tt][Rr][Cc]$'))) } } # Get and analyze the log file debug ' Inside ONET module, getting the listener log file' var ($lin) = grepLastFile('Log File','f') var (undef,undef,undef,$log) = split('\s+',$lin,4) var $log = trim($log) if !$log {write write 'Log File entry not found in listener status%BR%\ (This may be because the listener is not up)%BR%' } elsif ?$buf = openListenerLog($log,$SIZE) {write '---++!! Errors in Log' var $lnk = encode($log) output => d,log if cond(hasPeriod(),${CUR.O_LAST}->write_file($buf,['F',$log,'P','T']),\ ${CUR.O_LAST}->write_tail($buf,$TAIL,['F',$log,'T','T'])) {var $lnk = concat('[[',${CUR.O_LAST}->get_raw(true),'][_blank][',$lnk,']]') write ' * Links point to files that have been collected in their \ original format. Opening them directly in your browser can \ present security risks. To prevent them, access the file \ outside the browser or use the link to save them and use an \ adequate viewer.' } end ${CUR.O_LAST} write '|*Listener Name*|', $lsn,' |' write '|*Listener Log File*|',$lnk,' |' var ($lgt,$cnt) = $buf->count('TNS-') if hasPeriod() {write '|*TNS Errors (between ',getBeginTime(),' and ',getEndTime(),')*|',\ $cnt,' |' if $cnt {debug ' Inside ONET module, showing the range errors from listener ',$lsn write '---++!! Errors for ',$lsn write '' loop $lin ($buf->grep('TNS-')) write decode($lin) write '' } } else {if $buf->is_complete write '|*Total TNS Errors*|',$cnt,' |' else write '|*TNS Errors (in last ',$siz,' KiB)*|',$cnt,' |' if $cnt {write '|*TNS Errors (in last 1000 lines)*|',\ $buf->grep('TNS-','c',0,expr('-',$lgt,1000),$lgt),' |' debug ' Inside ONET module, showing the last 50 errors from listener ',$lsn write '---++!! Last 50 Errors for ',$lsn write '' loop $lin ($buf->grep('TNS-','',-50)) write decode($lin) write '' } } call $buf->close write $TOP } else {write write 'Could not read the log file: ',encode($log),'%BR%\ It does not exist even though it is specified for this listener%BR%' } # Collect the trace files if $trc {debug ' Inside ONET module, collecting the listener trace files' var $dir = dirname($trc) var $pat = concat('^',basename($trc),$rot,'\.trc$') var $vol = expr('*',$TRC_SIZE,1048576) prefix {write '---++!! Trace Files' write ' * Readable trace files not older than ',$TRC_AGE,' days' write ' * Trace file volume lower than ',$TRC_SIZE,' MiB' write '|*Trace File Name*| *Size(MiB)*|*Last Modified Date*|' } loop $fil (grepDir($dir,$pat,'ipt')) {var ($lnk,$siz) = (encode($fil),getSize($fil)) if and($siz,testFile('r',$fil),not(isOlder($fil,$TRC_AGE))) {decr $vol,$siz if expr('>=',$vol,0) {output d,concat('trc_',$lsn,'_',basename($fil)) if ${CUR.O_LAST}->write_data($fil) var $lnk = concat('[[',${CUR.O_LAST}->get_raw(true),\ '][_blank][',$lnk,']]') end ${CUR.O_LAST} } } write '|',$lnk,'| ',$siz,'|',getLastModify($fil,''),' |' } if hasOutput(true) write $TOP } # Get services debug ' Inside ONET module, getting the listener services for ',$lsn write '---+ Services Information for ',$lsn call load_lsn($cmd,'services',$lsn,$pwd{$lsn}) call writeLastFile() write $TOP } } else {write 'Unable to execute lsnrctl command' write 'File Permissions are:%BR%' call statFile('b',catFile($ORACLE_HOME,'bin',$cmd)) write 'User: ',id(),'%BR%' } if match($ctx,'ASM') call setLocalEnv('ORACLE_HOME',$hom) # For VMS, report quotas in TNSLSNR.COM file if isVms() {write '---' write '---+ Quota Logicals in ORA_NETWORK:TNSLSNR.COM' prefix write '' loop $lin (grepFile('ORA_NETWORK:TNSLSNR.COM','define\s+ORA_LSNR_','i')) write $lin if hasOutput(true) write '' } =head2 cman - Connection Manager Shows the connection manager services and status. =cut report cman var $TTL = '---+!! Connection Manager' loop $lin (grepFile(catFile($TNS_ADMIN,'cman.ora'),'^\s*\w+\s*=\s*')) {var $nam = key($lin) var $cmd = concat('cmctl show services -c ',$nam) prefix {if ?delete($TTL) {write last write $TOC } write "---+ Services for Connection Manager Instance '",$nam,"'" write '---## Using: ',encode($cmd) } if writeCommand($cmd) write $TOP var $cmd = concat('cmctl show status -c ',$nam) prefix {if ?delete($TTL) {write last write $TOC } write "---+ Status for Connection Manager Instance '",$nam,"'" write '---## Using: ',encode($cmd) } if writeCommand($cmd) write $TOP } if isCreated(true) toc '2:[[',getFile(),'][rda_report][Connection Manager]]' =head2 netenv - Network Environment Checks the setting of C and lists C<.ora> files from well-known directories. =cut debug ' Inside ONET module, net environment, looking for tns_admin' report netenv write '---+!! Display of Various Network Environment Information' write $TOC write '---+ Is TNS_ADMIN Being Used?' write '' loop $key (grepEnv('^TNS_')) write $key,'=',getEnv($key) write '' write $TOP debug ' Inside ONET module, net environment, doing ls of directories' write '---+ Listing of .ora Files in the Well Known Locations' macro list_ora {var ($dir) = @arg import $TOP keep %tbl if exists($tbl{$dir}) return write '---++ Listing of .ora files from ',encode($dir) if grepDir($dir,'\.ora$','inp') call statFile('b',last) else write 'There are no .ora files in ',encode($dir),'%BR%' write $TOP var $tbl{$dir} = 1 } call list_ora('/etc') call list_ora('/var/opt/oracle') call list_ora($tns_dft = catDir($ORACLE_HOME,'network','admin')) call list_ora(catDir($ORACLE_HOME,'network','names')) call list_ora(catDir($ORACLE_HOME,'hs','admin')) if !sameDir($tns_dft,$tns_env = getEnv('TNS_ADMIN')) call list_ora(catDir($tns_env)) debug ' Inside ONET module, get TNS listener processes' if isVms() {prefix {write '---+ TNS Listener Processes' write '' } loop $lin (grepCommand('show device/file ora_root/nosys',\ 'tnslsnr(_64)?\.exe','i')) write $lin } else {prefix {write '---+ TNS Listener Processes' write '' write getHeader() } loop $lin (grepCommand($PS_EF,'tnslsnr','i')) write $lin } if hasOutput(true) {write '' write $TOP } toc '2:[[',getFile(),'][rda_report][Network Environment]]' =head2 dynamic_dep - Dynamic Dependencies Lists the dynamic dependencies of executable files or shared libraries. =cut if $pgm = check($osn,'aix', 'dump -Xany -Hv',\ 'hpux', 'chatr',\ 'linux', 'ldd',\ 'solaris','ldd') {debug ' Inside ONET module, gather dynamic dependencies' report dynamic_dep prefix {write '---+!! Dynamic Dependencies' write $TOC } loop $fil (catFile($ORACLE_HOME,'bin','oracle'),\ catFile($ORACLE_HOME,'bin','tnslsnr'),\ catFile($ORACLE_HOME,'bin','names'),\ catFile($ORACLE_HOME,'bin','sqlplus'),\ catFile($ORACLE_HOME,'lib','libclntsh.so')) {if ?testFile('r',$fil) {var $cmd = concat($pgm,' ',quote($fil)) write '---+ Dynamic Dependencies of ', encode($fil) write '---## Using: ',encode($cmd) call writeCommand($cmd) write $TOP } } if isCreated(true) toc '2:[[',getFile(),'][rda_report][Dynamic Dependencies]]' } =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L =begin credits =over 10 =item RDA 4.21: Cameron Melvin. =item RDA 4.22: Grant Hayden. =item RDA 4.31: Grant Hayden. =back =end credits =head1 COPYRIGHT NOTICE Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. =head1 TRADEMARK NOTICE Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. =cut