Index: trunk/extensions/AbuseFilter/Views/AbuseFilterViewEdit.php |
— | — | @@ -174,6 +174,8 @@ |
175 | 175 | global $wgMemc; |
176 | 176 | $wgMemc->delete( wfMemcKey( 'valid-tags' ) ); |
177 | 177 | } |
| 178 | + |
| 179 | + AbuseFilter::resetFilterProfile( $new_id ); |
178 | 180 | |
179 | 181 | global $wgOut; |
180 | 182 | |
— | — | @@ -257,11 +259,13 @@ |
258 | 260 | |
259 | 261 | if ($total > 0) { |
260 | 262 | $matches_percent = sprintf( '%.2f', 100 * $matches_count / $total ); |
| 263 | + $profile = AbuseFilter::getFilterProfile( $filter ); |
261 | 264 | $fields['abusefilter-edit-status-label'] = |
262 | 265 | wfMsgExt( 'abusefilter-edit-status', array( 'parsemag', 'escape' ), |
263 | 266 | $wgLang->formatNum($total), |
264 | 267 | $wgLang->formatNum($matches_count), |
265 | | - $wgLang->formatNum($matches_percent) |
| 268 | + $wgLang->formatNum($matches_percent), |
| 269 | + $wgLang->formatNum($profile) |
266 | 270 | ); |
267 | 271 | } |
268 | 272 | } |
Index: trunk/extensions/AbuseFilter/AbuseFilter.class.php |
— | — | @@ -361,10 +361,16 @@ |
362 | 362 | wfProfileIn( __METHOD__ ); |
363 | 363 | $dbr = wfGetDB( DB_SLAVE ); |
364 | 364 | $res = $dbr->select( 'abuse_filter', '*', array( 'af_enabled' => 1, 'af_deleted' => 0 ) ); |
| 365 | + |
| 366 | + // Sampling profiler |
| 367 | + $profile = rand(0,50); |
| 368 | + $profile = ($profile == 1) ? true : false; |
365 | 369 | |
366 | 370 | $filter_matched = array(); |
367 | 371 | |
368 | 372 | while ( $row = $dbr->fetchObject( $res ) ) { |
| 373 | + if ($profile) |
| 374 | + $startTime = microtime(true); |
369 | 375 | // Store the row somewhere convenient |
370 | 376 | self::$filters[$row->af_id] = $row; |
371 | 377 | |
— | — | @@ -377,6 +383,14 @@ |
378 | 384 | // Record non-match. |
379 | 385 | $filter_matched[$row->af_id] = false; |
380 | 386 | } |
| 387 | + |
| 388 | + if ($profile) { |
| 389 | + $endTime = microtime(true); |
| 390 | + |
| 391 | + $timeTaken = $endTime - $startTime; |
| 392 | + |
| 393 | + self::recordProfilingResult( $row->af_id, $timeTaken ); |
| 394 | + } |
381 | 395 | } |
382 | 396 | |
383 | 397 | // Update statistics, and disable filters which are over-blocking. |
— | — | @@ -386,6 +400,48 @@ |
387 | 401 | |
388 | 402 | return $filter_matched; |
389 | 403 | } |
| 404 | + |
| 405 | + public static function resetFilterProfile( $filter ) { |
| 406 | + global $wgMemc; |
| 407 | + $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); |
| 408 | + $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); |
| 409 | + |
| 410 | + $wgMemc->delete( $countKey ); |
| 411 | + $wgMemc->delete( $totalKey ); |
| 412 | + } |
| 413 | + |
| 414 | + public static function recordProfilingResult( $filter, $time ) { |
| 415 | + global $wgMemc; |
| 416 | + |
| 417 | + $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); |
| 418 | + $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); |
| 419 | + |
| 420 | + $curCount = $wgMemc->get( $countKey ); |
| 421 | + $curTotal = $wgMemc->get( $totalKey ); |
| 422 | + |
| 423 | + $wgMemc->set( $totalKey, $curTotal + $time, 3600 ); |
| 424 | + |
| 425 | + if ($curCount) |
| 426 | + $wgMemc->incr( $countKey ); |
| 427 | + else |
| 428 | + $wgMemc->set( $countKey, 1, 3600 ); |
| 429 | + } |
| 430 | + |
| 431 | + public static function getFilterProfile( $filter ) { |
| 432 | + global $wgMemc; |
| 433 | + |
| 434 | + $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); |
| 435 | + $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); |
| 436 | + |
| 437 | + $curCount = $wgMemc->get( $countKey ); |
| 438 | + $curTotal = $wgMemc->get( $totalKey ); |
| 439 | + |
| 440 | + if (!$curCount) |
| 441 | + return 0; |
| 442 | + |
| 443 | + $profile = ($curTotal / $curCount) * 1000; |
| 444 | + return round( $profile, 2); // Return in ms, rounded to 2dp |
| 445 | + } |
390 | 446 | |
391 | 447 | /** Returns an array [ list of actions taken by filter, error message to display, if any ] */ |
392 | 448 | public static function executeFilterActions( $filters, $title, $vars ) { |
Index: trunk/extensions/AbuseFilter/AbuseFilter.i18n.php |
— | — | @@ -151,7 +151,8 @@ |
152 | 152 | If you save your changes, you will overwrite all changes since the revision you are editing.</strong> • |
153 | 153 | [[Special:AbuseFilter/history/$2|Return to this filter's history]].", |
154 | 154 | 'abusefilter-edit-status-label' => 'Statistics:', |
155 | | - 'abusefilter-edit-status' => 'Of the last $1 {{PLURAL:$1|action|actions}}, this filter has matched $2 ($3%).', |
| 155 | + 'abusefilter-edit-status' => 'Of the last $1 {{PLURAL:$1|action|actions}}, this filter has matched $2 ($3%). |
| 156 | +On average, its run time is $4ms', |
156 | 157 | 'abusefilter-edit-throttled' => "'''Warning''': This filter was automatically disabled as a safety measure. |
157 | 158 | It reached the limit of matching more than $1% of actions.", |
158 | 159 | 'abusefilter-edit-new' => 'New filter', |