diff --git a/src/Event.php b/src/Event.php index 0148069ac..51f4563b2 100644 --- a/src/Event.php +++ b/src/Event.php @@ -19,6 +19,10 @@ * count: int, * tags: array, * } + * @phpstan-type SdkPackageEntry array{ + * name: string, + * version: string, + * } */ final class Event { @@ -174,6 +178,16 @@ final class Event */ private $sdkVersion = Client::SDK_VERSION; + /** + * @var SdkPackageEntry[] The Sentry SDK packages + */ + private $sdkPackages = [ + [ + 'name' => 'composer:sentry/sentry', + 'version' => Client::SDK_VERSION, + ], + ]; + /** * @var EventType The type of the Event */ @@ -276,6 +290,40 @@ public function setSdkVersion(string $sdkVersion): self return $this; } + /** + * Append a package to the list of SDK packages. + * + * @param SdkPackageEntry $package The package to append + * + * @return $this + * + * @internal + */ + public function appendSdkPackage(array $package): self + { + $this->sdkPackages[] = $package; + + return $this; + } + + /** + * Gets the SDK playload that will be sent to Sentry. + * + * @see https://develop.sentry.dev/sdk/data-model/event-payloads/sdk/ + * + * @return array{name: string, version: string, packages: SdkPackageEntry[]} + * + * @internal + */ + public function getSdkPayload(): array + { + return [ + 'name' => $this->sdkIdentifier, + 'version' => $this->sdkVersion, + 'packages' => $this->sdkPackages, + ]; + } + /** * Gets the timestamp of when this event was generated. */ diff --git a/src/Serializer/EnvelopItems/EventItem.php b/src/Serializer/EnvelopItems/EventItem.php index dd37f70ff..ca6d1d38b 100644 --- a/src/Serializer/EnvelopItems/EventItem.php +++ b/src/Serializer/EnvelopItems/EventItem.php @@ -28,10 +28,7 @@ public static function toEnvelopeItem(Event $event): string $payload = [ 'timestamp' => $event->getTimestamp(), 'platform' => 'php', - 'sdk' => [ - 'name' => $event->getSdkIdentifier(), - 'version' => $event->getSdkVersion(), - ], + 'sdk' => $event->getSdkPayload(), ]; if ($event->getStartTimestamp() !== null) { diff --git a/src/Serializer/EnvelopItems/TransactionItem.php b/src/Serializer/EnvelopItems/TransactionItem.php index de6fd624a..679bd6bcd 100644 --- a/src/Serializer/EnvelopItems/TransactionItem.php +++ b/src/Serializer/EnvelopItems/TransactionItem.php @@ -35,10 +35,7 @@ public static function toEnvelopeItem(Event $event): string $payload = [ 'timestamp' => $event->getTimestamp(), 'platform' => 'php', - 'sdk' => [ - 'name' => $event->getSdkIdentifier(), - 'version' => $event->getSdkVersion(), - ], + 'sdk' => $event->getSdkPayload(), ]; if ($event->getStartTimestamp() !== null) { diff --git a/src/Serializer/PayloadSerializer.php b/src/Serializer/PayloadSerializer.php index c109e0336..b836fe044 100644 --- a/src/Serializer/PayloadSerializer.php +++ b/src/Serializer/PayloadSerializer.php @@ -42,10 +42,7 @@ public function serialize(Event $event): string 'event_id' => (string) $event->getId(), 'sent_at' => gmdate('Y-m-d\TH:i:s\Z'), 'dsn' => (string) $this->options->getDsn(), - 'sdk' => [ - 'name' => $event->getSdkIdentifier(), - 'version' => $event->getSdkVersion(), - ], + 'sdk' => $event->getSdkPayload(), ]; $dynamicSamplingContext = $event->getSdkMetadata('dynamic_sampling_context'); diff --git a/tests/Serializer/PayloadSerializerTest.php b/tests/Serializer/PayloadSerializerTest.php index c9283825d..1e8eca0fe 100644 --- a/tests/Serializer/PayloadSerializerTest.php +++ b/tests/Serializer/PayloadSerializerTest.php @@ -63,9 +63,9 @@ public static function serializeAsEnvelopeDataProvider(): iterable yield [ Event::createEvent(new EventId('fc9442f5aef34234bb22b9a615e30ccd')), <<\/","server_name":"foo.example.com","release":"721e41770371db95eee98ca2707686226b993eda","environment":"production","fingerprint":["myrpc","POST","\/foo.bar"],"modules":{"my.module.name":"1.0"},"extra":{"my_key":1,"some_other_value":"foo bar"},"tags":{"ios_version":"4.0","context":"production"},"user":{"id":"unique_id","username":"my_user","email":"foo@example.com","ip_address":"127.0.0.1","segment":"my_segment"},"contexts":{"os":{"name":"Linux","version":"4.19.104-microsoft-standard","build":"#1 SMP Wed Feb 19 06:37:35 UTC 2020","kernel_version":"Linux 7944782cd697 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64"},"runtime":{"name":"php","sapi":"cli","version":"7.4.3"},"electron":{"type":"runtime","name":"Electron","version":"4.0"}},"breadcrumbs":{"values":[{"type":"user","category":"log","level":"info","timestamp":1597790835},{"type":"navigation","category":"log","level":"info","timestamp":1597790835,"data":{"from":"\/login","to":"\/dashboard"}},{"type":"default","category":"log","level":"info","timestamp":1597790835,"data":{"0":"foo","1":"bar"}}]},"request":{"method":"POST","url":"http:\/\/absolute.uri\/foo","query_string":"query=foobar&page=2","data":{"foo":"bar"},"cookies":{"PHPSESSID":"298zf09hf012fh2"},"headers":{"content-type":"text\/html"},"env":{"REMOTE_ADDR":"127.0.0.1"}},"exception":{"values":[{"type":"Exception","value":"chained exception","stacktrace":{"frames":[{"filename":"file\/name.py","lineno":3,"in_app":true},{"filename":"file\/name.py","lineno":3,"in_app":false,"abs_path":"absolute\/file\/name.py","function":"myfunction","raw_function":"raw_function_name","pre_context":["def foo():"," my_var = 'foo'"],"context_line":" raise ValueError()","post_context":["","def main():"],"vars":{"my_var":"value"}}]},"mechanism":{"type":"generic","handled":true,"data":{"code":123}}},{"type":"Exception","value":"initial exception"}]}} +{"timestamp":1597790835,"platform":"php","sdk":{"name":"sentry.php","version":"$sdkVersion","packages":[{"name":"composer:sentry\/sentry","version":"$sdkVersion"}]},"start_timestamp":1597790835,"level":"error","logger":"app.php","transaction":"\/users\/\/","server_name":"foo.example.com","release":"721e41770371db95eee98ca2707686226b993eda","environment":"production","fingerprint":["myrpc","POST","\/foo.bar"],"modules":{"my.module.name":"1.0"},"extra":{"my_key":1,"some_other_value":"foo bar"},"tags":{"ios_version":"4.0","context":"production"},"user":{"id":"unique_id","username":"my_user","email":"foo@example.com","ip_address":"127.0.0.1","segment":"my_segment"},"contexts":{"os":{"name":"Linux","version":"4.19.104-microsoft-standard","build":"#1 SMP Wed Feb 19 06:37:35 UTC 2020","kernel_version":"Linux 7944782cd697 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64"},"runtime":{"name":"php","sapi":"cli","version":"7.4.3"},"electron":{"type":"runtime","name":"Electron","version":"4.0"}},"breadcrumbs":{"values":[{"type":"user","category":"log","level":"info","timestamp":1597790835},{"type":"navigation","category":"log","level":"info","timestamp":1597790835,"data":{"from":"\/login","to":"\/dashboard"}},{"type":"default","category":"log","level":"info","timestamp":1597790835,"data":{"0":"foo","1":"bar"}}]},"request":{"method":"POST","url":"http:\/\/absolute.uri\/foo","query_string":"query=foobar&page=2","data":{"foo":"bar"},"cookies":{"PHPSESSID":"298zf09hf012fh2"},"headers":{"content-type":"text\/html"},"env":{"REMOTE_ADDR":"127.0.0.1"}},"exception":{"values":[{"type":"Exception","value":"chained exception","stacktrace":{"frames":[{"filename":"file\/name.py","lineno":3,"in_app":true},{"filename":"file\/name.py","lineno":3,"in_app":false,"abs_path":"absolute\/file\/name.py","function":"myfunction","raw_function":"raw_function_name","pre_context":["def foo():"," my_var = 'foo'"],"context_line":" raise ValueError()","post_context":["","def main():"],"vars":{"my_var":"value"}}]},"mechanism":{"type":"generic","handled":true,"data":{"code":123}}},{"type":"Exception","value":"initial exception"}]}} TEXT ]; @@ -181,9 +181,9 @@ public static function serializeAsEnvelopeDataProvider(): iterable yield [ $event, <<