Skip to content

Commit

Permalink
Attach _metrics_summary to transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
cleptric committed Feb 13, 2024
1 parent 2c1f5dd commit 647a60d
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 11 deletions.
31 changes: 30 additions & 1 deletion src/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
/**
* This is the base class for classes containing event data.
*
* @author Stefano Arlandini <sarlandini@alice.it>
* @phpstan-type MetricsSummary array{
* min: int|float,
* max: int|float,
* sum: int|float,
* count: int,
* tags: array<string>,
* }
*/
final class Event
{
Expand Down Expand Up @@ -61,6 +67,11 @@ final class Event
*/
private $metrics = [];

/**
* @var array<string, array<string, MetricsSummary>>
*/
private $metricsSummary = [];

/**
* @var string|null The name of the server (e.g. the host name)
*/
Expand Down Expand Up @@ -383,6 +394,24 @@ public function setMetrics(array $metrics): self
return $this;
}

/**
* @return array<string, array<string, MetricsSummary>>
*/
public function getMetricsSummary(): array
{
return $this->metricsSummary;
}

/**
* @param array<string, array<string, MetricsSummary>> $metricsSummary
*/
public function setMetricsSummary(array $metricsSummary): self
{
$this->metricsSummary = $metricsSummary;

return $this;
}

/**
* Gets the name of the server.
*/
Expand Down
40 changes: 31 additions & 9 deletions src/Serializer/EnvelopItems/TransactionItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@

/**
* @internal
*
* @phpstan-type MetricsSummary array{
* min: int|float,
* max: int|float,
* sum: int|float,
* count: int,
* tags: array<string>,
* }
*/
class TransactionItem implements EnvelopeItemInterface
{
Expand Down Expand Up @@ -117,6 +125,10 @@ public static function toEnvelopeItem(Event $event): string

$payload['spans'] = array_values(array_map([self::class, 'serializeSpan'], $event->getSpans()));

if (!empty($event->getMetricsSummary())) {
$payload['_metrics_summary'] = self::serializeMetricsSummary($event->getMetricsSummary());
}

$transactionMetadata = $event->getSdkMetadata('transaction_metadata');
if ($transactionMetadata instanceof TransactionMetadata) {
$payload['transaction_info']['source'] = (string) $transactionMetadata->getSource();
Expand All @@ -139,6 +151,7 @@ public static function toEnvelopeItem(Event $event): string
* op?: string,
* data?: array<string, mixed>,
* tags?: array<string, string>
* _metrics_summary?: array<string, mixed>
* }
*/
protected static function serializeSpan(Span $span): array
Expand Down Expand Up @@ -178,18 +191,27 @@ protected static function serializeSpan(Span $span): array
}

if (!empty($span->getMetricsSummary())) {
$formattedSummary = [];
$summary = $span->getMetricsSummary();
$result['_metrics_summary'] = self::serializeMetricsSummary($span->getMetricsSummary());
}

foreach ($summary as $mri => $metrics) {
foreach ($metrics as $metric) {
$formattedSummary[$mri][] = $metric;
}
}
return $result;
}

/**
* @param array<string, array<string, MetricsSummary>> $metricsSummary
*
* @return array<string, mixed>
*/
protected static function serializeMetricsSummary(array $metricsSummary): array
{
$formattedSummary = [];

$result['_metrics_summary'] = $formattedSummary;
foreach ($metricsSummary as $mri => $metrics) {
foreach ($metrics as $metric) {
$formattedSummary[$mri][] = $metric;
}
}

return $result;
return $formattedSummary;
}
}
4 changes: 4 additions & 0 deletions src/Tracing/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ public function finish(?float $endTimestamp = null): ?EventId
}
}

if (!empty($this->getMetricsSummary())) {
$event->setMetricsSummary($this->getMetricsSummary());
}

return $this->hub->captureEvent($event);
}
}
103 changes: 103 additions & 0 deletions tests/Metrics/MetricsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Sentry\Options;
use Sentry\SentrySdk;
use Sentry\State\Hub;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\TransactionContext;
use Symfony\Bridge\PhpUnit\ClockMock;

use function Sentry\metrics;
Expand Down Expand Up @@ -355,4 +357,105 @@ public function testSet(): void

metrics()->flush();
}

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

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

$self = $this;

