Refactor Statsd classes to enable null collector to work.

The following changes are added:
- Created MediawikiStatsdDataFactory interface
- Added hasData() method to see if there are any data to send
- Added getData() method to fetch data
- Made service infrastructure use MediawikiStatsdDataFactory interface
- Made wfLogProfilingData() use MediawikiStatsdDataFactory interface
- Added capability to enable/disable buffering collector

Bug: T166354
Change-Id: I2874175647e987996a9a399829b3319674471aaa
This commit is contained in:
Stanislav Malyshev 2017-05-25 17:23:44 -07:00
parent 41438a38e2
commit 7fdc3d09a3
11 changed files with 104 additions and 13 deletions

View file

@ -960,6 +960,7 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Widget\\TitleInputWidget' => __DIR__ . '/includes/widget/TitleInputWidget.php',
'MediaWiki\\Widget\\UserInputWidget' => __DIR__ . '/includes/widget/UserInputWidget.php',
'MediaWiki\\Widget\\UsersMultiselectWidget' => __DIR__ . '/includes/widget/UsersMultiselectWidget.php',
'MediawikiStatsdDataFactory' => __DIR__ . '/includes/libs/stats/MediawikiStatsdDataFactory.php',
'MemCachedClientforWiki' => __DIR__ . '/includes/compat/MemcachedClientCompat.php',
'MemcLockManager' => __DIR__ . '/includes/libs/lockmanager/MemcLockManager.php',
'MemcachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/MemcachedBagOStuff.php',

View file

@ -1191,7 +1191,8 @@ function wfLogProfilingData() {
$profiler->logData();
$config = $context->getConfig();
if ( $config->get( 'StatsdServer' ) ) {
$stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
if ( $config->get( 'StatsdServer' ) && $stats->hasData() ) {
try {
$statsdServer = explode( ':', $config->get( 'StatsdServer' ) );
$statsdHost = $statsdServer[0];
@ -1199,9 +1200,7 @@ function wfLogProfilingData() {
$statsdSender = new SocketSender( $statsdHost, $statsdPort );
$statsdClient = new SamplingStatsdClient( $statsdSender, true, false );
$statsdClient->setSamplingRates( $config->get( 'StatsdSamplingRates' ) );
$statsdClient->send(
MediaWikiServices::getInstance()->getStatsdDataFactory()->getBuffer()
);
$statsdClient->send( $stats->getData() );
} catch ( Exception $ex ) {
MWExceptionHandler::logException( $ex );
}

View file

@ -9,9 +9,9 @@ use EventRelayerGroup;
use GenderCache;
use GlobalVarConfig;
use Hooks;
use MediawikiStatsdDataFactory;
use Wikimedia\Rdbms\LBFactory;
use LinkCache;
use Liuggio\StatsdClient\Factory\StatsdDataFactory;
use Wikimedia\Rdbms\LoadBalancer;
use MediaHandlerFactory;
use MediaWiki\Linker\LinkRenderer;
@ -446,7 +446,7 @@ class MediaWikiServices extends ServiceContainer {
/**
* @since 1.27
* @return StatsdDataFactory
* @return MediawikiStatsdDataFactory
*/
public function getStatsdDataFactory() {
return $this->getService( 'StatsdDataFactory' );

View file

@ -170,7 +170,7 @@ abstract class ContextSource implements IContextSource {
* @deprecated since 1.27 use a StatsdDataFactory from MediaWikiServices (preferably injected)
*
* @since 1.25
* @return StatsdDataFactory
* @return MediawikiStatsdDataFactory
*/
public function getStats() {
return MediaWikiServices::getInstance()->getStatsdDataFactory();

View file

@ -109,7 +109,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
*
* @deprecated since 1.27 use a StatsdDataFactory from MediaWikiServices (preferably injected)
*
* @return StatsdDataFactory
* @return MediawikiStatsdDataFactory
*/
public function getStats() {
return MediaWikiServices::getInstance()->getStatsdDataFactory();

View file

@ -131,7 +131,7 @@ interface IContextSource {
* @deprecated since 1.27 use a StatsdDataFactory from MediaWikiServices (preferably injected)
*
* @since 1.25
* @return StatsdDataFactory
* @return MediawikiStatsdDataFactory
*/
public function getStats();

View file

@ -138,7 +138,7 @@ class RequestContext implements IContextSource, MutableContext {
*
* @deprecated since 1.27 use a StatsdDataFactory from MediaWikiServices (preferably injected)
*
* @return StatsdDataFactory
* @return MediawikiStatsdDataFactory
*/
public function getStats() {
return MediaWikiServices::getInstance()->getStatsdDataFactory();

View file

@ -32,8 +32,17 @@ use Liuggio\StatsdClient\Factory\StatsdDataFactory;
*
* @since 1.25
*/
class BufferingStatsdDataFactory extends StatsdDataFactory {
class BufferingStatsdDataFactory extends StatsdDataFactory implements MediawikiStatsdDataFactory {
protected $buffer = [];
/**
* Collection enabled?
* @var bool
*/
protected $enabled = true;
/**
* @var string
*/
private $prefix;
public function __construct( $prefix ) {
parent::__construct();
@ -49,6 +58,7 @@ class BufferingStatsdDataFactory extends StatsdDataFactory {
*
* @param string $key
* @since 1.26
* @return string
*/
private static function normalizeMetricKey( $key ) {
$key = preg_replace( '/[:.]+/', '.', $key );
@ -61,6 +71,9 @@ class BufferingStatsdDataFactory extends StatsdDataFactory {
$key, $value = 1, $metric = StatsdDataInterface::STATSD_METRIC_COUNT
) {
$entity = $this->produceStatsdDataEntity();
if ( !$this->enabled ) {
return $entity;
}
if ( $key !== null ) {
$key = self::normalizeMetricKey( "{$this->prefix}.{$key}" );
$entity->setKey( $key );
@ -79,9 +92,35 @@ class BufferingStatsdDataFactory extends StatsdDataFactory {
}
/**
* @deprecated Use getData()
* @return StatsdData[]
*/
public function getBuffer() {
return $this->buffer;
}
/**
* Check whether this data factory has any data.
* @return boolean
*/
public function hasData() {
return !empty( $this->buffer );
}
/**
* Return data from the factory.
* @return StatsdData[]
*/
public function getData() {
return $this->buffer;
}
/**
* Set collection enable status.
* @param bool $enabled Will collection be enabled?
* @return void
*/
public function setEnabled( $enabled ) {
$this->enabled = $enabled;
}
}

View file

@ -0,0 +1,28 @@
<?php
use Liuggio\StatsdClient\Entity\StatsdData;
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
/**
* Mediawiki adaptation of Statsd data factory.
*/
interface MediawikiStatsdDataFactory extends StatsdDataFactoryInterface {
/**
* Check whether this data factory has any data.
* @return boolean
*/
public function hasData();
/**
* Return data from the factory.
* @return StatsdData[]
*/
public function getData();
/**
* Set collection enable status.
* @param bool $enabled Will collection be enabled?
* @return void
*/
public function setEnabled( $enabled );
}

View file

@ -8,7 +8,7 @@ use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
* @author Addshore
* @since 1.27
*/
class NullStatsdDataFactory implements StatsdDataFactoryInterface {
class NullStatsdDataFactory implements MediawikiStatsdDataFactory {
/**
* This function creates a 'timing' StatsdData.
@ -108,4 +108,28 @@ class NullStatsdDataFactory implements StatsdDataFactoryInterface {
return $data;
}
/**
* Check whether this data factory has any data.
* @return boolean
*/
public function hasData() {
return false;
}
/**
* Return data from the factory.
* @return StatsdData[]
*/
public function getData() {
return [];
}
/**
* Set collection enable status.
* @param bool $enabled Will collection be enabled?
* @return void
*/
public function setEnabled( $enabled ) {
// Nothing to do, null factory is always disabled.
}
}

View file

@ -303,7 +303,7 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
'MainConfig' => [ 'MainConfig', Config::class ],
'SiteStore' => [ 'SiteStore', SiteStore::class ],
'SiteLookup' => [ 'SiteLookup', SiteLookup::class ],
'StatsdDataFactory' => [ 'StatsdDataFactory', StatsdDataFactory::class ],
'StatsdDataFactory' => [ 'StatsdDataFactory', MediawikiStatsdDataFactory::class ],
'InterwikiLookup' => [ 'InterwikiLookup', InterwikiLookup::class ],
'EventRelayerGroup' => [ 'EventRelayerGroup', EventRelayerGroup::class ],
'SearchEngineFactory' => [ 'SearchEngineFactory', SearchEngineFactory::class ],