From 1cb0ed76b6c45759919be41973bfd9ab49eac9ea Mon Sep 17 00:00:00 2001 From: Fabio Capucci Date: Wed, 14 Feb 2024 14:33:01 +0100 Subject: [PATCH] test failing job tracing --- src/Instrumentation/QueueInstrumentation.php | 4 +- .../QueueInstrumentationTest.php | 51 +++++++++++++++++++ tests/Support/TestJob.php | 10 +++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/Instrumentation/QueueInstrumentation.php b/src/Instrumentation/QueueInstrumentation.php index 5b8d5ba..e2fbed2 100644 --- a/src/Instrumentation/QueueInstrumentation.php +++ b/src/Instrumentation/QueueInstrumentation.php @@ -12,6 +12,7 @@ use Keepsuit\LaravelOpenTelemetry\Facades\Tracer; use OpenTelemetry\API\Trace\SpanInterface; use OpenTelemetry\API\Trace\SpanKind; +use OpenTelemetry\API\Trace\StatusCode; use OpenTelemetry\SemConv\TraceAttributes; class QueueInstrumentation implements Instrumentation @@ -113,7 +114,8 @@ protected function recordJobProcessing(): void $scope = Tracer::activeScope(); $span = Tracer::activeSpan(); - $span->recordException($event->exception); + $span->recordException($event->exception) + ->setStatus(StatusCode::STATUS_ERROR); $scope?->detach(); $span->end(); diff --git a/tests/Instrumentation/QueueInstrumentationTest.php b/tests/Instrumentation/QueueInstrumentationTest.php index 79be4f3..988a6cb 100644 --- a/tests/Instrumentation/QueueInstrumentationTest.php +++ b/tests/Instrumentation/QueueInstrumentationTest.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use Keepsuit\LaravelOpenTelemetry\Tests\Support\TestJob; +use OpenTelemetry\API\Trace\StatusCode; use OpenTelemetry\SDK\Trace\ImmutableSpan; use OpenTelemetry\SemConv\TraceAttributes; use Spatie\Valuestore\Valuestore; @@ -113,3 +114,53 @@ ->get('traceIdInJob')->toBe($root->getTraceId()) ->get('logContextInJob')->toMatchArray(['traceId' => $root->getTraceId()]); }); + +it('can trace queue failing jobs', function () { + withRootSpan(function () { + dispatch(new TestJob($this->valuestore, fail: true)); + }); + + Artisan::call('queue:work', [ + '--once' => true, + ]); + + $root = getRecordedSpans()->first(fn (ImmutableSpan $span) => $span->getName() === 'root'); + $enqueueSpan = getRecordedSpans()->first(fn (ImmutableSpan $span) => $span->getName() === TestJob::class.' enqueue'); + $processSpan = getRecordedSpans()->first(fn (ImmutableSpan $span) => $span->getName() === TestJob::class.' process'); + + assert($root instanceof ImmutableSpan); + assert($enqueueSpan instanceof ImmutableSpan); + assert($processSpan instanceof ImmutableSpan); + + $traceId = $enqueueSpan->getTraceId(); + $spanId = $enqueueSpan->getSpanId(); + + expect($this->valuestore) + ->get('uuid')->not->toBeNull() + ->get('traceparentInJob')->toBe(sprintf('00-%s-%s-01', $traceId, $spanId)) + ->get('traceIdInJob')->toBe($traceId) + ->get('logContextInJob')->toMatchArray(['traceId' => $traceId]); + + expect($enqueueSpan) + ->getStatus()->getCode()->toBe(StatusCode::STATUS_UNSET) + ->getAttributes()->toMatchArray([ + TraceAttributes::MESSAGING_SYSTEM => 'redis', + TraceAttributes::MESSAGING_OPERATION => 'enqueue', + TraceAttributes::MESSAGE_ID => $this->valuestore->get('uuid'), + TraceAttributes::MESSAGING_DESTINATION_NAME => 'default', + TraceAttributes::MESSAGING_DESTINATION_TEMPLATE => TestJob::class, + ]); + + expect($processSpan) + ->not->toBeNull() + ->getStatus()->getCode()->toBe(StatusCode::STATUS_ERROR) + ->getEvents()->toHaveCount(1) + ->getEvents()->{0}->getName()->toBe('exception') + ->getAttributes()->toMatchArray([ + TraceAttributes::MESSAGING_SYSTEM => 'redis', + TraceAttributes::MESSAGING_OPERATION => 'process', + TraceAttributes::MESSAGE_ID => $this->valuestore->get('uuid'), + TraceAttributes::MESSAGING_DESTINATION_NAME => 'default', + TraceAttributes::MESSAGING_DESTINATION_TEMPLATE => TestJob::class, + ]); +}); diff --git a/tests/Support/TestJob.php b/tests/Support/TestJob.php index b891120..1ef172b 100644 --- a/tests/Support/TestJob.php +++ b/tests/Support/TestJob.php @@ -15,8 +15,10 @@ class TestJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public function __construct(protected Valuestore $valuestore) - { + public function __construct( + protected Valuestore $valuestore, + protected bool $fail = false + ) { } public function handle(): void @@ -25,5 +27,9 @@ public function handle(): void $this->valuestore->put('traceparentInJob', $this->job->payload()['traceparent'] ?? null); $this->valuestore->put('traceIdInJob', Tracer::traceId()); $this->valuestore->put('logContextInJob', Log::sharedContext()); + + if ($this->fail) { + throw new \Exception('Job failed'); + } } }