Skip to content

Commit

Permalink
Filtering first set of Scoutapm-namespaced calls out of stack trace
Browse files Browse the repository at this point in the history
  • Loading branch information
asgrim committed Oct 2, 2019
1 parent fa0bbd0 commit e259138
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 12 deletions.
5 changes: 1 addition & 4 deletions src/Events/Request/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Scoutapm\Events\Tag\TagRequest;
use Scoutapm\Helper\Backtrace;
use Scoutapm\Helper\Timer;
use function array_slice;

/** @internal */
class Request implements CommandWithChildren
Expand Down Expand Up @@ -78,9 +77,7 @@ public function stopSpan(?float $overrideTimestamp = null) : void
$command->stop($overrideTimestamp);

if ($command->duration() > self::STACK_TRACE_THRESHOLD_SECONDS) {
$stack = Backtrace::capture();
$stack = array_slice($stack, 4);
$command->tag('stack', $stack);
$command->tag('stack', Backtrace::capture());
}

$this->currentCommand = $command->parent();
Expand Down
80 changes: 72 additions & 8 deletions src/Helper/Backtrace.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,93 @@

namespace Scoutapm\Helper;

use const DEBUG_BACKTRACE_IGNORE_ARGS;
use function array_filter;
use function array_key_exists;
use function array_slice;
use function debug_backtrace;
use function strpos;

/** @internal */
final class Backtrace
{
/** @return array<int, array<string, string>> */
/**
* @return array<int, array<string, string|int>>
*
* @psalm-return array<int, array{file: string, line: int, function: string}>
*/
public static function capture() : array
{
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$capturedStack = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 1);

$formatted_stack = [];
foreach ($stack as $frame) {
if (!isset($frame['file'], $frame['line'], $frame['function'])) {
$formattedStack = [];
foreach ($capturedStack as $frame) {
if (! isset($frame['file'], $frame['line'], $frame['function'])) {
continue;
}

$formatted_stack[] = [
/** @psalm-var array{file: string, line: int, function: string, class: string, type: string} $frame */
$formattedStack[] = [
'file' => $frame['file'],
'line' => $frame['line'],
'function' => $frame['function'],
'function' => self::formatFunctionNameFromFrame($frame),
];
}

return $formatted_stack;
return self::filterScoutRelatedFramesFromTopOfStack($formattedStack);
}

/**
* @param array<string, string|int> $frame
*
* @psalm-param array{file: string, line: int, function: string, class: string, type: string} $frame
*/
private static function formatFunctionNameFromFrame(array $frame) : string
{
if (! array_key_exists('class', $frame) || ! array_key_exists('type', $frame)) {
return $frame['function'];
}

return $frame['class'] . $frame['type'] . $frame['function'];
}

/**
* @param array<string, string|int> $frame
*
* @psalm-param array{file: string, line: int, function: string} $frame
*/
private static function isScoutRelated(array $frame) : bool
{
return strpos($frame['function'], 'Scoutapm') === 0;
}

/**
* @param array<int, array<string, string|int>> $formattedStack
*
* @return array<int, array<string, string|int>>
*
* @psalm-param array<int, array{file: string, line: int, function: string}> $formattedStack
* @psalm-return array<int, array{file: string, line: int, function: string}>
*/
private static function filterScoutRelatedFramesFromTopOfStack(array $formattedStack) : array
{
$stillInsideScout = true;

return array_filter(
$formattedStack,
static function (array $frame) use (&$stillInsideScout) : bool {
if (! $stillInsideScout) {
return true;
}

if (self::isScoutRelated($frame)) {
return false;
}

$stillInsideScout = false;

return true;
}
);
}
}
1 change: 1 addition & 0 deletions tests/Unit/Helper/BacktraceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PHPUnit\Framework\TestCase;
use Scoutapm\Helper\Backtrace;
use function array_keys;

/** @covers \Scoutapm\Helper\Backtrace */
final class BacktraceTest extends TestCase
Expand Down

0 comments on commit e259138

Please sign in to comment.