Passed
Pull Request — master (#8)
by
unknown
03:37 queued 48s
created

HttpTracingMiddleware::traceIdHeader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Umbrellio\Jaravel\Middleware;
6
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Facades\Config;
9
use OpenTelemetry\SDK\Trace\Span;
10
use Symfony\Component\HttpFoundation\Response;
11
use Umbrellio\Jaravel\Services\Caller;
12
use Umbrellio\Jaravel\Services\Http\TracingRequestGuard;
13
use Umbrellio\Jaravel\Services\Span\ActiveSpanTraceIdRetriever;
14
use Umbrellio\Jaravel\Services\Span\SpanCreator;
15
use Umbrellio\Jaravel\Services\Span\SpanAttributeHelper;
16
use Umbrellio\Jaravel\Services\TraceIdHeaderRetriever;
17
18
class HttpTracingMiddleware
19
{
20
    private SpanCreator $spanCreator;
21
    private TracingRequestGuard $requestGuard;
22
    private ActiveSpanTraceIdRetriever $activeTraceIdRetriever;
23
    private TraceIdHeaderRetriever $traceIdHeaderRetriever;
24
25
    public function __construct(
26
        SpanCreator $spanCreator,
27
        TracingRequestGuard $requestGuard,
28
        ActiveSpanTraceIdRetriever $activeTraceIdRetriever,
29
        TraceIdHeaderRetriever $traceIdHeaderRetriever
30
    ) {
31
        $this->spanCreator = $spanCreator;
32
        $this->requestGuard = $requestGuard;
33
        $this->activeTraceIdRetriever = $activeTraceIdRetriever;
34
        $this->traceIdHeaderRetriever = $traceIdHeaderRetriever;
35
    }
36
37
    /** @param Request $request */
38
    public function handle($request, callable $next)
39
    {
40
        if (!$this->requestGuard->allowRequest($request)) {
41
            return $next($request);
42
        }
43
44
        $headers = $request->server->all();
45
46
        $traceIdHeader = $this->traceIdHeaderRetriever->retrieve($headers, $this->traceIdHeader());
47
48
        $this->spanCreator->create(
49
            Caller::call(Config::get('jaravel.http.span_name'), [$request]),
50
            $traceIdHeader
51
        )->activate();
52
53
        /** @var Response $response */
54
        $response = $next($request);
55
56
        $this->addTraceIdToHeaderIfNeeded($response);
57
58
        return $response;
59
    }
60
61
    public function terminate($request, $response)
62
    {
63
        $span = Span::getCurrent();
64
        $scope = $span->activate();
65
66
        $callableConfig = Config::get('jaravel.http.attributes', fn () => [
67
            'type' => 'http',
68
        ]);
69
70
        SpanAttributeHelper::setAttributes($span, Caller::call($callableConfig, [$request, $response]));
71
72
        $span->end();
73
        $scope->detach();
74
    }
75
76
    private function addTraceIdToHeaderIfNeeded(Response $response): void
77
    {
78
        $headerName = $this->traceIdHeader();
79
80
        if (!$headerName) {
81
            return;
82
        }
83
84
        $traceId = $this->activeTraceIdRetriever->retrieve();
85
86
        $response->headers->set($headerName, $traceId);
87
    }
88
89
    private function traceIdHeader(): ?string
90
    {
91
        return Config::get('jaravel.trace_id_header', null);
92
    }
93
}
94