Skip to content

Commit cde1d67

Browse files
authored
Attach _metrics_summary to transactions (#1702)
1 parent 74caa66 commit cde1d67

File tree

5 files changed

+182
-11
lines changed

5 files changed

+182
-11
lines changed

src/Event.php

+30-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313
/**
1414
* This is the base class for classes containing event data.
1515
*
16-
* @author Stefano Arlandini <[email protected]>
16+
* @phpstan-type MetricsSummary array{
17+
* min: int|float,
18+
* max: int|float,
19+
* sum: int|float,
20+
* count: int,
21+
* tags: array<string>,
22+
* }
1723
*/
1824
final class Event
1925
{
@@ -61,6 +67,11 @@ final class Event
6167
*/
6268
private $metrics = [];
6369

70+
/**
71+
* @var array<string, array<string, MetricsSummary>>
72+
*/
73+
private $metricsSummary = [];
74+
6475
/**
6576
* @var string|null The name of the server (e.g. the host name)
6677
*/
@@ -383,6 +394,24 @@ public function setMetrics(array $metrics): self
383394
return $this;
384395
}
385396

397+
/**
398+
* @return array<string, array<string, MetricsSummary>>
399+
*/
400+
public function getMetricsSummary(): array
401+
{
402+
return $this->metricsSummary;
403+
}
404+
405+
/**
406+
* @param array<string, array<string, MetricsSummary>> $metricsSummary
407+
*/
408+
public function setMetricsSummary(array $metricsSummary): self
409+
{
410+
$this->metricsSummary = $metricsSummary;
411+
412+
return $this;
413+
}
414+
386415
/**
387416
* Gets the name of the server.
388417
*/

src/Serializer/EnvelopItems/TransactionItem.php

+31-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212

1313
/**
1414
* @internal
15+
*
16+
* @phpstan-type MetricsSummary array{
17+
* min: int|float,
18+
* max: int|float,
19+
* sum: int|float,
20+
* count: int,
21+
* tags: array<string>,
22+
* }
1523
*/
1624
class TransactionItem implements EnvelopeItemInterface
1725
{
@@ -117,6 +125,10 @@ public static function toEnvelopeItem(Event $event): string
117125

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

128+
if (!empty($event->getMetricsSummary())) {
129+
$payload['_metrics_summary'] = self::serializeMetricsSummary($event->getMetricsSummary());
130+
}
131+
120132
$transactionMetadata = $event->getSdkMetadata('transaction_metadata');
121133
if ($transactionMetadata instanceof TransactionMetadata) {
122134
$payload['transaction_info']['source'] = (string) $transactionMetadata->getSource();
@@ -139,6 +151,7 @@ public static function toEnvelopeItem(Event $event): string
139151
* op?: string,
140152
* data?: array<string, mixed>,
141153
* tags?: array<string, string>
154+
* _metrics_summary?: array<string, mixed>
142155
* }
143156
*/
144157
protected static function serializeSpan(Span $span): array
@@ -178,18 +191,27 @@ protected static function serializeSpan(Span $span): array
178191
}
179192

180193
if (!empty($span->getMetricsSummary())) {
181-
$formattedSummary = [];
182-
$summary = $span->getMetricsSummary();
194+
$result['_metrics_summary'] = self::serializeMetricsSummary($span->getMetricsSummary());
195+
}
183196

184-
foreach ($summary as $mri => $metrics) {
185-
foreach ($metrics as $metric) {
186-
$formattedSummary[$mri][] = $metric;
187-
}
188-
}
197+
return $result;
198+
}
199+
200+
/**
201+
* @param array<string, array<string, MetricsSummary>> $metricsSummary
202+
*
203+
* @return array<string, mixed>
204+
*/
205+
protected static function serializeMetricsSummary(array $metricsSummary): array
206+
{
207+
$formattedSummary = [];
189208

190-
$result['_metrics_summary'] = $formattedSummary;
209+
foreach ($metricsSummary as $mri => $metrics) {
210+
foreach ($metrics as $metric) {
211+
$formattedSummary[$mri][] = $metric;
212+
}
191213
}
192214

193-
return $result;
215+
return $formattedSummary;
194216
}
195217
}

src/Tracing/Transaction.php

+4
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ public function finish(?float $endTimestamp = null): ?EventId
190190
}
191191
}
192192

193+
if (!empty($this->getMetricsSummary())) {
194+
$event->setMetricsSummary($this->getMetricsSummary());
195+
}
196+
193197
return $this->hub->captureEvent($event);
194198
}
195199
}

tests/Metrics/MetricsTest.php

+103
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use Sentry\Options;
1616
use Sentry\SentrySdk;
1717
use Sentry\State\Hub;
18+
use Sentry\Tracing\SpanContext;
19+
use Sentry\Tracing\TransactionContext;
1820
use Symfony\Bridge\PhpUnit\ClockMock;
1921

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

356358
metrics()->flush();
357359
}
360+
361+
public function testMetricsSummary(): void
362+
{
363+
ClockMock::withClockMock(1699412953);
364+
365+
/** @var ClientInterface&MockObject $client */
366+
$client = $this->createMock(ClientInterface::class);
367+
$client->expects($this->any())
368+
->method('getOptions')
369+
->willReturn(new Options([
370+
'enable_tracing' => true,
371+
'environment' => 'development',
372+
'release' => '1.0.0',
373+
]));
374+
375+
$self = $this;
376+
377+
$client->expects($this->once())
378+
->method('captureEvent')
379+
->with($this->callback(static function (Event $event) use ($self): bool {
380+
$self->assertSame(
381+
[
382+
'c:foo@second' => [
383+
'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";}' => [
384+
'min' => 1.0,
385+
'max' => 1.0,
386+
'sum' => 1.0,
387+
'count' => 1,
388+
'tags' => [
389+
'environment' => 'development',
390+
'foo' => 'bar',
391+
'release' => '1.0.0',
392+
'transaction' => 'GET /metrics',
393+
],
394+
],
395+
],
396+
],
397+
$event->getMetricsSummary()
398+
);
399+
400+
$self->assertSame(
401+
[
402+
'c:foo@second' => [
403+
'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";}' => [
404+
'min' => 1.0,
405+
'max' => 1.0,
406+
'sum' => 2.0,
407+
'count' => 2,
408+
'tags' => [
409+
'environment' => 'development',
410+
'foo' => 'bar',
411+
'release' => '1.0.0',
412+
'transaction' => 'GET /metrics',
413+
],
414+
],
415+
],
416+
],
417+
$event->getSpans()[0]->getMetricsSummary()
418+
);
419+
420+
return true;
421+
}));
422+
423+
$hub = new Hub($client);
424+
SentrySdk::setCurrentHub($hub);
425+
426+
$transactionContext = TransactionContext::make()
427+
->setName('GET /metrics')
428+
->setOp('http.server');
429+
$transaction = $hub->startTransaction($transactionContext);
430+
$hub->setSpan($transaction);
431+
432+
metrics()->increment(
433+
'foo',
434+
1,
435+
MetricsUnit::second(),
436+
['foo' => 'bar']
437+
);
438+
439+
$spanContext = SpanContext::make()
440+
->setOp('function');
441+
$span = $transaction->startChild($spanContext);
442+
$hub->setSpan($span);
443+
444+
metrics()->increment(
445+
'foo',
446+
1,
447+
MetricsUnit::second(),
448+
['foo' => 'bar']
449+
);
450+
451+
metrics()->increment(
452+
'foo',
453+
1,
454+
MetricsUnit::second(),
455+
['foo' => 'bar']
456+
);
457+
458+
$span->finish();
459+
$transaction->finish();
460+
}
358461
}

tests/Serializer/PayloadSerializerTest.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -472,13 +472,26 @@ public static function serializeAsEnvelopeDataProvider(): iterable
472472
'trace_id' => '21160e9b836d479f81611368b2aa3d2c',
473473
'span_id' => '5dd538dc297544cc',
474474
]);
475+
$event->setMetricsSummary([
476+
'c:counter@star' => [
477+
'c:counter@stara:0:{s:10:"repository";s:6:"client";}' => [
478+
'min' => 1,
479+
'max' => 1,
480+
'sum' => 1,
481+
'count' => 1,
482+
'tags' => [
483+
'repository' => 'client',
484+
],
485+
],
486+
],
487+
]);
475488

476489
yield [
477490
$event,
478491
<<<TEXT
479492
{"event_id":"fc9442f5aef34234bb22b9a615e30ccd","sent_at":"2020-08-18T22:47:15Z","dsn":"http:\/\/[email protected]\/sentry\/1","sdk":{"name":"sentry.php","version":"$sdkVersion"}}
480493
{"type":"transaction","content_type":"application\/json"}
481-
{"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"}}]}}]}
494+
{"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"}}]}}
482495
TEXT
483496
,
484497
];

0 commit comments

Comments
 (0)