diff --git a/src/Zipkin/ErrorParser.php b/src/Zipkin/ErrorParser.php index d08b67d..8dc22f3 100644 --- a/src/Zipkin/ErrorParser.php +++ b/src/Zipkin/ErrorParser.php @@ -1,5 +1,7 @@ + */ public function parseTags(Throwable $e): array; } diff --git a/src/Zipkin/Instrumentation/Http/Client/HttpClientTracing.php b/src/Zipkin/Instrumentation/Http/Client/HttpClientTracing.php index f3bb1b8..8775f2a 100644 --- a/src/Zipkin/Instrumentation/Http/Client/HttpClientTracing.php +++ b/src/Zipkin/Instrumentation/Http/Client/HttpClientTracing.php @@ -27,8 +27,8 @@ class HttpClientTracing public function __construct( Tracing $tracing, - HttpClientParser $parser = null, - callable $requestSampler = null + ?HttpClientParser $parser = null, + ?callable $requestSampler = null ) { $this->tracing = $tracing; $this->parser = $parser ?? new DefaultHttpClientParser(); diff --git a/src/Zipkin/Instrumentation/Http/Server/HttpServerTracing.php b/src/Zipkin/Instrumentation/Http/Server/HttpServerTracing.php index 53b7395..abc7c2e 100644 --- a/src/Zipkin/Instrumentation/Http/Server/HttpServerTracing.php +++ b/src/Zipkin/Instrumentation/Http/Server/HttpServerTracing.php @@ -26,8 +26,8 @@ class HttpServerTracing public function __construct( Tracing $tracing, - HttpServerParser $parser = null, - callable $requestSampler = null + ?HttpServerParser $parser = null, + ?callable $requestSampler = null ) { $this->tracing = $tracing; $this->parser = $parser ?? new DefaultHttpServerParser(); diff --git a/src/Zipkin/Instrumentation/Mysqli/Mysqli.php b/src/Zipkin/Instrumentation/Mysqli/Mysqli.php index e25011b..95f3baf 100644 --- a/src/Zipkin/Instrumentation/Mysqli/Mysqli.php +++ b/src/Zipkin/Instrumentation/Mysqli/Mysqli.php @@ -6,8 +6,8 @@ use const Zipkin\Tags\ERROR; use Zipkin\Tracer; use Zipkin\Span; - use Zipkin\Endpoint; +use Zipkin\Kind; use InvalidArgumentException; /** @@ -24,113 +24,105 @@ final class Mysqli extends \Mysqli ]; private Tracer $tracer; - private array $options; public function __construct( Tracer $tracer, array $options = [], - string $host = null, - string $user = null, - string $password = null, + ?string $host = null, + ?string $user = null, + ?string $password = null, string $database = '', - int $port = null, - string $socket = null + ?int $port = null, + ?string $socket = null ) { self::validateOptions($options); $this->tracer = $tracer; $this->options = $options + self::DEFAULT_OPTIONS; + + $defaultHost = \ini_get('mysqli.default_host') ?: ''; + $defaultUser = \ini_get('mysqli.default_user') ?: ''; + $defaultPassword = \ini_get('mysqli.default_pw') ?: ''; + $defaultPort = (int) (\ini_get('mysqli.default_port') ?: 3306); + $defaultSocket = \ini_get('mysqli.default_socket') ?: ''; + parent::__construct( - $host ?? (ini_get('mysqli.default_host') ?: ''), - $user ?? (ini_get('mysqli.default_user') ?: ''), - $password ?? (ini_get('mysqli.default_pw') ?: ''), + $host ?? $defaultHost, + $user ?? $defaultUser, + $password ?? $defaultPassword, $database, - $port ?? (($defaultPort = ini_get('mysqli.default_port')) ? (int) $defaultPort : 3306), - $socket ?? (ini_get('mysqli.default_socket') ?: '') + $port ?? $defaultPort, + $socket ?? $defaultSocket ); } - private static function validateOptions(array $opts): void + /** + * {@inheritdoc} + */ + public function query(string $query, int $result_mode = MYSQLI_STORE_RESULT): mysqli_result|bool { - if (array_key_exists('tag_query', $opts) && ($opts['tag_query'] !== (bool) $opts['tag_query'])) { - throw new InvalidArgumentException('Invalid tag_query, bool expected'); - } - - if (array_key_exists('remote_endpoint', $opts) && !($opts['remote_endpoint'] instanceof Endpoint)) { - throw new InvalidArgumentException(sprintf('Invalid remote_endpoint, %s expected', Endpoint::class)); - } - - if (array_key_exists('default_tags', $opts) && ($opts['default_tags'] !== (array) $opts['default_tags'])) { - throw new InvalidArgumentException('Invalid default_tags, array expected'); - } - } + $span = $this->tracer->nextSpan(); + $span->start(); + $span->setName('query'); + $span->setKind(Kind\CLIENT); - private function addsTagsAndRemoteEndpoint(Span $span, string $query = null): void - { - if ($query !== null && $this->options['tag_query']) { + if ($this->options['tag_query']) { $span->tag('sql.query', $query); } - if ($this->options['remote_endpoint'] !== null) { - $span->setRemoteEndpoint($this->options['remote_endpoint']); - } - foreach ($this->options['default_tags'] as $key => $value) { $span->tag($key, $value); } - } - - /** - * Performs a query on the database - * - * @return mysqli_result|bool - * @alias mysqli_query - */ - public function query(string $query, int $resultmode = MYSQLI_STORE_RESULT) - { - if ($resultmode === MYSQLI_ASYNC) { - // if $resultmode is async, making the timing on this execution - // does not make much sense. For now we just skip tracing on this. - return parent::query($query, $resultmode); - } - $span = $this->tracer->nextSpan(); - $span->setName('sql/query'); - $this->addsTagsAndRemoteEndpoint($span, $query); - if ($this->options['tag_query']) { - $span->tag('sql.query', $query); + if ($this->options['remote_endpoint'] !== null) { + $span->setRemoteEndpoint($this->options['remote_endpoint']); } - $span->start(); try { - $result = parent::query($query, $resultmode); + $result = parent::query($query, $result_mode); if ($result === false) { - $span->tag(ERROR, 'true'); + $span->tag(ERROR, $this->error); } return $result; + } catch (\Throwable $e) { + $span->tag(ERROR, $e->getMessage()); + throw $e; } finally { $span->finish(); } } /** - * @return bool - * @alias mysqli_real_query + * {@inheritdoc} */ - // phpcs:ignore PSR1.Methods.CamelCapsMethodName - public function real_query(string $query) + public function real_query(string $query): bool { $span = $this->tracer->nextSpan(); - $span->setName('sql/query'); - $this->addsTagsAndRemoteEndpoint($span, $query); - $span->start(); + $span->setName('real_query'); + $span->setKind(Kind\CLIENT); + + if ($this->options['tag_query']) { + $span->tag('sql.query', $query); + } + + foreach ($this->options['default_tags'] as $key => $value) { + $span->tag($key, $value); + } + + if ($this->options['remote_endpoint'] !== null) { + $span->setRemoteEndpoint($this->options['remote_endpoint']); + } + try { $result = parent::real_query($query); if ($result === false) { - $span->tag(ERROR, 'true'); + $span->tag(ERROR, $this->error); } return $result; + } catch (\Throwable $e) { + $span->tag(ERROR, $e->getMessage()); + throw $e; } finally { $span->finish(); } @@ -138,58 +130,63 @@ public function real_query(string $query) /** * {@inheritdoc} - * @alias mysqli_begin_transaction */ - // phpcs:ignore PSR1.Methods.CamelCapsMethodName - public function begin_transaction($flags = 0, $name = null) + public function begin_transaction(int $flags = 0, ?string $name = null): bool { $span = $this->tracer->nextSpan(); - $span->setName('sql/begin_transaction'); - $this->addsTagsAndRemoteEndpoint($span); $span->start(); - if ($name !== null) { - $span->tag('mysqli.transaction_name', (string) $name); + $span->setName('begin_transaction'); + $span->setKind(Kind\CLIENT); + + foreach ($this->options['default_tags'] as $key => $value) { + $span->tag($key, $value); } - try { - if ($name === null) { - $result = parent::begin_transaction($flags); - } else { - $result = parent::begin_transaction($flags, $name); - } + if ($this->options['remote_endpoint'] !== null) { + $span->setRemoteEndpoint($this->options['remote_endpoint']); + } + + try { + $result = parent::begin_transaction($flags, $name); if ($result === false) { - $span->tag(ERROR, 'true'); + $span->tag(ERROR, $this->error); } return $result; + } catch (\Throwable $e) { + $span->tag(ERROR, $e->getMessage()); + throw $e; } finally { $span->finish(); } } /** - * @return bool - * @alias mysqli_commit + * {@inheritdoc} */ - public function commit(int $flags = -1, ?string $name = null) + public function commit(int $flags = 0, ?string $name = null): bool { $span = $this->tracer->nextSpan(); - $span->setName('sql/begin_transaction'); - $this->addsTagsAndRemoteEndpoint($span); $span->start(); - if ($name !== null) { - $span->tag('mysqli.transaction_name', $name); + $span->setName('commit'); + $span->setKind(Kind\CLIENT); + + foreach ($this->options['default_tags'] as $key => $value) { + $span->tag($key, $value); } - try { - if ($name === null) { - $result = parent::commit($flags); - } else { - $result = parent::commit($flags, $name); - } + if ($this->options['remote_endpoint'] !== null) { + $span->setRemoteEndpoint($this->options['remote_endpoint']); + } + + try { + $result = parent::commit($flags, $name); if ($result === false) { - $span->tag(ERROR, 'true'); + $span->tag(ERROR, $this->error); } return $result; + } catch (\Throwable $e) { + $span->tag(ERROR, $e->getMessage()); + throw $e; } finally { $span->finish(); } @@ -197,29 +194,48 @@ public function commit(int $flags = -1, ?string $name = null) /** * {@inheritdoc} - * @alias mysqli_rollback */ - public function rollback($flags = 0, $name = null) + public function rollback(int $flags = 0, ?string $name = null): bool { $span = $this->tracer->nextSpan(); - $span->setName('sql/rollback'); - $this->addsTagsAndRemoteEndpoint($span); $span->start(); - if ($name !== null) { - $span->tag('mysqli.transaction_name', (string) $name); + $span->setName('rollback'); + $span->setKind(Kind\CLIENT); + + foreach ($this->options['default_tags'] as $key => $value) { + $span->tag($key, $value); } + + if ($this->options['remote_endpoint'] !== null) { + $span->setRemoteEndpoint($this->options['remote_endpoint']); + } + try { - if ($name === null) { - $result = parent::commit($flags); - } else { - $result = parent::commit($flags, $name); - } + $result = parent::rollback($flags, $name); if ($result === false) { - $span->tag(ERROR, 'true'); + $span->tag(ERROR, $this->error); } return $result; + } catch (\Throwable $e) { + $span->tag(ERROR, $e->getMessage()); + throw $e; } finally { $span->finish(); } } + + private static function validateOptions(array $opts): void + { + if (isset($opts['remote_endpoint']) && !$opts['remote_endpoint'] instanceof Endpoint) { + throw new InvalidArgumentException( + \sprintf('Invalid remote_endpoint. Expected Endpoint, got %s', \gettype($opts['remote_endpoint'])) + ); + } + + if (isset($opts['default_tags']) && !\is_array($opts['default_tags'])) { + throw new InvalidArgumentException( + \sprintf('Invalid default_tags. Expected array, got %s', \gettype($opts['default_tags'])) + ); + } + } } diff --git a/src/Zipkin/Kind.php b/src/Zipkin/Kind.php index fda3b9b..e5dcfc9 100644 --- a/src/Zipkin/Kind.php +++ b/src/Zipkin/Kind.php @@ -28,3 +28,11 @@ * #PRODUCER} of this message is the {@link TraceContext#parentId()} of this span. */ const CONSUMER = 'CONSUMER'; + + +class Kind { + const CLIENT = 'CLIENT'; + const SERVER = 'SERVER'; + const PRODUCER = 'PRODUCER'; + const CONSUMER = 'CONSUMER'; +} diff --git a/src/Zipkin/NoopSpan.php b/src/Zipkin/NoopSpan.php index be148f1..b8a78f2 100644 --- a/src/Zipkin/NoopSpan.php +++ b/src/Zipkin/NoopSpan.php @@ -37,7 +37,7 @@ public function getContext(): TraceContext * Spans can be modified before calling start. For example, you can add tags to the span and * set its name without lock contention. */ - public function start(int $timestamp = null): void + public function start(?int $timestamp = null): void { } @@ -87,7 +87,7 @@ public function setError(Throwable $e): void * @return void * @see Annotations */ - public function annotate(string $value, int $timestamp = null): void + public function annotate(string $value, ?int $timestamp = null): void { } @@ -113,7 +113,7 @@ public function abandon(): void * {@link zipkin.Span#duration Zipkin's span duration} is derived by subtracting the start * timestamp from this, and set when appropriate. */ - public function finish(int $timestamp = null): void + public function finish(?int $timestamp = null): void { } diff --git a/src/Zipkin/NoopSpanCustomizer.php b/src/Zipkin/NoopSpanCustomizer.php index 49d74d9..fffb64a 100644 --- a/src/Zipkin/NoopSpanCustomizer.php +++ b/src/Zipkin/NoopSpanCustomizer.php @@ -23,7 +23,7 @@ public function tag(string $key, string $value): void /** * {@inheritdoc} */ - public function annotate(string $value, int $timestamp = null): void + public function annotate(string $value, ?int $timestamp = null): void { } } diff --git a/src/Zipkin/Propagation/B3.php b/src/Zipkin/Propagation/B3.php index 73cc8b5..274d95f 100644 --- a/src/Zipkin/Propagation/B3.php +++ b/src/Zipkin/Propagation/B3.php @@ -147,7 +147,7 @@ final class B3 implements Propagation * same injector list. */ public function __construct( - LoggerInterface $logger = null, + ?LoggerInterface $logger = null, array $kindInjectors = [] ) { $this->logger = $logger ?: new NullLogger(); diff --git a/src/Zipkin/Propagation/CurrentTraceContext.php b/src/Zipkin/Propagation/CurrentTraceContext.php index 7b5a548..5d8bafb 100644 --- a/src/Zipkin/Propagation/CurrentTraceContext.php +++ b/src/Zipkin/Propagation/CurrentTraceContext.php @@ -18,9 +18,12 @@ final class CurrentTraceContext { + /** + * @var ?TraceContext + */ private ?TraceContext $context; - public function __construct(TraceContext $currentContext = null) + public function __construct(?TraceContext $currentContext = null) { $this->context = $currentContext; } @@ -40,7 +43,7 @@ public function getContext(): ?TraceContext * @param TraceContext|null $currentContext * @return callable():void The scope closed */ - public function createScopeAndRetrieveItsCloser(TraceContext $currentContext = null): callable + public function createScopeAndRetrieveItsCloser(?TraceContext $currentContext = null): callable { $previous = $this->context; $self = $this; diff --git a/src/Zipkin/RealSpan.php b/src/Zipkin/RealSpan.php index 33b7eaf..cc8ea07 100644 --- a/src/Zipkin/RealSpan.php +++ b/src/Zipkin/RealSpan.php @@ -48,11 +48,11 @@ public function getContext(): TraceContext * Spans can be modified before calling start. For example, you can add tags to the span and * set its name without lock contention. * - * @param int $timestamp + * @param int|null $timestamp * @return void * @throws \InvalidArgumentException */ - public function start(int $timestamp = null): void + public function start(?int $timestamp = null): void { if ($timestamp !== null && !isValid($timestamp)) { throw new InvalidArgumentException( @@ -117,7 +117,7 @@ public function setError(Throwable $e): void * @throws \InvalidArgumentException * @see Zipkin\Annotations */ - public function annotate(string $value, int $timestamp = null): void + public function annotate(string $value, ?int $timestamp = null): void { if ($timestamp !== null && !isValid($timestamp)) { throw new InvalidArgumentException( @@ -161,7 +161,7 @@ public function abandon(): void * @return void * @throws \InvalidArgumentException */ - public function finish(int $timestamp = null): void + public function finish(?int $timestamp = null): void { if ($timestamp !== null && !isValid($timestamp)) { throw new InvalidArgumentException('Invalid timestamp'); diff --git a/src/Zipkin/Recording/Span.php b/src/Zipkin/Recording/Span.php index 82c68d4..6d25e05 100644 --- a/src/Zipkin/Recording/Span.php +++ b/src/Zipkin/Recording/Span.php @@ -262,13 +262,13 @@ public function setRemoteEndpoint(Endpoint $remoteEndpoint): void } /** - * Completes and reports the span. If no finish timestamp is specified - * we don't compute the duration but the span is still reporterd. This - * usually happens when a span is flushed manually. + * Records the final timestamp, calculates duration and puts the span + * in the recorder. * - * @param int|null $finishTimestamp + * @param int|null $finishTimestamp When null, the value of {@link Timestamp\now()} + * is used. */ - public function finish(int $finishTimestamp = null): void + public function finish(?int $finishTimestamp = null): void { if ($this->finished) { return; diff --git a/src/Zipkin/Reporter.php b/src/Zipkin/Reporter.php index 983982e..9d43b90 100644 --- a/src/Zipkin/Reporter.php +++ b/src/Zipkin/Reporter.php @@ -9,7 +9,9 @@ interface Reporter { /** - * @param MutableSpan[] $spans + * Sends the given spans to the transport. + * + * @param array $spans * @return void */ public function report(array $spans): void; diff --git a/src/Zipkin/Reporters/Http.php b/src/Zipkin/Reporters/Http.php index 14f9cdc..ee20ca7 100644 --- a/src/Zipkin/Reporters/Http.php +++ b/src/Zipkin/Reporters/Http.php @@ -11,8 +11,8 @@ use Zipkin\Reporter; use Zipkin\Recording\ReadbackSpan; use RuntimeException; -use Psr\Log\NullLogger; use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; final class Http implements Reporter { @@ -51,9 +51,9 @@ final class Http implements Reporter */ public function __construct( array $options = [], - ClientFactory $requesterFactory = null, - LoggerInterface $logger = null, - SpanSerializer $serializer = null + ?ClientFactory $requesterFactory = null, + ?LoggerInterface $logger = null, + ?SpanSerializer $serializer = null ) { $this->options = \array_merge(self::DEFAULT_OPTIONS, $options); $this->clientFactory = $requesterFactory ?? CurlFactory::create(); diff --git a/src/Zipkin/Reporters/JsonV2Serializer.php b/src/Zipkin/Reporters/JsonV2Serializer.php index c7a05e1..c3d9894 100644 --- a/src/Zipkin/Reporters/JsonV2Serializer.php +++ b/src/Zipkin/Reporters/JsonV2Serializer.php @@ -13,7 +13,7 @@ class JsonV2Serializer implements SpanSerializer { private ErrorParser $errorParser; - public function __construct(ErrorParser $errorParser = null) + public function __construct(?ErrorParser $errorParser = null) { $this->errorParser = $errorParser ?? new DefaultErrorParser(); } diff --git a/src/Zipkin/Reporters/Log.php b/src/Zipkin/Reporters/Log.php index d2cebd1..e9eae5b 100644 --- a/src/Zipkin/Reporters/Log.php +++ b/src/Zipkin/Reporters/Log.php @@ -16,7 +16,7 @@ final class Log implements Reporter public function __construct( LoggerInterface $logger, - SpanSerializer $serializer = null + ?SpanSerializer $serializer = null ) { $this->logger = $logger; $this->serializer = $serializer ?? new JsonV2Serializer(); diff --git a/src/Zipkin/Span.php b/src/Zipkin/Span.php index d8fcdac..fcb3cb3 100644 --- a/src/Zipkin/Span.php +++ b/src/Zipkin/Span.php @@ -14,9 +14,14 @@ interface Span * When true, no recording is done and nothing is reported to zipkin. However, this span should * still be injected into outgoing requests. Use this flag to avoid performing expensive * computation. + * + * @return bool */ public function isNoop(): bool; + /** + * @return TraceContext + */ public function getContext(): TraceContext; /** @@ -24,11 +29,18 @@ public function getContext(): TraceContext; * * Spans can be modified before calling start. For example, you can add tags to the span and * set its name without lock contention. + * + * @param int|null $timestamp + * @return void + * @throws \InvalidArgumentException */ - public function start(int $timestamp = null): void; + public function start(?int $timestamp = null): void; /** * Sets the string name for the logical operation this span represents. + * + * @param string $name + * @return void */ public function setName(string $name): void; @@ -38,16 +50,20 @@ public function setName(string $name): void; * and that plus its duration as "ss". * * The value must be strictly one of the ones listed in {@link Kind}. + * + * @param string $kind one of Kind\CLIENT, Kind\SERVER, Kind\CONSUMER and + * Kind\PRODUCER + * @return void */ public function setKind(string $kind): void; /** * Tags give your span context for search, viewing and analysis. For example, a key - * "your_app.version" would let you lookup spans by version. A tag {@link Zipkin\Tags\SQL_QUERY} - * isn't searchable, but it can help in debugging when viewing a trace. + * "your_app.version" would let you lookup spans by version. A tag "sql.query" isn't searchable, + * but might show in the span view for a database call. * * @param string $key Name used to lookup spans, such as "your_app.version". See {@link Zipkin\Tags} for - * standard ones. + * common ones. * @param string $value * @return void */ @@ -65,9 +81,9 @@ public function setError(Throwable $e): void; * @param string $value A short tag indicating the event, like "finagle.retry" * @param int|null $timestamp * @return void - * @see Annotations + * @throws \InvalidArgumentException */ - public function annotate(string $value, int $timestamp = null): void; + public function annotate(string $value, ?int $timestamp = null): void; /** * For a client span, this would be the server's address. @@ -94,17 +110,18 @@ public function abandon(): void; * * @param int|null $timestamp * @return void + * @throws \InvalidArgumentException */ - public function finish(int $timestamp = null): void; + public function finish(?int $timestamp = null): void; /** * Reports the span, even if unfinished. Most users will not call this method. * * This primarily supports two use cases: one-way spans and orphaned spans. - * For example, a one-way span can be modeled as a span where one tracer calls start and another + * For example, a one-way span can be modeled as a span where one flusher calls start and another * calls finish. In order to report that span from its origin, flush must be called. * - * Another example is where a user did not call finish within a deadline or before a shutdown + * Another example is where a user didn't call finish within a deadline or before a shutdown * occurs. By flushing, you can report what was in progress. * * @return void diff --git a/src/Zipkin/SpanCustomizer.php b/src/Zipkin/SpanCustomizer.php index 5a56459..918505b 100644 --- a/src/Zipkin/SpanCustomizer.php +++ b/src/Zipkin/SpanCustomizer.php @@ -41,5 +41,5 @@ public function tag(string $key, string $value): void; * @return void * @see Annotations */ - public function annotate(string $value, int $timestamp = null): void; + public function annotate(string $value, ?int $timestamp = null): void; } diff --git a/src/Zipkin/SpanCustomizerShield.php b/src/Zipkin/SpanCustomizerShield.php index 06e94df..ca60c95 100644 --- a/src/Zipkin/SpanCustomizerShield.php +++ b/src/Zipkin/SpanCustomizerShield.php @@ -37,7 +37,7 @@ public function tag(string $key, string $value): void /** * {@inheritdoc} */ - public function annotate(string $value, int $timestamp = null): void + public function annotate(string $value, ?int $timestamp = null): void { $this->delegate->annotate($value, $timestamp); } diff --git a/src/Zipkin/Tracer.php b/src/Zipkin/Tracer.php index 4d40b81..42ddfa7 100644 --- a/src/Zipkin/Tracer.php +++ b/src/Zipkin/Tracer.php @@ -70,10 +70,10 @@ public function __construct( * } * } * - * @param SamplingFlags $samplingFlags - * @return Span + * @param SamplingFlags|null $samplingFlags the sampling flags, defaults to SampleFlags::EMPTY + * @return Span a span that has not been started */ - public function newTrace(SamplingFlags $samplingFlags = null): Span + public function newTrace(?SamplingFlags $samplingFlags = null): Span { if ($samplingFlags === null) { $samplingFlags = DefaultSamplingFlags::createAsEmpty(); @@ -135,11 +135,11 @@ public function joinSpan(TraceContext $context): Span * finish the span. Not only is it safe to call the closer, you must call the closer to end the scope, or * risk leaking resources associated with the scope. * - * @param Span $span to place into scope or null to clear the scope + * @param Span|null $span to place into scope or null to clear the scope * * @return callable():void The scope closer */ - public function openScope(Span $span = null): callable + public function openScope(?Span $span = null): callable { return $this->currentTraceContext->createScopeAndRetrieveItsCloser( $span === null ? null : $span->getContext() @@ -189,11 +189,12 @@ public function flush(): void * whatever the {@link #currentSpan()} was. Make sure you re-apply {@link #withSpanInScope(Span)} * so that data is written to the correct trace. * - * @param SamplingFlags|TraceContext $contextOrFlags + * @param TraceContext|SamplingFlags|null $contextOrFlags Either the trace context + * to use to create the new span or the SamplingFlags * @return Span * @throws \RuntimeException */ - public function nextSpan(SamplingFlags $contextOrFlags = null): Span + public function nextSpan(?SamplingFlags $contextOrFlags = null): Span { if ($contextOrFlags === null) { $parent = $this->currentTraceContext->getContext(); @@ -230,7 +231,7 @@ public function nextSpan(SamplingFlags $contextOrFlags = null): Span public function nextSpanWithSampler( callable $sampler, array $args = [], - SamplingFlags $contextOrFlags = null + ?SamplingFlags $contextOrFlags = null ): Span { if ($contextOrFlags === null) { $contextOrFlags = $this->currentTraceContext->getContext();