mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
Support sampling subprocess execution in Multimeter
Summary: Ref T6930. Add subprocess sampling/labeling. Test Plan: (This table includes some buggy test labels.) {F391655} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6930 Differential Revision: https://secure.phabricator.com/D12675
This commit is contained in:
parent
e6e0df6aff
commit
bee4dc7d53
2 changed files with 90 additions and 1 deletions
|
@ -91,6 +91,8 @@ final class MultimeterControl {
|
||||||
throw new Exception(pht('Call setSampleRate() before saving events!'));
|
throw new Exception(pht('Call setSampleRate() before saving events!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->addServiceEvents();
|
||||||
|
|
||||||
// Don't sample any of this stuff.
|
// Don't sample any of this stuff.
|
||||||
$this->pauseMultimeter();
|
$this->pauseMultimeter();
|
||||||
|
|
||||||
|
@ -191,7 +193,7 @@ final class MultimeterControl {
|
||||||
if (isset($map[$name])) {
|
if (isset($map[$name])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$need[] = $name;
|
$need[$name] = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($need as $name) {
|
foreach ($need as $name) {
|
||||||
|
@ -204,4 +206,87 @@ final class MultimeterControl {
|
||||||
return $map;
|
return $map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addServiceEvents() {
|
||||||
|
$events = PhutilServiceProfiler::getInstance()->getServiceCallLog();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$type = idx($event, 'type');
|
||||||
|
switch ($type) {
|
||||||
|
case 'exec':
|
||||||
|
$this->newEvent(
|
||||||
|
MultimeterEvent::TYPE_EXEC_TIME,
|
||||||
|
$label = $this->getLabelForCommandEvent($event['command']),
|
||||||
|
(1000000 * $event['duration']));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLabelForCommandEvent($command) {
|
||||||
|
$argv = preg_split('/\s+/', $command);
|
||||||
|
|
||||||
|
$bin = array_shift($argv);
|
||||||
|
$bin = basename($bin);
|
||||||
|
$bin = trim($bin, '"\'');
|
||||||
|
|
||||||
|
// It's important to avoid leaking details about command parameters,
|
||||||
|
// because some may be sensitive. Given this, it's not trivial to
|
||||||
|
// determine which parts of a command are arguments and which parts are
|
||||||
|
// flags.
|
||||||
|
|
||||||
|
// Rather than try too hard for now, just whitelist some workflows that we
|
||||||
|
// know about and record everything else generically. Overall, this will
|
||||||
|
// produce labels like "pygmentize" or "git log", discarding all flags and
|
||||||
|
// arguments.
|
||||||
|
|
||||||
|
$workflows = array(
|
||||||
|
'git' => array(
|
||||||
|
'log' => true,
|
||||||
|
'for-each-ref' => true,
|
||||||
|
'pull' => true,
|
||||||
|
'clone' => true,
|
||||||
|
'fetch' => true,
|
||||||
|
'cat-file' => true,
|
||||||
|
'init' => true,
|
||||||
|
'config' => true,
|
||||||
|
'remote' => true,
|
||||||
|
'rev-parse' => true,
|
||||||
|
'diff' => true,
|
||||||
|
'ls-tree' => true,
|
||||||
|
),
|
||||||
|
'svn' => array(
|
||||||
|
'log' => true,
|
||||||
|
'diff' => true,
|
||||||
|
),
|
||||||
|
'hg' => array(
|
||||||
|
'log' => true,
|
||||||
|
'locate' => true,
|
||||||
|
'pull' => true,
|
||||||
|
'clone' => true,
|
||||||
|
'init' => true,
|
||||||
|
'diff' => true,
|
||||||
|
'cat' => true,
|
||||||
|
),
|
||||||
|
'svnadmin' => array(
|
||||||
|
'create' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$workflow = null;
|
||||||
|
$candidates = idx($workflows, $bin);
|
||||||
|
if ($candidates) {
|
||||||
|
foreach ($argv as $arg) {
|
||||||
|
if (isset($candidates[$arg])) {
|
||||||
|
$workflow = $arg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($workflow) {
|
||||||
|
return 'bin.'.$bin.' '.$workflow;
|
||||||
|
} else {
|
||||||
|
return 'bin.'.$bin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class MultimeterEvent extends MultimeterDAO {
|
||||||
|
|
||||||
const TYPE_STATIC_RESOURCE = 0;
|
const TYPE_STATIC_RESOURCE = 0;
|
||||||
const TYPE_REQUEST_TIME = 1;
|
const TYPE_REQUEST_TIME = 1;
|
||||||
|
const TYPE_EXEC_TIME = 2;
|
||||||
|
|
||||||
protected $eventType;
|
protected $eventType;
|
||||||
protected $eventLabelID;
|
protected $eventLabelID;
|
||||||
|
@ -32,6 +33,8 @@ final class MultimeterEvent extends MultimeterDAO {
|
||||||
return pht('Static Resource');
|
return pht('Static Resource');
|
||||||
case self::TYPE_REQUEST_TIME:
|
case self::TYPE_REQUEST_TIME:
|
||||||
return pht('Web Request');
|
return pht('Web Request');
|
||||||
|
case self::TYPE_EXEC_TIME:
|
||||||
|
return pht('Subprocesses');
|
||||||
}
|
}
|
||||||
|
|
||||||
return pht('Unknown ("%s")', $type);
|
return pht('Unknown ("%s")', $type);
|
||||||
|
@ -46,6 +49,7 @@ final class MultimeterEvent extends MultimeterDAO {
|
||||||
case self::TYPE_STATIC_RESOURCE:
|
case self::TYPE_STATIC_RESOURCE:
|
||||||
return pht('%s Req', new PhutilNumber($cost));
|
return pht('%s Req', new PhutilNumber($cost));
|
||||||
case self::TYPE_REQUEST_TIME:
|
case self::TYPE_REQUEST_TIME:
|
||||||
|
case self::TYPE_EXEC_TIME:
|
||||||
return pht('%s us', new PhutilNumber($cost));
|
return pht('%s us', new PhutilNumber($cost));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue