Merge "rdbms: add statsd metrics to TransactionProfiler"
This commit is contained in:
commit
c02baea1d6
4 changed files with 52 additions and 9 deletions
|
|
@ -874,6 +874,9 @@ class MediaWiki {
|
|||
$trxLimits = $this->config->get( MainConfigNames::TrxProfilerLimits );
|
||||
$trxProfiler = Profiler::instance()->getTransactionProfiler();
|
||||
$trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
|
||||
$statsFactory = MediaWikiServices::getInstance()->getStatsdDataFactory();
|
||||
$trxProfiler->setStatsdDataFactory( $statsFactory );
|
||||
$trxProfiler->setRequestMethod( $request->getMethod() );
|
||||
if ( $request->hasSafeMethod() ) {
|
||||
$trxProfiler->setExpectations( $trxLimits['GET'], __METHOD__ );
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1917,16 +1917,21 @@ class ApiMain extends ApiBase {
|
|||
* @param ApiBase $module
|
||||
*/
|
||||
protected function setRequestExpectations( ApiBase $module ) {
|
||||
$limits = $this->getConfig()->get( MainConfigNames::TrxProfilerLimits );
|
||||
$request = $this->getRequest();
|
||||
|
||||
$trxLimits = $this->getConfig()->get( MainConfigNames::TrxProfilerLimits );
|
||||
$trxProfiler = Profiler::instance()->getTransactionProfiler();
|
||||
$trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
|
||||
if ( $this->getRequest()->hasSafeMethod() ) {
|
||||
$trxProfiler->setExpectations( $limits['GET'], __METHOD__ );
|
||||
} elseif ( $this->getRequest()->wasPosted() && !$module->isWriteMode() ) {
|
||||
$trxProfiler->setExpectations( $limits['POST-nonwrite'], __METHOD__ );
|
||||
$this->getRequest()->markAsSafeRequest();
|
||||
$statsFactory = MediaWikiServices::getInstance()->getStatsdDataFactory();
|
||||
$trxProfiler->setStatsdDataFactory( $statsFactory );
|
||||
$trxProfiler->setRequestMethod( $request->getMethod() );
|
||||
if ( $request->hasSafeMethod() ) {
|
||||
$trxProfiler->setExpectations( $trxLimits['GET'], __METHOD__ );
|
||||
} elseif ( $request->wasPosted() && !$module->isWriteMode() ) {
|
||||
$trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
|
||||
$request->markAsSafeRequest();
|
||||
} else {
|
||||
$trxProfiler->setExpectations( $limits['POST'], __METHOD__ );
|
||||
$trxProfiler->setExpectations( $trxLimits['POST'], __METHOD__ );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@
|
|||
*/
|
||||
namespace Wikimedia\Rdbms;
|
||||
|
||||
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
|
||||
use NullStatsdDataFactory;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use RuntimeException;
|
||||
use StatsdAwareInterface;
|
||||
use Wikimedia\ScopedCallback;
|
||||
|
||||
/**
|
||||
|
|
@ -35,13 +38,17 @@ use Wikimedia\ScopedCallback;
|
|||
* @ingroup Profiler
|
||||
* @ingroup Database
|
||||
*/
|
||||
class TransactionProfiler implements LoggerAwareInterface {
|
||||
class TransactionProfiler implements LoggerAwareInterface, StatsdAwareInterface {
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
/** @var StatsdDataFactoryInterface */
|
||||
private $stats;
|
||||
/** @var array<string,array> Map of (event name => map of FLD_* class constants) */
|
||||
private $expect;
|
||||
/** @var array<string,int> Map of (event name => current hits) */
|
||||
private $hits;
|
||||
/** @var array<string,int> Map of (event name => violation counter) */
|
||||
private $violations;
|
||||
/** @var array<string,int> Map of (event name => silence counter) */
|
||||
private $silenced;
|
||||
|
||||
|
|
@ -57,6 +64,9 @@ class TransactionProfiler implements LoggerAwareInterface {
|
|||
*/
|
||||
private $dbTrxMethodTimes;
|
||||
|
||||
/** @var string|null HTTP request method; null for CLI mode */
|
||||
private $method;
|
||||
|
||||
/** @var float|null */
|
||||
private $wallClockOverride;
|
||||
|
||||
|
|
@ -104,12 +114,25 @@ class TransactionProfiler implements LoggerAwareInterface {
|
|||
$this->silenced = array_fill_keys( self::EVENT_NAMES, 0 );
|
||||
|
||||
$this->setLogger( new NullLogger() );
|
||||
$this->setStatsdDataFactory( new NullStatsdDataFactory() );
|
||||
}
|
||||
|
||||
public function setLogger( LoggerInterface $logger ) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function setStatsdDataFactory( StatsdDataFactoryInterface $statsFactory ) {
|
||||
$this->stats = $statsFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?string $method HTTP method; null for CLI mode
|
||||
* @return void
|
||||
*/
|
||||
public function setRequestMethod( ?string $method ) {
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return bool Old value
|
||||
|
|
@ -447,6 +470,7 @@ class TransactionProfiler implements LoggerAwareInterface {
|
|||
);
|
||||
|
||||
$this->hits = array_fill_keys( self::COUNTER_EVENT_NAMES, 0 );
|
||||
$this->violations = array_fill_keys( self::EVENT_NAMES, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -491,13 +515,21 @@ class TransactionProfiler implements LoggerAwareInterface {
|
|||
?string $trxId = null,
|
||||
?string $serverName = null
|
||||
) {
|
||||
$violations = ++$this->violations[$event];
|
||||
// First violation; check if this is a web request
|
||||
if ( $violations === 1 && $this->method !== null ) {
|
||||
$this->stats->increment( "rdbms_trxprofiler_warnings.$event.{$this->method}" );
|
||||
}
|
||||
|
||||
$max = $this->expect[$event][self::FLD_LIMIT];
|
||||
$by = $this->expect[$event][self::FLD_FNAME];
|
||||
|
||||
$message = "Expectation ($event <= $max) by $by not met (actual: {actualSeconds})";
|
||||
if ( $trxId ) {
|
||||
$message .= ' in trx #{trxId}';
|
||||
}
|
||||
$message .= ":\n{query}\n";
|
||||
|
||||
$this->logger->warning(
|
||||
$message,
|
||||
[
|
||||
|
|
|
|||
|
|
@ -211,7 +211,10 @@ abstract class Profiler {
|
|||
}
|
||||
|
||||
/**
|
||||
* Log the data to the backing store for all ProfilerOutput instances that have one
|
||||
* Log data to all the applicable backing stores
|
||||
*
|
||||
* This logs the profiling data to the backing store for each configured ProfilerOutput
|
||||
* instance. It also logs any request data for the TransactionProfiler instance.
|
||||
*
|
||||
* @since 1.25
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue