From: Charles C. <ch...@ru...> - 2005-02-02 09:36:43
|
I have written a new plugin to allow me to analyse the SQL access log (if available). I hope others find it useful. One issue - some or all of the queries that I have written may use the MySQL specific dialect of SQL. However, most of the plugin provides the framework to parametrise the queries and to display the results and, I hope, I have documented how to add new queries. Use of the plugin requires administrator access as some of the information may be sensitive. regards, Charles <?php /* Copyright 2005 Charles Corrigan and $ThePhpWikiProgrammingTeam This file is (not yet) part of PhpWiki. PhpWiki is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PhpWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PhpWiki; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * A plugin that provides a framework and some useful queries to analyse the SQL * access log. This information may be sensitive and so is limited to * administrator access only. * * To add a new query, see _getQueryString() */ class WikiPlugin_AnalyseAccessLog extends WikiPlugin { /** * Build the query string * * FIXME - some or all of these queries may be MySQL specific / non-portable * * FIXME - is there a more correct way to get the name of the accesslog * table? * * The column names displayed are generated from the actual query column * names, so make sure that each column in the query is given a user * friendly name. Note that the column names are passed to _() and so may be * translated. * * If there are query specific where conditions, then the construction * " if ($where_conditions<>'') * $where_conditions = 'WHERE '.$where_conditions.' ';" * should be changed to * " if ($where_conditions<>'') * $where_conditions = 'AND '.$where_conditions.' ';" * and in the assignment to query have something like * " $query= "SELECT " * ."referer " * ."FROM $accesslog " * ."WHERE referer IS NOT NULL " * .$where_conditions */ function _getQueryString(&$args) { // extract any parametrised conditions from the arguments, // in particular, how much history to select $where_conditions = $this->_getWhereConditions($args); // get the correct name for the table //FIXME is there a more correct way to do this? global $DBParams; $accesslog = (!empty($DBParams['prefix']) ? $DBParams['prefix'] : '')."accesslog"; $query = ''; if ($args['mode']=='referring_urls') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."left(referer,length(referer)-instr(reverse(referer),'?')) AS Referring_URL, " ."count(*) AS Referral_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Referring_URL"; } elseif ($args['mode']=='referring_domains') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."left(referer, if(locate('/', referer, 8) > 0, locate('/', referer, 8) -1, length(referer))) AS Referring_Domain, " ."count(*) AS Referral_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Referring_Domain"; } elseif ($args['mode']=='remote_hosts') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_host AS Remote_Host, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Remote_Host"; } elseif ($args['mode']=='users') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_user AS User, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY User"; } elseif ($args['mode']=='host-users') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_host AS Remote_Host, " ."remote_user AS User, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Remote_Host, User"; } return $query; } function getDefaultArguments() { return array( 'mode' => 'referring_domains', // referring_domains, referring_urls, remote_hosts, users, host-users 'caption' => '', // blank means use the mode as the caption/title for the output 'local_referrers' => 'true', // only show external referring sites 'period' => '', // the type of period to report: // may be weeks, days, hours, minutes, or blank for all 'count' => '0' // the number of periods to report ); } function getName () { return _("AnalyseAccessLog"); } function getDescription () { return _("Show summary information from the access log table."); } function getVersion() { return preg_replace("/[Revision: $]/", '', "\$Revision: 0.1 $"); } function run($dbi, $argstr, &$request, $basepage) { // flag that the output may not be cached - i.e. it is dynamic $request->setArg('nocache',1); if (!$request->_user->isAdmin()) return HTML::p(_('The requested information is available only to administrators.')); if (!ACCESS_LOG_SQL==2) return HTML::p(_('The SQL_ACCESS_LOG is not enabled.')); // set aside a place for the table headers, see _setHeaders() $this->_theadrow = HTML::tr(); $this->_headerSet = false; $args = $this->getArgs($argstr, $request); $query = $this->_getQueryString($args); if ($query=='') return HTML::p(sprintf( _("Unrecognised parameter 'mode=%s'"), $args['mode'])); // get the data back. // Note that this must be done before the final generation of the table, // otherwise the headers will not be ready $tbody = $this->_getQueryResults($query, $dbi); return HTML::table(array( 'border' => 1, 'cellspacing' => 1, 'cellpadding' => 1), HTML::caption(HTML::h1(HTML::br(),$this->_getCaption($args))), HTML::thead($this->_theadrow), $tbody); } function _getQueryResults($query, &$dbi) { $queryResult = $dbi->genericSqlIter($query); if (!$queryResult) { $tbody = HTML::tbody((HTML::tr(HTML::td(_('_nothing_'))))); } else { $tbody = HTML::tbody(); while ($row = $queryResult->next()) { $this->_setHeaders($row); $tr = HTML::tr(); foreach ($row as $value) { // output a '-' for empty values, otherwise the table looks strange $tr->pushContent(HTML::td( empty($value) ? '-' : $value )); } $tbody->pushContent($tr); } } $queryResult->free(); return $tbody; } function _setHeaders($row) { if(!$this->_headerSet) { foreach ($row as $key => $value) { $this->_theadrow->pushContent(HTML::th(_($key))); } $this->_headerSet = true; } } function _getWhereConditions(&$args) { $where_conditions = ''; if ($args['period']<>'') { $since = 0; if ($args['period']=='minutes') { $since = 60; } elseif ($args['period']=='hours') { $since = 60 * 60; } elseif ($args['period']=='days') { $since = 60 * 60 * 24; } elseif ($args['period']=='weeks') { $since = 60 * 60 * 24 * 7; } $since = $since * $args['count']; if ($since>0) { if ($where_conditions<>'') $where_conditions = $where_conditions.' AND '; $since = time() - $since; $where_conditions = $where_conditions."time_stamp>$since"; } } if ($args['local_referrers']<>'true') { if ($where_conditions<>'') $where_conditions = $where_conditions.' AND '; $localhost = SERVER_URL; $len = strlen($localhost); $where_conditions = $where_conditions."left(referer,$len)<>'$localhost'"; } // the assumed contract is that there is a space at the end of the condtions string, // so that following SQL clauses (such as GROUP BY) will not cause a syntax error if ($where_conditions<>'') $where_conditions = $where_conditions.' '; return $where_conditions; } function _getCaption(&$args) { $caption = $args['caption']; if ($caption=='') $caption = _($args['mode']); if ($args['period']<>'' && $args['count']) $caption = $caption." - ".$args['count']." "._($args['period']); return $caption; } } ?> |
From: Reini U. <ru...@x-...> - 2005-02-02 11:59:54
|
Charles Corrigan schrieb: > I have written a new plugin to allow me to analyse the SQL access log (if > available). I hope others find it useful. Thanks. Sounds useful. There are some more useful accesslog plugins in the works for which I had no time yet. RhNav (FractalNavigation) by Walter Rafelsberger. http://phpwiki.sourceforge.net/phpwiki/FractalNavigationPlugin Also author of the shamino_com theme. One note: please use _("") and not _(''), xgettext requires " -- Reini Urban http://xarch.tu-graz.ac.at/home/rurban/ |
From: Charles C. <ch...@ru...> - 2005-02-02 15:19:06
|
Reini Urban wrote > There are some more useful accesslog plugins in the works for > which I had no time yet. RhNav (FractalNavigation) by Walter > Rafelsberger. > http://phpwiki.sourceforge.net/phpwiki/FractalNavigationPlugin > Also author of the shamino_com theme. I will have a look. I did look at lib/plugin/RecentReferrals.php but decided it was not flexible enough for what I wanted to do. > One note: please use _("") and not _(''), xgettext requires " OK, I redid the plugin below, replacing _('') with _(""). One thing I am not certain of - do all calls to _() have to use "" or is _($key) legal? While I was re-doing the file, I also added further documentation regarding adding new queries. New file lib/plugin/AnalyseAccessLog.php <?php /* Copyright 2005 Charles Corrigan and $ThePhpWikiProgrammingTeam This file is (not yet) part of PhpWiki. PhpWiki is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PhpWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PhpWiki; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * A plugin that provides a framework and some useful queries to analyse the SQL * access log. This information may be sensitive and so is limited to * administrator access only. * * To add a new query, see _getQueryString() */ class WikiPlugin_AnalyseAccessLog extends WikiPlugin { /** * Build the query string * * FIXME - some or all of these queries may be MySQL specific / non-portable. * Can someone suggest a way to detect the underlying database engine and * then load an engine specific set of queries? * * FIXME - is there a more correct way to get the name of the accesslog * table? * * To add a new query, add a new "} elseif { ($args['mode']=='new-query-name')" * section towards the end of this function, using one of the exiting queries * as a template. I have used the convention that, while constructing the * query string, * - each clause is on a separate line and * - each clause has the required trailing punctuation or space. * * The column names displayed are generated from the actual query column * names, so make sure that each column in the query is given a user * friendly name. Note that the column names are passed to _() and so may be * translated. * * If there are query specific where conditions, then the construction * if ($where_conditions<>'') * $where_conditions = 'WHERE '.$where_conditions.' '; * should be changed to * if ($where_conditions<>'') * $where_conditions = 'AND '.$where_conditions.' '; * and in the assignment to the query have something like * $query= "SELECT " * ."referer " * ."FROM $accesslog " * ."WHERE referer IS NOT NULL " * .$where_conditions */ function _getQueryString(&$args) { // extract any parametrised conditions from the arguments, // in particular, how much history to select $where_conditions = $this->_getWhereConditions($args); // get the correct name for the table //FIXME is there a more correct way to do this? global $DBParams; $accesslog = (!empty($DBParams['prefix']) ? $DBParams['prefix'] : '')."accesslog"; $query = ''; if ($args['mode']=='referring_urls') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."left(referer,length(referer)-instr(reverse(referer),'?')) AS Referring_URL, " ."count(*) AS Referral_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Referring_URL"; } elseif ($args['mode']=='referring_domains') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."left(referer, if(locate('/', referer, 8) > 0, locate('/', referer, 8) -1, length(referer))) AS Referring_Domain, " ."count(*) AS Referral_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Referring_Domain"; } elseif ($args['mode']=='remote_hosts') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_host AS Remote_Host, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Remote_Host"; } elseif ($args['mode']=='users') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_user AS User, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY User"; } elseif ($args['mode']=='host-users') { if ($where_conditions<>'') $where_conditions = 'WHERE '.$where_conditions.' '; $query = "SELECT " ."remote_host AS Remote_Host, " ."remote_user AS User, " ."count(*) AS Access_Count " ."FROM $accesslog " .$where_conditions ."GROUP BY Remote_Host, User"; } return $query; } function getDefaultArguments() { return array( 'mode' => 'referring_domains', // see _getQueryString(), currently one of // referring_domains, referring_urls, remote_hosts, users, host-users 'caption' => '', // blank means use the mode as the caption/title for the output 'local_referrers' => 'true', // only show external referring sites 'period' => '', // the type of history period to retrieve, see _getWhereConditions() // may be weeks, days, hours, minutes, or blank for all 'count' => '0' // the number of periods to retrieve ); } function getName () { return _("AnalyseAccessLog"); } function getDescription () { return _("Show summary information from the access log table."); } function getVersion() { return preg_replace("/[Revision: $]/", '', "\$Revision: 0.1 $"); } function run($dbi, $argstr, &$request, $basepage) { // flag that the output may not be cached - i.e. it is dynamic $request->setArg('nocache',1); if (!$request->_user->isAdmin()) return HTML::p(_("The requested information is available only to administrators.")); if (!ACCESS_LOG_SQL==2) return HTML::p(_("The SQL_ACCESS_LOG is not enabled.")); // set aside a place for the table headers, see _setHeaders() $this->_headerSet = false; $this->_theadRow = HTML::tr(); $args = $this->getArgs($argstr, $request); $query = $this->_getQueryString($args); if ($query=='') return HTML::p(sprintf( _("Unrecognised parameter 'mode=%s'"), $args['mode'])); // get the data back. // Note that this must be done before the final generation of the html table, // otherwise the headers will not be ready $tbody = $this->_getQueryResults($query, $dbi); return HTML::table(array( 'border' => 1, 'cellspacing' => 1, 'cellpadding' => 1), HTML::caption(HTML::h1(HTML::br(),$this->_getCaption($args))), HTML::thead($this->_theadRow), $tbody); } function _getQueryResults($query, &$dbi) { $queryResult = $dbi->genericSqlIter($query); if (!$queryResult) { $tbody = HTML::tbody((HTML::tr(HTML::td(_("_nothing_"))))); } else { $tbody = HTML::tbody(); while ($row = $queryResult->next()) { $this->_setHeaders($row); $tr = HTML::tr(); foreach ($row as $value) { // output a '-' for empty values, otherwise the table looks strange $tr->pushContent(HTML::td( empty($value) ? '-' : $value )); } $tbody->pushContent($tr); } } $queryResult->free(); return $tbody; } function _setHeaders($row) { if(!$this->_headerSet) { foreach ($row as $key => $value) { $this->_theadRow->pushContent(HTML::th(_($key))); } $this->_headerSet = true; } } function _getWhereConditions(&$args) { $where_conditions = ''; if ($args['period']<>'') { $since = 0; if ($args['period']=='minutes') { $since = 60; } elseif ($args['period']=='hours') { $since = 60 * 60; } elseif ($args['period']=='days') { $since = 60 * 60 * 24; } elseif ($args['period']=='weeks') { $since = 60 * 60 * 24 * 7; } $since = $since * $args['count']; if ($since>0) { if ($where_conditions<>'') $where_conditions = $where_conditions.' AND '; $since = time() - $since; $where_conditions = $where_conditions."time_stamp>$since"; } } if ($args['local_referrers']<>'true') { if ($where_conditions<>'') $where_conditions = $where_conditions.' AND '; $localhost = SERVER_URL; $len = strlen($localhost); $where_conditions = $where_conditions."left(referer,$len)<>'$localhost'"; } // the assumed contract is that there is a space at the end of the condtions string, // so that following SQL clauses (such as GROUP BY) will not cause a syntax error if ($where_conditions<>'') $where_conditions = $where_conditions.' '; return $where_conditions; } function _getCaption(&$args) { $caption = $args['caption']; if ($caption=='') $caption = _($args['mode']); if ($args['period']<>'' && $args['count']) $caption = $caption." - ".$args['count']." "._($args['period']); return $caption; } } ?> |
From: Reini U. <ru...@x-...> - 2005-02-02 15:55:31
|
Charles Corrigan schrieb: >>One note: please use _("") and not _(''), xgettext requires " > > OK, I redid the plugin below, replacing _('') with _(""). One thing I am not certain of - do all calls to _() have to use "" or is > _($key) legal? _($key) is legal but not extracted by xgettext, which collects all the strings for the pot file. So you must be sure to have the string defined somewhere else, otherwise no translation will be printed. And we don't like it, since it's hard to maintain. _WikiTranslation uses the php hash for these kind of tricks. -- Reini Urban http://xarch.tu-graz.ac.at/home/rurban/ |
From: Charles C. <ch...@ru...> - 2005-02-03 15:37:36
Attachments:
AnalyseAccessLog.patch
|
Attached is a patch to include my latest updates to this plugin. I have included the patch inline and also attached a file incase the message gets badly mangled. Changes: - change parameter: mode is now queryName - changed query names and column names to include spaces - make it easier to add a new query - fix use of _() - new parameters to filter the contents of the accesslog - new parameter to caption tables - new parameter to display the actual SQL for debugging purposes - make output table look nicer TODO: provide mechanism to make it easier to put the queries in a configuration file Regards, Charles Index: AnalyseAccessLog.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/plugin/AnalyseAccessLog.php,v retrieving revision 1.1 diff -u -r1.1 AnalyseAccessLog.php --- AnalyseAccessLog.php 2 Feb 2005 20:41:02 -0000 1.1 +++ AnalyseAccessLog.php 3 Feb 2005 15:22:36 -0000 @@ -19,6 +19,7 @@ along with PhpWiki; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /** * A plugin that provides a framework and some useful queries to analyse the SQL * access log. This information may be sensitive and so is limited to @@ -32,105 +33,97 @@ /** * Build the query string * - * FIXME - some or all of these queries may be MySQL specific / non-portable + * FIXME - some or all of these queries may be MySQL specific / non- + * portable. Can someone suggest a way to detect the underlying database + * engine and then load an engine specific set of queries? * - * FIXME - is there a more correct way to get the name of the accesslog - * table? + * To add a new query, add a new + * "} elseif ($queryName=='your new query name') {" + * section towards the end of this function, using one of the exiting + * queries as a template. I have used the convention that, while + * constructing the query string, + * - each clause is on a separate line and + * - each clause has the required trailing punctuation or space. * * The column names displayed are generated from the actual query column - * names, so make sure that each column in the query is given a user - * friendly name. Note that the column names are passed to _() and so may be - * translated. - * - * If there are query specific where conditions, then the construction - * " if ($where_conditions<>'') - * $where_conditions = 'WHERE '.$where_conditions.' ';" - * should be changed to - * " if ($where_conditions<>'') - * $where_conditions = 'AND '.$where_conditions.' ';" - * and in the assignment to query have something like - * " $query= "SELECT " - * ."referer " - * ."FROM $accesslog " - * ."WHERE referer IS NOT NULL " - * .$where_conditions + * names, I suggest that each column in the query is given a user friendly + * name. */ function _getQueryString(&$args) { // extract any parametrised conditions from the arguments, // in particular, how much history to select $where_conditions = $this->_getWhereConditions($args); - // get the correct name for the table - //FIXME is there a more correct way to do this? + // get the correct table name global $DBParams; - $accesslog = (!empty($DBParams['prefix']) ? $DBParams['prefix'] : '')."accesslog"; + $accesslog = (!empty($DBParams['prefix']) ? $DBParams['prefix'] : '').'accesslog'; $query = ''; - if ($args['mode']=='referring_urls') { - if ($where_conditions<>'') - $where_conditions = 'WHERE '.$where_conditions.' '; - $query = "SELECT " - ."left(referer,length(referer)-instr(reverse(referer),'?')) AS Referring_URL, " - ."count(*) AS Referral_Count " + $queryName = $args['queryName']; + + if ($queryName=='Referring URLs') { + $query = 'SELECT ' + ."left(referer,length(referer)-instr(reverse(referer),'?')) AS 'Referring URL', " + ."count(*) AS 'Referral Count' " ."FROM $accesslog " - .$where_conditions - ."GROUP BY Referring_URL"; + .($where_conditions ? 'WHERE '.$where_conditions : '') + ."GROUP BY 'Referring URL'"; - } elseif ($args['mode']=='referring_domains') { - if ($where_conditions<>'') - $where_conditions = 'WHERE '.$where_conditions.' '; + } elseif ($queryName=="Referring Domains") { $query = "SELECT " - ."left(referer, if(locate('/', referer, 8) > 0,locate('/', referer, 8) -1, length(referer))) AS Referring_Domain, " - ."count(*) AS Referral_Count " + ."left(referer, if(locate('/', referer, 8) > 0, locate('/', referer, 8) -1, length(referer))) AS 'Referring Domain', " + ."count(*) AS 'Referral Count' " ."FROM $accesslog " - .$where_conditions - ."GROUP BY Referring_Domain"; + .($where_conditions ? 'WHERE '.$where_conditions : '') + ."GROUP BY 'Referring Domain'"; - } elseif ($args['mode']=='remote_hosts') { - if ($where_conditions<>'') - $where_conditions = 'WHERE '.$where_conditions.' '; + } elseif ($queryName=="Remote Hosts") { $query = "SELECT " - ."remote_host AS Remote_Host, " - ."count(*) AS Access_Count " + ."remote_host AS 'Remote Host', " + ."count(*) AS 'Access Count' " ."FROM $accesslog " - .$where_conditions - ."GROUP BY Remote_Host"; + .($where_conditions ? 'WHERE '.$where_conditions : '') + ."GROUP BY 'Remote Host'"; - } elseif ($args['mode']=='users') { - if ($where_conditions<>'') - $where_conditions = 'WHERE '.$where_conditions.' '; + } elseif ($queryName=="Users") { $query = "SELECT " ."remote_user AS User, " - ."count(*) AS Access_Count " + ."count(*) AS 'Access Count' " ."FROM $accesslog " - .$where_conditions + .($where_conditions ? 'WHERE '.$where_conditions : '') ."GROUP BY User"; - } elseif ($args['mode']=='host-users') { - if ($where_conditions<>'') - $where_conditions = 'WHERE '.$where_conditions.' '; + } elseif ($queryName=="Host Users") { $query = "SELECT " - ."remote_host AS Remote_Host, " + ."remote_host AS 'Remote Host', " ."remote_user AS User, " - ."count(*) AS Access_Count " + ."count(*) AS 'Access Count' " ."FROM $accesslog " - .$where_conditions - ."GROUP BY Remote_Host, User"; + .($where_conditions ? 'WHERE '.$where_conditions : '') + ."GROUP BY 'Remote Host', User"; } return $query; } function getDefaultArguments() { return array( - 'mode' => 'referring_domains', - // referring_domains, referring_urls, remote_hosts, users, host-users - 'caption' => '', - // blank means use the mode as the caption/title for the output - 'local_referrers' => 'true', // only show external referring sites - 'period' => '', // the type of period to report: - // may be weeks, days, hours, minutes, or blank for all - 'count' => '0' // the number of periods to report - ); + 'queryName' => '', // the name of the query to execute, see _getQueryString() + // "Referring Domains", "Referring URLs", "Remote Hosts", + // "Users", "Host Users" + // but note that this is subject to change + 'caption' => '', // blank means use the mode as the caption/title for the output + 'debugShowQuery' => '', // if set, show the query string in the table footer + 'period' => '', // the type of history period to retrieve, see _getWhereConditions() + // may be weeks, days, hours, minutes, or blank for all + 'count' => '0', // the number of periods to retrieve - must be a number + 'user' => '', // empty/default to retrieve all users, or a specific user or + // <NONE> for no user + 'host' => '', // empty/default to retrieve all remote_hosts, or a specific host + 'referrer' => '', // empty/default to retrieve all referrers, + // <NONE> to retrieve no referrer or + // otherwise matched to the start of the referrer string + 'local_referrers' => 'true' // if not true, return only external referring sites + ); } function getName () { @@ -143,48 +136,52 @@ function getVersion() { return preg_replace("/[Revision: $]/", '', - "\$Revision: 1.1 $"); + "\$Revision: 0.1 $"); } function run($dbi, $argstr, &$request, $basepage) { - // flag that the output may not be cached - i.e. it is dynamic - $request->setArg('nocache', 1); + // flag that the output is dynamic and may not be cached + $request->setArg('nocache',1); if (!$request->_user->isAdmin()) - return HTML::p(_("The requested information is available only to Administrators.")); + return HTML::p(_("The requested information is available only to administrators.")); - if (!ACCESS_LOG_SQL) // need read access + if (!ACCESS_LOG_SQL==2) return HTML::p(_("The SQL_ACCESS_LOG is not enabled.")); // set aside a place for the table headers, see _setHeaders() - $this->_theadrow = HTML::tr(); $this->_headerSet = false; + $this->_theadRow = HTML::tr(); $args = $this->getArgs($argstr, $request); $query = $this->_getQueryString($args); - if ($query=='') - return HTML::p(sprintf( _("Unrecognised parameter 'mode=%s'"), - $args['mode'])); + if (!$query) + return HTML::p(sprintf(_("Unrecognised 'queryName=%s'"), + $args['queryName'])); // get the data back. - // Note that this must be done before the final generation ofthe table, - // otherwise the headers will not be ready + // Note that this must be done before the final generation of the html table, + // otherwise the headers will not be ready $tbody = $this->_getQueryResults($query, $dbi); - return HTML::table(array( 'border' => 1, - 'cellspacing' => 1, - 'cellpadding' => 1), - HTML::caption(HTML::h1(HTML::br(),$this->_getCaption($args))), - HTML::thead($this->_theadrow), + $caption = $this->_getCaption($args); + + return HTML::table(array('border' => 1, + 'cellspacing' => 2, + 'cellpadding' => 3, + 'summary' => $caption), + HTML::caption(HTML::br(), HTML::h1($caption)), + HTML::thead($this->_theadRow), + HTML::tfoot(HTML::tr(HTML::td(array('colspan' => 100), $args['debugShowQuery'] ? $query : ''))), $tbody); } function _getQueryResults($query, &$dbi) { $queryResult = $dbi->genericSqlIter($query); - if (!$queryResult) { - $tbody = HTML::tbody(HTML::tr(HTML::td(_("<empty>")))); + if (!$queryResult or !$queryResult->count()) { + $tbody = HTML::tbody((HTML::tr(HTML::td(_("_ no result _"))))); } else { $tbody = HTML::tbody(); while ($row = $queryResult->next()) { @@ -204,7 +201,7 @@ function _setHeaders($row) { if(!$this->_headerSet) { foreach ($row as $key => $value) { - $this->_theadrow->pushContent(HTML::th(_($key))); + $this->_theadRow->pushContent(HTML::th($key)); } $this->_headerSet = true; } @@ -226,25 +223,54 @@ } $since = $since * $args['count']; if ($since>0) { - if ($where_conditions<>'') - $where_conditions = $where_conditions.' AND '; $since = time() - $since; - $where_conditions = $where_conditions."time_stamp > $since"; + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."time_stamp>$since"; + } + if (1==2) { // this section is to ensure that the period names are available for translation + _("minutes"); _("hours"); _("days"); _("weeks"); + } + } + + $host = $args['host']; + if ($host) + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."remote_host='$host'"; + + $user = $args['user']; + if ($user) { + if ($user=='<NONE>') { + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."(remote_user IS NULL OR remote_user='' OR remote_user=' ' OR remote_user='-')"; + } else { + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."remote_user='$user'"; + } + } + + $referrer = $args['referrer']; + if ($referrer) { + if ($referrer=='<NONE>') { + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."(referer IS NULL OR referer='' OR referer=' ' OR referer='-')"; + } else { + $len = strlen($referrer); + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."left(referer,$len)<>'$referrer'"; } } if ($args['local_referrers']<>'true') { - if ($where_conditions<>'') - $where_conditions = $where_conditions.' AND '; $localhost = SERVER_URL; $len = strlen($localhost); - $where_conditions = $where_conditions."left(referer,$len)<>'$localhost'"; + $where_conditions = (!$where_conditions ? '' : $where_conditions.' AND ') + ."left(referer,$len)<>'$localhost'"; } - // The assumed contract is that there is a space at the end of the - // conditions string,so that following SQL clauses (such as GROUP BY) - // will not cause a syntax error - if ($where_conditions<>'') + // the assumed contract is that there is a space at the end of the condtions string, + // so that following SQL clauses (such as GROUP BY) will not cause a syntax error + // but we want a blank string if there are no where conditions. + if ($where_conditions) $where_conditions = $where_conditions.' '; return $where_conditions; @@ -252,10 +278,10 @@ function _getCaption(&$args) { $caption = $args['caption']; - if ($caption=='') - $caption = _($args['mode']); - if ($args['period']<>'' && $args['count']) - $caption = $caption." - ".$args['count']." "._($args['period']); + if (!$caption) + $caption = $args['queryName']; + if ($args['period'] && $args['count']) + $caption = $caption.' - '.$args['count'].' '._($args['period']); return $caption; } |
From: Charles C. <ch...@ru...> - 2005-02-04 16:22:22
|
Attached are my latest updates to the AnalyseAccessLog plugin. Major changes - split out the queries into lib/plugin/AnalyseAccessLog.inc - wrote the AnalyseActionLogPlugin wiki page - added a parameter to allow the output table to be centered (trying to right justify the table causes problems in both IE and Mozilla). I think that this is now pretty much done. The only enhancement that might be interesting is some facility to mark each query with the list of database engines that it is known to successfully run against. I would be delighted to add new queries against the access log, if anyone is willing to write... Random thoughts I thought about making it easier to write new queries on wiki pages but the security implications were horrendous. Much of the framework could easily be repurposed to write arbitrary queries against the database where the wiki data is held. Do we want to go that way? Regards, Charles |