@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+90 -1
+86 -1
src/applications/multimeter/data/MultimeterControl.php
··· 91 91 throw new Exception(pht('Call setSampleRate() before saving events!')); 92 92 } 93 93 94 + $this->addServiceEvents(); 95 + 94 96 // Don't sample any of this stuff. 95 97 $this->pauseMultimeter(); 96 98 ··· 191 193 if (isset($map[$name])) { 192 194 continue; 193 195 } 194 - $need[] = $name; 196 + $need[$name] = $name; 195 197 } 196 198 197 199 foreach ($need as $name) { ··· 202 204 } 203 205 204 206 return $map; 207 + } 208 + 209 + private function addServiceEvents() { 210 + $events = PhutilServiceProfiler::getInstance()->getServiceCallLog(); 211 + foreach ($events as $event) { 212 + $type = idx($event, 'type'); 213 + switch ($type) { 214 + case 'exec': 215 + $this->newEvent( 216 + MultimeterEvent::TYPE_EXEC_TIME, 217 + $label = $this->getLabelForCommandEvent($event['command']), 218 + (1000000 * $event['duration'])); 219 + break; 220 + } 221 + } 222 + } 223 + 224 + private function getLabelForCommandEvent($command) { 225 + $argv = preg_split('/\s+/', $command); 226 + 227 + $bin = array_shift($argv); 228 + $bin = basename($bin); 229 + $bin = trim($bin, '"\''); 230 + 231 + // It's important to avoid leaking details about command parameters, 232 + // because some may be sensitive. Given this, it's not trivial to 233 + // determine which parts of a command are arguments and which parts are 234 + // flags. 235 + 236 + // Rather than try too hard for now, just whitelist some workflows that we 237 + // know about and record everything else generically. Overall, this will 238 + // produce labels like "pygmentize" or "git log", discarding all flags and 239 + // arguments. 240 + 241 + $workflows = array( 242 + 'git' => array( 243 + 'log' => true, 244 + 'for-each-ref' => true, 245 + 'pull' => true, 246 + 'clone' => true, 247 + 'fetch' => true, 248 + 'cat-file' => true, 249 + 'init' => true, 250 + 'config' => true, 251 + 'remote' => true, 252 + 'rev-parse' => true, 253 + 'diff' => true, 254 + 'ls-tree' => true, 255 + ), 256 + 'svn' => array( 257 + 'log' => true, 258 + 'diff' => true, 259 + ), 260 + 'hg' => array( 261 + 'log' => true, 262 + 'locate' => true, 263 + 'pull' => true, 264 + 'clone' => true, 265 + 'init' => true, 266 + 'diff' => true, 267 + 'cat' => true, 268 + ), 269 + 'svnadmin' => array( 270 + 'create' => true, 271 + ), 272 + ); 273 + 274 + $workflow = null; 275 + $candidates = idx($workflows, $bin); 276 + if ($candidates) { 277 + foreach ($argv as $arg) { 278 + if (isset($candidates[$arg])) { 279 + $workflow = $arg; 280 + break; 281 + } 282 + } 283 + } 284 + 285 + if ($workflow) { 286 + return 'bin.'.$bin.' '.$workflow; 287 + } else { 288 + return 'bin.'.$bin; 289 + } 205 290 } 206 291 207 292 }
+4
src/applications/multimeter/storage/MultimeterEvent.php
··· 4 4 5 5 const TYPE_STATIC_RESOURCE = 0; 6 6 const TYPE_REQUEST_TIME = 1; 7 + const TYPE_EXEC_TIME = 2; 7 8 8 9 protected $eventType; 9 10 protected $eventLabelID; ··· 32 33 return pht('Static Resource'); 33 34 case self::TYPE_REQUEST_TIME: 34 35 return pht('Web Request'); 36 + case self::TYPE_EXEC_TIME: 37 + return pht('Subprocesses'); 35 38 } 36 39 37 40 return pht('Unknown ("%s")', $type); ··· 46 49 case self::TYPE_STATIC_RESOURCE: 47 50 return pht('%s Req', new PhutilNumber($cost)); 48 51 case self::TYPE_REQUEST_TIME: 52 + case self::TYPE_EXEC_TIME: 49 53 return pht('%s us', new PhutilNumber($cost)); 50 54 } 51 55