• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FriendsOfOpenTelemetry / opentelemetry-bundle / 8191680297

07 Mar 2024 04:39PM UTC coverage: 86.386% (+0.4%) from 85.969%
8191680297

push

github

gaelreyrol
refacto(instrumentation): remove local usage of scopes

12 of 12 new or added lines in 6 files covered. (100.0%)

6 existing lines in 5 files now uncovered.

1929 of 2233 relevant lines covered (86.39%)

6.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.29
/src/Instrumentation/Symfony/HttpClient/TraceableHttpClient.php
1
<?php
2

3
namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Symfony\HttpClient;
4

5
use Nyholm\Psr7\Uri;
6
use OpenTelemetry\API\Trace\SpanInterface;
7
use OpenTelemetry\API\Trace\SpanKind;
8
use OpenTelemetry\API\Trace\StatusCode;
9
use OpenTelemetry\API\Trace\TracerInterface;
10
use OpenTelemetry\Context\Context;
11
use OpenTelemetry\SemConv\TraceAttributes;
12
use Psr\Log\LoggerAwareInterface;
13
use Psr\Log\LoggerInterface;
14
use Symfony\Component\HttpClient\Response\ResponseStream;
15
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
16
use Symfony\Contracts\HttpClient\HttpClientInterface;
17
use Symfony\Contracts\HttpClient\ResponseInterface;
18
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
19
use Symfony\Contracts\Service\ResetInterface;
20

21
final class TraceableHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface
22
{
23
    public function __construct(
24
        private HttpClientInterface $client,
25
        private readonly TracerInterface $tracer,
26
        private ?LoggerInterface $logger = null,
27
    ) {
28
    }
6✔
29

30
    /**
31
     * @param array<mixed> $options
32
     */
33
    public function request(string $method, string $url, array $options = []): ResponseInterface
34
    {
35
        $scope = Context::storage()->scope();
4✔
36
        if (null !== $scope) {
4✔
37
            $this->logger?->debug(sprintf('Using scope "%s"', spl_object_id($scope)));
×
38
        } else {
39
            $this->logger?->debug('No active scope');
4✔
40
        }
41
        $span = null;
4✔
42

43
        try {
44
            $uri = new Uri($url);
4✔
45

46
            $spanBuilder = $this->tracer
4✔
47
                ->spanBuilder('http.client')
4✔
48
                ->setSpanKind(SpanKind::KIND_CLIENT)
4✔
49
                ->setParent($scope?->context())
4✔
50
                ->setAttribute(TraceAttributes::URL_FULL, $url)
4✔
51
                ->setAttribute(TraceAttributes::URL_SCHEME, $uri->getScheme())
4✔
52
                ->setAttribute(TraceAttributes::URL_PATH, $uri->getPath())
4✔
53
                ->setAttribute(TraceAttributes::URL_QUERY, $uri->getQuery())
4✔
54
                ->setAttribute(TraceAttributes::URL_FRAGMENT, $uri->getFragment())
4✔
55
                ->setAttribute(TraceAttributes::HTTP_REQUEST_METHOD, $method)
4✔
56
            ;
4✔
57

58
            $span = $spanBuilder->startSpan();
4✔
59

60
            $this->logger?->debug(sprintf('Starting span "%s"', $span->getContext()->getSpanId()));
4✔
61

62
            return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $span);
4✔
UNCOV
63
        } catch (ExceptionInterface $exception) {
×
64
            $span->recordException($exception, [TraceAttributes::EXCEPTION_ESCAPED => true]);
×
65
            $span->setStatus(StatusCode::STATUS_ERROR, $exception->getMessage());
×
66
            throw $exception;
×
67
        } finally {
68
            if ($span instanceof SpanInterface) {
4✔
69
                $this->logger?->debug(sprintf('Ending span "%s"', $span->getContext()->getSpanId()));
4✔
70
                $span->end();
4✔
71
            }
72
        }
73
    }
74

75
    public function stream(iterable|ResponseInterface $responses, ?float $timeout = null): ResponseStreamInterface
76
    {
77
        if ($responses instanceof TraceableResponse) {
1✔
78
            $responses = [$responses];
1✔
79
        } elseif (!is_iterable($responses)) {
×
80
            throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', __METHOD__, get_debug_type($responses)));
×
81
        }
82

83
        return new ResponseStream(TraceableResponse::stream($this->client, $responses, $timeout));
1✔
84
    }
85

86
    /**
87
     * @param array<mixed> $options
88
     */
89
    public function withOptions(array $options): static
90
    {
91
        $clone = clone $this;
×
92
        $clone->client = $this->client->withOptions($options);
×
93

94
        return $clone;
×
95
    }
96

97
    public function setLogger(LoggerInterface $logger): void
98
    {
99
        if ($this->client instanceof LoggerAwareInterface) {
×
100
            $this->client->setLogger($logger);
×
101
        }
102
        $this->logger = $logger;
×
103
    }
104

105
    public function reset(): void
106
    {
107
        if ($this->client instanceof ResetInterface) {
2✔
108
            $this->client->reset();
2✔
109
        }
110
    }
111
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc