Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions src/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ final class Event
private $id;

/**
* @var string|float The date and time of when this event was generated
* @var float|null The date and time of when this event was generated
*/
private $timestamp;

Expand Down Expand Up @@ -161,7 +161,7 @@ final class Event
private function __construct(?EventId $eventId, EventType $eventType)
{
$this->id = $eventId ?? EventId::generate();
$this->timestamp = gmdate('Y-m-d\TH:i:s\Z');
$this->timestamp = microtime(true);
$this->sdkVersion = PrettyVersions::getVersion('sentry/sentry')->getPrettyVersion();
$this->type = $eventType;
}
Expand Down Expand Up @@ -237,19 +237,17 @@ public function setSdkVersion(string $sdkVersion): void
/**
* Gets the timestamp of when this event was generated.
*
* @return string|float
* @return float
*/
public function getTimestamp()
public function getTimestamp(): ?float
{
return $this->timestamp;
}

/**
* Sets the timestamp of when the Event was created.
*
* @param float|string $timestamp
*/
public function setTimestamp($timestamp): void
public function setTimestamp(?float $timestamp): void
{
$this->timestamp = $timestamp;
}
Expand Down
10 changes: 10 additions & 0 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ public function setTracesSampleRate(float $sampleRate): void
$this->options = $this->resolver->resolve($options);
}

/**
* Gets whether tracing is enabled or not. The feature is enabled when at
* least one of the `traces_sample_rate` and `traces_sampler` options is
* set.
*/
public function isTracingEnabled(): bool
{
return 0 != $this->options['traces_sample_rate'] || null !== $this->options['traces_sampler'];
}

/**
* Gets whether the stacktrace will be attached on captureMessage.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/ResponseStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class ResponseStatus
private $value;

/**
* @var array<string, ResponseStatus>
* @var array<string, self>
*/
private static $instances = [];

Expand Down
2 changes: 1 addition & 1 deletion src/Serializer/PayloadSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ private function serializeSpan(Span $span): array
}

if (null !== $span->getStatus()) {
$result['status'] = $span->getStatus();
$result['status'] = (string) $span->getStatus();
}

if (null !== $span->getDescription()) {
Expand Down
102 changes: 62 additions & 40 deletions src/State/Hub.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,63 +209,47 @@ public function getIntegration(string $className): ?IntegrationInterface
return null;
}

/**
* Gets the scope bound to the top of the stack.
*/
private function getScope(): Scope
{
return $this->getStackTop()->getScope();
}

/**
* Gets the topmost client/layer pair in the stack.
*/
private function getStackTop(): Layer
{
return $this->stack[\count($this->stack) - 1];
}

