# IAS.ctl: Collects Web and HTTP Information # $Id: IAS.ctl,v 1.6 2015/02/20 15:30:24 RDA Exp $ # ARCS: $Header: /home/cvs/cvs/RDA_8/src/scripting/lib/collect/OFM/IAS.ctl,v 1.6 2015/02/20 15:30:24 RDA Exp $ # # Change History # 20150220 KRA Improve list management. =head1 NAME OFM:IAS - Collects Web and HTTP Information =head1 DESCRIPTION This module collects Web and HTTP-related information. The following macros are available: =cut # Make the module persistent and share macros keep $KEEP_BLOCK,@SHARE_MACROS var @SHARE_MACROS = ('httpServer_getListenerConf',\ 'httpServer_getListenerLogs',\ 'httpServer_getJServConf',\ 'httpServer_getJServLogs',\ 'httpServer_getJServJavaVersions',\ 'httpServer_getModplsqlConf',\ 'httpServer_getOdlLog',\ 'httpServer_getStartScripts') var @RESET_MACROS = (@SHARE_MACROS,'httpServer_readConf') # Initialization delete $APACHE_TOP,$ORACLE_HOME,$TAIL import $APACHE_TOP,$ORACLE_HOME,$TAIL keep $APACHE_TOP,$OH1,$ORACLE_HOME,$TAIL var $OH = verbatim($ORACLE_HOME) var $OH1 = concat('^',$OH,'[\\\/]') if !$TAIL var $TAIL = ${DFT.N_TAIL:1000} # Allow to define the variables at upper level but reset them delete %HTTPDCONF,%HTTPDERRLOG,%HTTPDREQLOG,%HTTPDMODPLSQLCFG,\ @HTTPDSTARTSCRIPTS,@JSERVCFGFILES,%JSERVLOG,%JSERVPROPERTIES,\ %JSERVZONEPROPS,$SERVERROOT import %HTTPDCONF,%HTTPDERRLOG,%HTTPDREQLOG,%HTTPDMODPLSQLCFG,\ @HTTPDSTARTSCRIPTS,@JSERVCFGFILES,%JSERVLOG,%JSERVPROPERTIES,\ %JSERVZONEPROPS,$SERVERROOT keep %HTTPDCONF,%HTTPDERRLOG,%HTTPDREQLOG,%HTTPDMODPLSQLCFG,\ @HTTPDSTARTSCRIPTS,@JSERVCFGFILES,%JSERVLOG,%JSERVPROPERTIES,\ %JSERVZONEPROPS,$SERVERROOT var %HTTPDCONF = () var %HTTPDERRLOG = () var %HTTPDREQLOG = () var %HTTPDMODPLSQLCFG = () var @HTTPDSTARTSCRIPTS = () var @JSERVCFGFILES = () var %JSERVLOG = () var %JSERVPROPERTIES = () var %JSERVZONEPROPS = () var $SERVERROOT = undef =head1 HTTP SERVER MACROS =head2 macro httpServer_getListenerConf([$flag]) This macro recursively searches all F included files. It modifies the following imported variables: =over 16 =item C<%HTTPDCONF> F and all included files (that is, all files that can contain configuration directives). =item C<$SERVERROOT> The Apache C setting. It may not be handled correctly in all cases. Non-absolute paths are relative to C, but if C is in the included files, C and include directives may not be processed in the correct order. =back It requires the C<$APACHE_TOP> and C<$ORACLE_HOME> variables. It does not generate reports when the flag is true. =cut macro httpServer_resolveVariables {var ($val,$hom,$ins,$typ,$nam) = @arg var $val = replace(replace(replace(replace($val,\ '\$\{ORACLE_HOME\}',$hom),\ '\$\{ORACLE_INSTANCE\}',$ins),\ '\$\{COMPONENT_TYPE\}',$typ),\ '\$\{COMPONENT_NAME\}',$nam) return $val } macro httpServer_getListenerConf {var ($flg,$ins,$typ,$nam) = @arg import $APACHE_TOP,$OH1,$ORACLE_HOME,$SERVERROOT,%HTTPDCONF macro httpServer_readConf {var ($fil,$bas,$ins,$typ,$nam) = @arg import $ORACLE_HOME,%HTTPDCONF keep $ORACLE_HOME,%HTTPDCONF # Treat a configuration file if ?testFile('fr',$fil) {loop $lin (grepFile($fil,'^\s*(ServerRoot|include)\s+','ij')) {var $val = trim(replace($lin,'^\s*\w+\s+'),"[\0x22\0x27]") if $ins var $val = httpServer_resolveVariables($val,$ORACLE_HOME,$ins,$typ,$nam) if match($lin,'^\s*ServerRoot\s+',true) {if and(testDir('dr',$val = catDir($val)),not(sameDir($val,$bas))) {if $bas echo 'Warning: Your HTTP server uses ServerRoot configurations that may \ not be handled properly by RDA.' var $bas = $val } } elsif match($lin,'^\s*include\s+',true) {if !isAbsolute($val = catFile($val)) var $val = catFile($bas,$val) if match($pat = basename($val),'[\*\?\[\]]') {loop $hit (grepDir(dirname($val),re($pat),cond(isUnix(),'np','inp'))) var $bas = httpServer_readConf($hit,$bas,$ins,$typ,$nam) } else var $bas = httpServer_readConf($val,$bas,$ins,$typ,$nam) } } var $HTTPDCONF{$fil} = $bas } # Treat a configuration directory elsif ?testDir('dx',$fil) {# If it is a directory then look for all files in that directory loop $det (grepDir($fil,'.','np')) {next match(basename($det),'^\.+$') if ?testFile('f',$det) var $bas = httpServer_readConf($det,$bas,$ins,$typ,$nam) } } # Return the current SERVERROOT return $bas } # Get all HTTP configuration files var $dir = catDir($APACHE_TOP,'conf') var $cnf = ${F_HTTPD_CONF_LOCATION} if ?testFile('f',$cnf) var $SERVERROOT = httpServer_readConf($cnf,'',$ins,$typ,$nam) elsif ?testFile('f',catFile($dir,'httpd.conf')) var $SERVERROOT = httpServer_readConf(lastFile(),'',$ins,$typ,$nam) elsif ?testFile('f',catFile($dir,'httpds.conf')) var $SERVERROOT = httpServer_readConf(lastFile(),'',$ins,$typ,$nam) else var $SERVERROOT = undef # Display the configuration files found if !$flg {toc '2:Listener Configuration' loop $fil (keys(%HTTPDCONF)) {var $nam = replace($fil,$OH1) report concat('lc_',$nam) write '---+ Content Taken from File ',encode($nam) call writeFilter($fil,'(PlsqlDatabasePassword\s*).*$') toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_LC',$txt } } } =head2 macro httpServer_getListenerLogs([$flag]) This macro retrieves the log files. It modifies the following imported variables: =over 16 =item C<%HTTPDERRLOG> All log files from C and C directives. =item C<%HTTPDREQLOG> All request log files from C and C directives. =back For F or F, it gets the last or most current file. Because the suffixes indicate the number of seconds since 1970, the last line from the alphabetically sorted output is the most recent or current one. Only suffixes with exactly ten digits are used because the billionth UNIX second was in 2001 and the 32bit overflow of UNIX time will be greater than 2 billion in 2038. Similarly named files such as F are ignored. It requires the C<$APACHE_TOP>, C<$ORACLE_HOME>, and C<%HTTPDCONF> variables. It does not generate reports when the flag is true. =cut macro httpServer_getArg {var $str = $arg[0] if !match($str,'^"') return split('\s',$str,2) # Encode special characters var $str = replace($str,'(\\\\|\\134)','\0x5C',true) var $str = replace($str,"\\\0x22",'\0x22',true) var $str = replace($str,"\\\0x27",'\0x27',true) var $str = replace($str,'\\042','\0x22',true) var $str = replace($str,'\\047','\0x27',true) # Extract the first argument var (undef,$str,$arg) = split('\s*\"\s*',$str,3) # Decode special characters var $str = replace($str,'\\0x22',"\0x22",true) var $str = replace($str,'\\0x27',"\0x27",true) var $str = replace($str,'\\0x5C',"\0x5C",true) return ($str,$arg) } macro httpServer_getListenerLogs {var ($flg,$ins,$typ,$nam) = @arg import $APACHE_TOP,$OH1,$ORACLE_HOME,$TAIL,\ %HTTPDCONF,%HTTPDERRLOG,%HTTPDREQLOG loop $cnf (keys(%HTTPDCONF)) {loop $lin (grepFile($cnf,'^\s*(ErrorLog|SSLLog)\s+','ij')) {if $ins var $lin = httpServer_resolveVariables($lin,$ORACLE_HOME,$ins,$typ,$nam) var ($fil) = httpServer_getArg(replace($lin,'^\s*\w+\s+')) if match($fil,'^\|') {# If the log is a Pipe log var ($cmd,$arg) = httpServer_getArg($fil) var $cmd = catFile(substr($cmd,1)) debug ' ErrorLog Logpipe program is ',$cmd if or(sameFile($cmd,catFile('bin','rotatelogs')),\ sameFile($cmd,catFile($HTTPDCONF{$cnf},'bin','rotatelogs')),\ sameFile($cmd,catFile($APACHE_TOP,'bin','rotatelogs')),\ sameFile($cmd,catFile('bin','odl_rotatelogs')),\ sameFile($cmd,catFile($HTTPDCONF{$cnf},'bin','odl_rotatelogs')),\ sameFile($cmd,catFile($APACHE_TOP,'bin','odl_rotatelogs'))) {# Well-known rotatelogs as pipe command. Log base name is the first param. var ($fil) = httpServer_getArg($arg) var $fil = catFile($fil) debug ' ErrorLog Logpipe base name: ',$fil if !isAbsolute($fil) var $fil = catFile($HTTPDCONF{$cnf},$fil) var ($dir,$bas) = (dirname($fil),basename($fil)) var @tbl = reverse(grepDir($dir,concat('^',$bas,'\.\d{10}$'),'np')) if !and(match($cmd,'odl_rotatelogs$'),testFile('fr',$fil)) var $fil = shift(@tbl) debug ' ErrorLog Logpipe using file: ',$fil if ?testFile('fr',$tbl[0]) var $HTTPDERRLOG{$tbl[0]} = 2 } else {var $fil = undef } } elsif !match($fil,'^syslog(:.*)$') {# If log is neither a Pipe log nor a syslog, it can only be a normal file if !isAbsolute($fil = catFile($fil)) var $fil = catFile($HTTPDCONF{$cnf},$fil) } if ?testFile('fr',$fil) var $HTTPDERRLOG{$fil} = 1 } # Not sure whether spaces in customlogs file names are correctly dealt here loop $lin (grepFile($cnf,'^\s*(TransferLog|CustomLog)\s','ij')) {if $ins var $lin = httpServer_resolveVariables($lin,$ORACLE_HOME,$ins,$typ,$nam) var ($fil) = httpServer_getArg(replace($lin,'^\s*\w+\s+')) if match($fil,'^\|') {# If the log is a Pipe log var ($cmd,$arg) = httpServer_getArg($fil) var $cmd = catFile(substr($cmd,1)) debug ' TransferLog Logpipe program is ',$cmd if or(sameFile($cmd,catFile('bin','rotatelogs')),\ sameFile($cmd,catFile($HTTPDCONF{$cnf},'bin','rotatelogs')),\ sameFile($cmd,catFile($APACHE_TOP,'bin','rotatelogs')),\ sameFile($cmd,catFile('bin','odl_rotatelogs')),\ sameFile($cmd,catFile($HTTPDCONF{$cnf},'bin','odl_rotatelogs')),\ sameFile($cmd,catFile($APACHE_TOP,'bin','odl_rotatelogs'))) {# Well-known rotatelogs as pipe command. Log base name is the first param. var ($fil) = httpServer_getArg($arg) var $fil = catFile($fil) debug ' TransferLog Logpipe base name: ',$fil if !isAbsolute($fil) var $fil = catFile($HTTPDCONF{$cnf},$fil) var ($dir,$bas) = (dirname($fil),basename($fil)) var @tbl = reverse(grepDir($dir,concat('^',$bas,'\.\d{10}$'),'np')) if !and(match($cmd,'odl_rotatelogs$'),testFile('fr',$fil)) var $fil = shift(@tbl) debug ' TransferLog Logpipe using file: ',$fil if ?testFile('fr',$tbl[0]) var $HTTPDREQLOG{$tbl[0]} = 2 } else var $fil = undef } elsif !match($fil,'^syslog(:.*)$') {# If log is neither a Pipe log nor a syslog, it can only be a normal file if !isAbsolute($fil = catFile($fil)) var $fil = catFile($HTTPDCONF{$cnf},$fil) } if ?testFile('fr',$fil) var $HTTPDREQLOG{$fil} = 1 } } if !$flg {toc '2:Listener Log Files' loop $fil (keys(%HTTPDERRLOG),keys(%HTTPDREQLOG)) {var $nam = replace($fil,$OH1) report concat('ll_',$nam) write '---+ Last ',$TAIL,' Lines from File ',encode($nam) call writeTail($fil,$TAIL) toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_LL',$txt } } } =for stopwords getJServConf httpServer JServ Jserv jserv =head2 macro httpServer_getJServConf This macro retrieves the Jserv configuration. It modifies the following imported variables: =over 16 =item C<%JSERVPROPERTIES> All F that are used by Apache configurations. =item C<%JSERVZONEPROPS> The F of all recognized JServ engines. =item C<@JSERVCFGFILES> Both the jserv properties files and the zone properties files. =back It requires the C<$ORACLE_HOME>, and C<%HTTPDCONF> variables. =cut macro httpServer_getJServConf {import $OH1,$ORACLE_HOME,%HTTPDCONF,%JSERVPROPERTIES,%JSERVZONEPROPS,\ @JSERVCFGFILES loop $cnf (keys(%HTTPDCONF)) {loop $lin (grepFile($cnf,'^\s*ApJServProperties\s+','ij')) {var $fil = trim(replace($lin,'^\s*\w+\s+'),"[\0x22\0x27]") if ?testFile('fr',$fil) var $JSERVPROPERTIES{$fil} = 1 } loop $lin (grepFile($cnf,'^\s*ApJServGroup\s+[\w\-]+\s+\d+\s+\d+\s+','ij')) {var $fil = field('\s+',-1,$lin) if ?testFile('fr',$fil) var $JSERVPROPERTIES{$fil} = 1 } } loop $prp (keys(%JSERVPROPERTIES)) {call push(@JSERVCFGFILES,$prp) loop $lin (grepFile($prp,'^\s*zones\=','ij')) {loop $zon (split(',',trim(replace($lin,'^[^\=]+\=')))) {loop $fil (grepFile($prp,concat('^\s*',$zon,'\.properties='))) {var $fil = replace($fil,'^[^\=]+=') if ?testFile('fr',$fil) {var $JSERVZONEPROPS{$fil} = 1 call push(@JSERVCFGFILES,$fil) } } } } } # Do not make $JSERVCFGFILES unique, because it would mix up the entry order if @JSERVCFGFILES {toc '2:JServ Configuration' loop $fil (@JSERVCFGFILES) {var $nam = replace($fil,$OH1) report concat('jc_',$nam) write '---+ Content Taken from File ',encode($nam) call writeFile($fil) toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_JC',$txt } } } =for stopwords getJServJavaVersions =head2 macro httpServer_getJServJavaVersions This macro determines the Java versions used by Jserv. It requires C<%JSERVPROPERTIES>. =cut macro httpServer_getJServJavaVersions {import %JSERVPROPERTIES # Find JDK versions used by JServ engines. var %wrapperbin = () loop $prp (keys(%JSERVPROPERTIES)) {loop $lin (grepFile($prp,'^\s*wrapper\.bin\=','i')) {loop $cmd (split(',',trim(replace($lin,'^[^\=]+\=')))) var $wrapperbin{$cmd} = 1 } } report jserv_javaversions prefix write '---+ Java Versions' loop $cmd (keys(%wrapperbin)) {write '---++ ',encode($cmd) if compare('eq',basename(dirname($cmd)),'bin') call statFile('p',dirname(dirname($cmd))) write var $cmd = quote($cmd) call writeCommand(concat($cmd,' -version 2>&1')) write call writeCommand(concat($cmd,' -fullversion 2>&1')) } if isCreated(true) toc '2:[[',getFile(),'][rda_report][Java Versions used by JServ]]' } =for stopwords getJServLogs JServer =head2 macro httpServer_getJServLogs This macro gets the JServer logs. It modifies the following imported variable: =over 16 =item C<%JSERVLOG> JServ log files, both from the engines themselves and from the Apache module. =back It requires the C<$APACHE_TOP>, C<$ORACLE_HOME>, and C<%JSERVPROPERTIES> variables. =cut macro httpServer_getJServLogs {import $OH1,$ORACLE_HOME,$TAIL,%HTTPDCONF,%JSERVLOG,%JSERVPROPERTIES loop $cnf (keys(%HTTPDCONF)) {loop $fil (grepFile($cnf,'^\s*ApJServLogFile\s+','ij')) {var $fil = trim(replace($fil,'^\s*\w+\s+'),"[\0x22\0x27]") if !isAbsolute($fil) var $fil = catFile($HTTPDCONF{$cnf},$fil) if !match($fil,'^\|') var $JSERVLOG{$fil} = 1 } } loop $prp (keys(%JSERVPROPERTIES)) {loop $fil (grepFile($cnf,'^\s*log.file\=','ij')) {var $fil = trim(replace($fil,'^[^\=]+\=')) if ?testFile('fr',$fil) var $JSERVLOG{$fil} = 1 } } pretoc '2:JServ Log Files' loop $fil (keys(%JSERVLOG)) {var $nam = replace($fil,$OH1) report concat('jl_',$nam) write '---+ Last ',$TAIL,' Lines from File ',encode($nam) call writeTail($fil,$TAIL) if !getLength() write encode($fil),' was empty.' toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_JL',$txt } unpretoc } =for stopwords getModplsqlConf =head2 macro httpServer_getModplsqlConf This macro attempts to find C from the environment and default location. It modifies the following imported variable: =over 16 =item C<%HTTPDMODPLSQLCFG> Heuristically finds candidates for the F file for F. =back It requires the C<$APACHE_TOP>, C<$ORACLE_HOME>, and C<@HTTPDSTARTSCRIPTS> variable. =cut macro httpServer_getModplsqlConf {import $APACHE_TOP,$OH1,$ORACLE_HOME,@HTTPDSTARTSCRIPTS,%HTTPDMODPLSQLCFG loop $hss (@HTTPDSTARTSCRIPTS) {loop $fil (grepFile($hss,'WV_GATEWAY_CFG')) {var $fil = trim(replace($fil,'^.WV_GATEWAY_CFG='),"[\0x22\0x27]") if ?testFile('fr',$fil) var $HTTPDMODPLSQLCFG{$fil} = 1 } } loop $fil (getEnv('WV_GATEWAY_CFG'),\ catFile(dirname($APACHE_TOP),'modplsql','cfg','wdbsvr.app')) {if ?testFile('fr',$fil) var $HTTPDMODPLSQLCFG{$fil} = 1 } pretoc '2:mod_plsql Configuration Files' loop $fil (keys(%HTTPDMODPLSQLCFG)) {var $nam = replace($fil,$OH1) report concat('pc_',$nam) write '---+ Content Taken from File ',encode($nam) call writeFilter($fil,'^(\s*password\s*=\s*).*$') toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_PC',$txt } unpretoc } =head2 macro httpServer_getOdlLog([$AS11,$ins,$typ,$cmp]) This macro retrieves the HTTP Server ODL log file. This new method for reporting diagnostic messages presents a common format for diagnostic messages and log files, and a mechanism for correlating all diagnostic messages from various components across Oracle Application Server. For Application Servers when ODL is enabled in XML mode, RDA collects the last 64 KiB of data by default. For Application Server 11g when ODL is enabled in Text mode, RDA collects the last 1000 lines by default. It requires the C<$APACHE_TOP>, and C<%HTTPDCONF> variables. =cut macro httpServer_getOdlLog {var ($AS11,$ins,$typ,$cmp) = @arg import $APACHE_TOP,$ODL_SIZE,$ORACLE_HOME,$TAIL,$TOP,%HTTPDCONF keep $APACHE_TOP,$ODL_SIZE,$ORACLE_HOME,$TAIL,$TOP # Determine the HTTP Server ODL log file location var $fil = undef loop $cfg (keys(%HTTPDCONF)) {# Determine the logging mode next !grepFile($cfg,'^\s*OraLogMode\s+','fij') var $mod = field('\s+',1,last) next !match($mod,cond($AS11,'ODL-Text|ODL-XML','oracle'),true) # Look for an user defined path loop $cfg (keys(%HTTPDCONF)) {next !grepFile($cfg,'^\s*OraLogDir\s+','fij') var ($lin) = (last) var $pth = trim(replace($lin,'^\s*\w+\s+'),"[\0x22\0x27]") if $AS11 var $pth = httpServer_resolveVariables($pth,$ORACLE_HOME,$ins,$typ,$cmp) if ?testDir('dr',$pth = catDir($pth)) {if $AS11 {if match($mod,'ODL-Text',true) {var $fil = catFile($pth,concat($cmp,'.log')) var $odl_txt = true } else var ($fil) = grepDir($pth,concat('^(',verbatim($cmp),'|log)\.xml$'),'f') } else var $fil = catFile($pth,'log.xml') } break } if !?$fil {if $AS11 {var $fil = catFile($ins,'diagnostics','logs',$typ,$cmp,concat($cmp,'.log')) var $odl_txt = true } else var $fil = catFile($APACHE_TOP,'logs','oracle','log.xml') } break } # Report log information if length($fil) {var $nam = encode(catSymbol($fil)) report odl_log if and($odl_txt,testFile('fr',$fil)) {prefix write '---+ Last ',$TAIL,' Lines from File ',$nam call writeTail($fil,$TAIL) } elsif createBuffer('odl','T',$fil,$ODL_SIZE) {if expr('<',last,0) {write '---## Information Taken from ',encode($fil) call statFile('b',$fil) call writeBuffer('odl') } else {while getLine('odl') {var $lin = chomp(last) break match($lin,'^ Scripts to start Apache: F and F. These scripts may have been changed to include additional environment variables. =back It requires the C<$APACHE_TOP> and C<$ORACLE_HOME> variables. =cut macro httpServer_getStartScripts {import $APACHE_TOP,$OH1,$ORACLE_HOME,@HTTPDSTARTSCRIPTS var $dir = catDir($APACHE_TOP,'bin') var $apactl = catFile($dir,'apachectl') var $htsctl = catFile($dir,'httpdsctl') if ?testFile('fr',$apactl) call push(@HTTPDSTARTSCRIPTS,$apactl) if ?testFile('fr',$htsctl) call push(@HTTPDSTARTSCRIPTS,$htsctl) pretoc '2:HTTP Server Start Scripts' loop $fil (@HTTPDSTARTSCRIPTS) {var $nam = replace($fil,$OH1) report concat('ss_',$nam) write '---+ Content Taken from File ',encode($nam) call writeFile($fil) toc '3:[[',getFile(),'][rda_report][',encode($txt = addSymbol($fil)),']]' share 'IAS_SS',$txt } unpretoc } =begin credits =over 10 =item RDA 4.2: Lionel Montmayeur. =item RDA 4.10: Russ Hodgson. =item RDA 4.16: Daniel Mortimer. =item RDA 4.19: Daniel Mortimer, Roelof Van Suilichem. =item RDA 4.20: Daniel Mortimer. =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