Add runtime metrics to statsd

Metrics per edit:
    - Execution time of all filters
    - Number of filters executed
    - Number of conditions executed

Due to the current structure of abuse filter there was not
a clean way to include filter actions and abuselog creation
as part of the runtime metrics.

Bug: T161059
Change-Id: I6208b620453863133c6623aa419775f63c7d3eb1
This commit is contained in:
Dayllan Maza 2017-08-24 10:52:49 -04:00
parent 1e5a5539b2
commit c07294cc9c
3 changed files with 49 additions and 4 deletions

View file

@ -117,3 +117,8 @@ $wgAbuseFilterLogIPMaxAge = 3 * 30 * 24 * 3600; // 3 months
* Whether to record the average time taken and average number of conditions used by each filter.
*/
$wgAbuseFilterProfile = false;
/**
* Whether to record runtime metrics for all filters combined.
*/
$wgAbuseFilterRuntimeProfile = false;

View file

@ -248,7 +248,8 @@
"_merge_strategy": "array_plus"
},
"AbuseFilterLogIPMaxAge": 7776000,
"AbuseFilterProfile": false
"AbuseFilterProfile": false,
"AbuseFilterRuntimeProfile": false
},
"load_composer_autoloader": true,
"manifest_version": 1

View file

@ -878,7 +878,7 @@ class AbuseFilter {
public static function filterAction(
$vars, $title, $group = 'default', $user = null, $mode = 'execute'
) {
global $wgUser, $wgTitle, $wgRequest;
global $wgUser, $wgTitle, $wgRequest, $wgAbuseFilterRuntimeProfile;
$context = RequestContext::getMain();
$oldContextTitle = $context->getTitle();
@ -906,6 +906,10 @@ class AbuseFilter {
$stashKey = self::getStashKey( $cache, $vars, $group );
$isForEdit = ( $vars->getVar( 'action' )->toString() === 'edit' );
if ( $wgAbuseFilterRuntimeProfile ) {
$startTime = microtime( true );
}
$filter_matched = false;
if ( $mode === 'execute' && $isForEdit ) {
// Check the filter edit stash results first
@ -933,6 +937,13 @@ class AbuseFilter {
if ( $mode === 'stash' ) {
// Save the filter stash result and do nothing further
$cacheData = [ 'matches' => $filter_matched, 'tags' => self::$tagsToSet ];
// Add runtime metrics in cache for later use
if ( $wgAbuseFilterRuntimeProfile ) {
$cacheData['condCount'] = self::$condCount;
$cacheData['runtime'] = ( microtime( true ) - $startTime ) * 1000;
}
$cache->set( $stashKey, $cacheData, $cache::TTL_MINUTE );
$logger->debug( __METHOD__ . ": cache store for '$title' (key $stashKey)." );
$statsd->increment( 'abusefilter.check-stash.store' );
@ -942,13 +953,24 @@ class AbuseFilter {
$matched_filters = array_keys( array_filter( $filter_matched ) );
// Save runtime metrics only on edits
if ( $wgAbuseFilterRuntimeProfile && $mode === 'execute' && $isForEdit ) {
if ( $cacheData ) {
$runtime = $cacheData['runtime'];
$condCount = $cacheData['condCount'];
} else {
$runtime = ( microtime( true ) - $startTime ) * 1000;
$condCount = self::$condCount;
}
self::recordRuntimeProfilingResult( count( $matched_filters ), $condCount, $runtime );
}
if ( count( $matched_filters ) == 0 ) {
$status = Status::newGood();
} else {
$status = self::executeFilterActions( $matched_filters, $title, $vars );
$actions_taken = $status->getValue();
$action = $vars->getVar( 'ACTION' )->toString();
// If $wgUser isn't safe to load (e.g. a failure during
@ -980,6 +1002,7 @@ class AbuseFilter {
if ( $wgTitle !== $oldWgTitle ) {
$wgTitle = $oldWgTitle;
}
if ( $context->getTitle() !== $oldContextTitle && $oldContextTitle instanceof Title ) {
$context->setTitle( $oldContextTitle );
}
@ -1745,6 +1768,22 @@ class AbuseFilter {
}
}
/**
* Record runtime profiling data
*
* @param int $totalFilters
* @param int $totalConditions
* @param float $runtime
*/
private static function recordRuntimeProfilingResult( $totalFilters, $totalConditions, $runtime ) {
$keyPrefix = 'abusefilter.runtime-profile.' . wfWikiID() . '.';
$statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
$statsd->timing( $keyPrefix . 'runtime', $runtime );
$statsd->timing( $keyPrefix . 'total_filters', $totalFilters );
$statsd->timing( $keyPrefix . 'total_conditions', $totalConditions );
}
/**
* @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups)
* @param string[] $filters