/**
* {@inheritdoc}
*/
public function startTransaction(TransactionContext $context): Transaction
{
$transaction = new Transaction($context, $this);
$client = $this->getClient();
$sampleRate = null;
$options = null !== $client ? $client->getOptions() : null;

if (null !== $client) {
$sampler = $client->getOptions()->getTracesSampler();
if (null === $options || !$options->isTracingEnabled()) {
$transaction->setSampled(false);

if (null !== $sampler) {
$sampleRate = $sampler(SamplingContext::getDefault($context));
}
return $transaction;
}

// Roll the dice for sampling transaction, all child spans inherit the sampling decision.
// Only if $sampleRate is `null` (which can only be because then the traces_sampler wasn't defined)
// we need to roll the dice.
if (null === $context->sampled && null === $sampleRate) {
if (null !== $client) {
$sampleRate = $client->getOptions()->getTracesSampleRate();
}
$samplingContext = SamplingContext::getDefault($context);
$tracesSampler = $options->getTracesSampler();
$sampleRate = null !== $tracesSampler
? $tracesSampler($samplingContext)
: $this->getSampleRate($samplingContext->getParentSampled(), $options->getSampleRate());

if (!$this->isValidSampleRate($sampleRate)) {
$transaction->setSampled(false);

return $transaction;
}

if ($sampleRate < 1 && mt_rand(1, 100) / 100.0 > $sampleRate) {
// if true = we want to have the transaction
// if false = we don't want to have it
$context->sampled = false;
} else {
$context->sampled = true;
if (0.0 === $sampleRate) {
$transaction->setSampled(false);

return $transaction;
}

$transaction = new Transaction($context, $this);
$transaction->setSampled(mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax() < $sampleRate);

// We only want to create a span list if we sampled the transaction
// If sampled == false, we will discard the span anyway, so we can save memory by not storing child spans
if ($context->sampled) {
$transaction->initSpanRecorder();
if (!$transaction->getSampled()) {
return $transaction;
}

$transaction->initSpanRecorder();

return $transaction;
}

Expand Down Expand Up @@ -297,4 +281,42 @@ public function getSpan(): ?Span
{
return $this->getScope()->getSpan();
}

/**
* Gets the scope bound to the top of the stack.
*/
private function getScope(): Scope
{
return $this->getStackTop()->getScope();
}

/**
* Gets the topmost client/layer pair in the stack.
*/
private function getStackTop(): Layer
{
return $this->stack[\count($this->stack) - 1];
}

private function getSampleRate(?bool $hasParentBeenSampled, float $fallbackSampleRate): float
{
if (true === $hasParentBeenSampled) {
return 1;
}

if (false === $hasParentBeenSampled) {
return 0;
}

return $fallbackSampleRate;
}

private function isValidSampleRate(float $sampleRate): bool
{
if ($sampleRate < 0 || $sampleRate > 1) {
return false;
}

return true;
}
}
17 changes: 7 additions & 10 deletions src/State/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,17 +363,17 @@ public function applyToEvent(Event $event, $payload): ?Event
}

/**
* Returns the Span that is on the Scope.
* Returns the span that is on the scope.
*/
public function getSpan(): ?Span
{
return $this->span;
}

/**
* Sets the Span on the Scope.
* Sets the span on the scope.
*
* @param Span|null $span The Span
* @param Span|null $span The span
*
* @return $this
*/
Expand All @@ -385,19 +385,16 @@ public function setSpan(?Span $span): self
}

/**
* Returns the Transaction that is on the Scope.
*
* @psalm-suppress MoreSpecificReturnType
* @psalm-suppress LessSpecificReturnStatement
* Returns the transaction attached to the scope (if there is one).
*/
public function getTransaction(): ?Transaction
{
$span = $this->span;

if (null !== $span && null !== $span->spanRecorder && !empty($span->spanRecorder->getSpans())) {
if (null !== $span && null !== $span->getSpanRecorder() && !empty($span->getSpanRecorder()->getSpans())) {
// The first span in the recorder is considered to be a Transaction
/** @phpstan-ignore-next-line */
return $span->spanRecorder->getSpans()[0];
/** @var Transaction */
return $span->getSpanRecorder()->getSpans()[0];
}

return null;
Expand Down
27 changes: 22 additions & 5 deletions src/Tracing/SamplingContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ final class SamplingContext
private $transactionContext;

/**
* Returns the default instance of for the SamplingContext.
* @var bool|null Sampling decision from the parent transaction, if any
*/
private $parentSampled;

/**
* Returns an instance populated with the data of the transaction context.
*/
public static function getDefault(TransactionContext $transactionContext): self
{
$context = new SamplingContext();
$context->setTransactionContext($transactionContext);
$context = new self();
$context->transactionContext = $transactionContext;
$context->parentSampled = $transactionContext->getParentSampled();

return $context;
}
Expand All @@ -27,8 +33,19 @@ public function getTransactionContext(): ?TransactionContext
return $this->transactionContext;
}

public function setTransactionContext(?TransactionContext $transactionContext): void
/**
* Gets the sampling decision from the parent transaction, if any.
*/
public function getParentSampled(): ?bool
{
return $this->parentSampled;
}

/**
* Sets the sampling decision from the parent transaction, if any.
*/
public function setParentSampled(?bool $parentSampled): void
{
$this->transactionContext = $transactionContext;
$this->parentSampled = $parentSampled;
}
}
Loading