$client->expects($this->once())
->method('captureEvent')
->with($this->callback(static function (Event $event) use ($self): bool {
$self->assertSame(
[
'c:foo@second' => [
'c:foo@seconda:4:{s:11:"environment";s:11:"development";s:3:"foo";s:3:"bar";s:7:"release";s:5:"1.0.0";s:11:"transaction";s:12:"GET /metrics";}' => [
'min' => 1.0,
'max' => 1.0,
'sum' => 1.0,
'count' => 1,
'tags' => [
'environment' => 'development',
'foo' => 'bar',
'release' => '1.0.0',
'transaction' => 'GET /metrics',
],
],
],
],
$event->getMetricsSummary(),
);

$self->assertSame(
[
'c:foo@second' => [
'c:foo@seconda:4:{s:11:"environment";s:11:"development";s:3:"foo";s:3:"bar";s:7:"release";s:5:"1.0.0";s:11:"transaction";s:12:"GET /metrics";}' => [
'min' => 1.0,
'max' => 1.0,
'sum' => 2.0,
'count' => 2,
'tags' => [
'environment' => 'development',
'foo' => 'bar',
'release' => '1.0.0',
'transaction' => 'GET /metrics',
],
],
],
],
$event->getSpans()[0]->getMetricsSummary(),
);

return true;
}));

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

$transactionContext = TransactionContext::make()
->setName('GET /metrics')
->setOp('http.server');
$transaction = $hub->startTransaction($transactionContext);
$hub->setSpan($transaction);

metrics()->increment(
'foo',
1,
MetricsUnit::second(),
['foo' => 'bar']
);

$spanContext = SpanContext::make()
->setOp('function');
$span = $transaction->startChild($spanContext);
$hub->setSpan($span);

metrics()->increment(
'foo',
1,
MetricsUnit::second(),
['foo' => 'bar']
);

metrics()->increment(
'foo',
1,
MetricsUnit::second(),
['foo' => 'bar']
);

$span->finish();
$transaction->finish();
}
}
15 changes: 14 additions & 1 deletion tests/Serializer/PayloadSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -472,13 +472,26 @@ public static function serializeAsEnvelopeDataProvider(): iterable
'trace_id' => '21160e9b836d479f81611368b2aa3d2c',
'span_id' => '5dd538dc297544cc',
]);
$event->setMetricsSummary([
'c:counter@star' => [
'c:counter@stara:0:{s:10:"repository";s:6:"client";}' => [
'min' => 1,
'max' => 1,
'sum' => 1,
'count' => 1,
'tags' => [
'repository' => 'client',
],
],
],
]);

yield [
$event,
<<<TEXT
{"event_id":"fc9442f5aef34234bb22b9a615e30ccd","sent_at":"2020-08-18T22:47:15Z","dsn":"http:\/\/public@example.com\/sentry\/1","sdk":{"name":"sentry.php","version":"$sdkVersion"}}
{"type":"transaction","content_type":"application\/json"}
{"timestamp":1597790835,"platform":"php","sdk":{"name":"sentry.php","version":"$sdkVersion"},"transaction":"GET \/","contexts":{"trace":{"trace_id":"21160e9b836d479f81611368b2aa3d2c","span_id":"5dd538dc297544cc"}},"spans":[{"span_id":"5dd538dc297544cc","trace_id":"21160e9b836d479f81611368b2aa3d2c","start_timestamp":1597790835,"_metrics_summary":{"c:counter@star":[{"min":10,"max":50,"sum":60,"count":2,"tags":{"repository":"client"}}]}}]}
{"timestamp":1597790835,"platform":"php","sdk":{"name":"sentry.php","version":"$sdkVersion"},"transaction":"GET \/","contexts":{"trace":{"trace_id":"21160e9b836d479f81611368b2aa3d2c","span_id":"5dd538dc297544cc"}},"spans":[{"span_id":"5dd538dc297544cc","trace_id":"21160e9b836d479f81611368b2aa3d2c","start_timestamp":1597790835,"_metrics_summary":{"c:counter@star":[{"min":10,"max":50,"sum":60,"count":2,"tags":{"repository":"client"}}]}}],"_metrics_summary":{"c:counter@star":[{"min":1,"max":1,"sum":1,"count":1,"tags":{"repository":"client"}}]}}
TEXT
,
];
Expand Down

0 comments on commit 647a60d

Please sign in to comment.