Skip to content

Commit

Permalink
Implement Metrics::timing (#1670)
Browse files Browse the repository at this point in the history
Co-authored-by: Michi Hoffmann <cleptric@users.noreply.github.com>
  • Loading branch information
stayallive and cleptric authored Jan 9, 2024
1 parent 013b822 commit 65d9ff3
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 15 deletions.
47 changes: 39 additions & 8 deletions src/Metrics/Metrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public static function getInstance(): self
}

/**
* @param int|float $value
* @param string[] $tags
* @param int|float $value
* @param array<string, string> $tags
*/
public function increment(
string $key,
Expand All @@ -60,8 +60,8 @@ public function increment(
}

/**
* @param int|float $value
* @param string[] $tags
* @param int|float $value
* @param array<string, string> $tags
*/
public function distribution(
string $key,
Expand All @@ -83,8 +83,8 @@ public function distribution(
}

/**
* @param int|float $value
* @param string[] $tags
* @param int|float $value
* @param array<string, string> $tags
*/
public function gauge(
string $key,
Expand All @@ -106,8 +106,8 @@ public function gauge(
}

/**
* @param int|string $value
* @param string[] $tags
* @param int|string $value
* @param array<string, string> $tags
*/
public function set(
string $key,
Expand All @@ -128,6 +128,37 @@ public function set(
);
}

/**
* @template T
*
* @param callable(): T $callable
* @param array<string, string> $tags
*
* @return T
*/
public function timing(
string $key,
callable $callable,
array $tags = [],
int $stackLevel = 0
) {
$startTimestamp = microtime(true);

$result = $callable();

$this->aggregator->add(
DistributionType::TYPE,
$key,
microtime(true) - $startTimestamp,
MetricsUnit::second(),
$tags,
(int) $startTimestamp,
$stackLevel
);

return $result;
}

public function flush(): ?EventId
{
return $this->aggregator->flush();
Expand Down
8 changes: 4 additions & 4 deletions src/Metrics/MetricsAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ final class MetricsAggregator
];

/**
* @param string[] $tags
* @param int|float|string $value
* @param array<string, string> $tags
* @param int|float|string $value
*/
public function add(
string $type,
Expand Down Expand Up @@ -114,9 +114,9 @@ public function flush(): ?EventId
}

/**
* @param string[] $tags
* @param array<string, string> $tags
*
* @return string[]
* @return array<string, string>
*/
private function serializeTags(array $tags): array
{
Expand Down
6 changes: 3 additions & 3 deletions src/Metrics/Types/AbstractType.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class AbstractType
private $unit;

/**
* @var string[]
* @var array<string, string>
*/
private $tags;

Expand All @@ -41,7 +41,7 @@ abstract class AbstractType
private $codeLocation;

/**
* @param string[] $tags
* @param array<string, string> $tags
*/
public function __construct(string $key, MetricsUnit $unit, array $tags, int $timestamp)
{
Expand Down Expand Up @@ -71,7 +71,7 @@ public function getUnit(): MetricsUnit
}

/**
* @return string[]
* @return array<string, string>
*/
public function getTags(): array
{
Expand Down
74 changes: 74 additions & 0 deletions tests/Metrics/MetricsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,80 @@ public function testDistribution(): void
metrics()->flush();
}

public function testTiming(): void
{
ClockMock::withClockMock(1699412953);

/** @var ClientInterface&MockObject $client */
$client = $this->createMock(ClientInterface::class);
$client->expects($this->any())
->method('getOptions')
->willReturn(new Options([
'release' => '1.0.0',
'environment' => 'development',
'attach_metric_code_locations' => true,
]));

$self = $this;

$client->expects($this->once())
->method('captureEvent')
->with($this->callback(static function (Event $event) use ($self): bool {
$metric = $event->getMetrics()['8a817dcdb12cfffc1fa8b459ad0c9d56'];

$self->assertSame(DistributionType::TYPE, $metric->getType());
$self->assertSame('foo', $metric->getKey());
$self->assertSame([1.0, 2.0], $metric->serialize());
$self->assertSame(MetricsUnit::second(), $metric->getUnit());
$self->assertSame(
[
'environment' => 'development',
'foo' => 'bar',
'release' => '1.0.0',
],
$metric->getTags()
);
$self->assertSame(1699412953, $metric->getTimestamp());

$codeLocation = $metric->getCodeLocation();

$self->assertSame('Sentry\Metrics\Metrics::timing', $codeLocation->getFunctionName());

return true;
}));

$hub = new Hub($client);
SentrySdk::setCurrentHub($hub);

$firstTimingResult = metrics()->timing(
'foo',
static function () {
// Move the clock forward 1 second
ClockMock::withClockMock(1699412954);

return '1second';
},
['foo' => 'bar']
);

$this->assertEquals('1second', $firstTimingResult);

ClockMock::withClockMock(1699412953);

$secondTimingResult = metrics()->timing(
'foo',
static function () {
// Move the clock forward 2 seconds
ClockMock::withClockMock(1699412955);
},
['foo' => 'bar']
);

$this->assertNull($secondTimingResult);

metrics()->flush();
}

public function testGauge(): void
{
ClockMock::withClockMock(1699412953);
Expand Down

0 comments on commit 65d9ff3

Please sign in to comment.