Skip to content

Commit d3833ab

Browse files
authored
Add full command to extras (#352)
1 parent ab8d1d0 commit d3833ab

File tree

7 files changed

+77
-1
lines changed

7 files changed

+77
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Add support for distributed tracing of SQL queries while using Doctrine DBAL (#426)
88
- Add support for distributed tracing when running a console command (#455)
99
- Add support for distributed tracing of cache pools (#)
10+
- Add `Full command` to extras for CLI commands, which includes command with all arguments
1011
- Deprecate the `Sentry\SentryBundle\EventListener\ConsoleCommandListener` class in favor of its parent class `Sentry\SentryBundle\EventListener\ConsoleListener` (#429)
1112
- Lower the required version of `symfony/psr-http-message-bridge` to allow installing it on a project that uses Symfony `3.4.x` components only (#480)
1213

src/EventListener/ConsoleListener.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Symfony\Component\Console\Event\ConsoleCommandEvent;
1010
use Symfony\Component\Console\Event\ConsoleErrorEvent;
1111
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
12+
use Symfony\Component\Console\Input\ArgvInput;
1213

1314
/**
1415
* This listener handles all errors thrown while running a console command and
@@ -49,10 +50,15 @@ public function handleConsoleCommandEvent(ConsoleCommandEvent $event): void
4950
{
5051
$scope = $this->hub->pushScope();
5152
$command = $event->getCommand();
53+
$input = $event->getInput();
5254

5355
if (null !== $command && null !== $command->getName()) {
5456
$scope->setTag('console.command', $command->getName());
5557
}
58+
59+
if ($input instanceof ArgvInput) {
60+
$scope->setExtra('Full command', (string) $input);
61+
}
5662
}
5763

5864
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\Tests\End2End\App\Command;
6+
7+
use Symfony\Component\Console\Command\Command;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Input\InputOption;
10+
use Symfony\Component\Console\Output\OutputInterface;
11+
12+
class MainCommand extends Command
13+
{
14+
protected function configure()
15+
{
16+
$this
17+
->addOption('option1', null, InputOption::VALUE_NONE)
18+
->addOption('option2', 'o2', InputOption::VALUE_OPTIONAL)
19+
->addArgument('id')
20+
;
21+
}
22+
23+
protected function execute(InputInterface $input, OutputInterface $output): int
24+
{
25+
throw new \RuntimeException('This is an intentional error');
26+
}
27+
}

tests/End2End/App/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ services:
2323
tags:
2424
- controller.service_arguments
2525

26+
Sentry\SentryBundle\Tests\End2End\App\Command\MainCommand:
27+
tags: [{ name: 'console.command', command: 'main-command' }]
28+
2629
monolog:
2730
handlers:
2831
main:

tests/End2End/End2EndTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Symfony\Bundle\FrameworkBundle\Console\Application;
1111
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
1212
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
13+
use Symfony\Component\Console\Input\ArgvInput;
14+
use Symfony\Component\Console\Output\NullOutput;
1315
use Symfony\Component\Console\Tester\CommandTester;
1416
use Symfony\Component\HttpFoundation\Response;
1517
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -171,6 +173,25 @@ public function testNotice(): void
171173
$this->assertEventCount(1);
172174
}
173175

176+
public function testCommand(): void
177+
{
178+
self::bootKernel();
179+
$application = new Application(self::$kernel);
180+
181+
try {
182+
$application->doRun(new ArgvInput(['bin/console', 'main-command', '--option1', '--option2=foo', 'bar']), new NullOutput());
183+
} catch (\RuntimeException $e) {
184+
$this->assertSame('This is an intentional error', $e->getMessage());
185+
}
186+
187+
$this->assertEventCount(1);
188+
$this->assertCount(1, StubTransportFactory::$events);
189+
$this->assertSame(
190+
['Full command' => 'main-command --option1 --option2=foo bar'],
191+
StubTransportFactory::$events[0]->getExtra()
192+
);
193+
}
194+
174195
public function testMessengerCaptureHardFailure(): void
175196
{
176197
$this->skipIfMessengerIsMissing();

tests/End2End/StubTransportFactory.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ class StubTransportFactory implements TransportFactoryInterface
1717
{
1818
public const SEPARATOR = '###';
1919

20+
/**
21+
* @var Event[]
22+
*/
23+
public static $events = [];
24+
2025
public function create(Options $options): TransportInterface
2126
{
2227
return new class() implements TransportInterface {
2328
public function send(Event $event): PromiseInterface
2429
{
30+
StubTransportFactory::$events[] = $event;
2531
touch(End2EndTest::SENT_EVENTS_LOG);
2632

2733
if ($event->getMessage()) {

tests/EventListener/AbstractConsoleListenerTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Console\Event\ConsoleCommandEvent;
1515
use Symfony\Component\Console\Event\ConsoleErrorEvent;
1616
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
17+
use Symfony\Component\Console\Input\ArgvInput;
1718
use Symfony\Component\Console\Input\InputInterface;
1819
use Symfony\Component\Console\Output\OutputInterface;
1920

@@ -33,8 +34,9 @@ protected function setUp(): void
3334
* @dataProvider handleConsoleCommmandEventDataProvider
3435
*
3536
* @param array<string, string> $expectedTags
37+
* @param array<string, string> $expectedExtra
3638
*/
37-
public function testHandleConsoleCommandEvent(ConsoleCommandEvent $consoleEvent, array $expectedTags): void
39+
public function testHandleConsoleCommandEvent(ConsoleCommandEvent $consoleEvent, array $expectedTags, array $expectedExtra): void
3840
{
3941
$listenerClass = static::getListenerClass();
4042
$scope = new Scope();
@@ -49,6 +51,7 @@ public function testHandleConsoleCommandEvent(ConsoleCommandEvent $consoleEvent,
4951
$event = $scope->applyToEvent(Event::createEvent());
5052

5153
$this->assertSame($expectedTags, $event->getTags());
54+
$this->assertSame($expectedExtra, $event->getExtra());
5255
}
5356

5457
/**
@@ -59,16 +62,25 @@ public function handleConsoleCommmandEventDataProvider(): \Generator
5962
yield [
6063
new ConsoleCommandEvent(null, $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)),
6164
[],
65+
[],
6266
];
6367

6468
yield [
6569
new ConsoleCommandEvent(new Command(), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)),
6670
[],
71+
[],
6772
];
6873

6974
yield [
7075
new ConsoleCommandEvent(new Command('foo:bar'), $this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)),
7176
['console.command' => 'foo:bar'],
77+
[],
78+
];
79+
80+
yield [
81+
new ConsoleCommandEvent(new Command('foo:bar'), new ArgvInput(['bin/console', 'foo:bar', '--foo=bar']), $this->createMock(OutputInterface::class)),
82+
['console.command' => 'foo:bar'],
83+
['Full command' => "'foo:bar' --foo=bar"],
7284
];
7385
}
7486

0 commit comments

Comments
 (0)