1010 * Only spans with errors are sent. Non-error spans are silently skipped.
1111 * Use the Stdout exporter for non-error spans.
1212 */
13- class Sentry implements Exporter
13+ readonly class Sentry implements Exporter
1414{
15- private string $ dsn ;
1615 private string $ endpoint ;
1716 private string $ publicKey ;
1817 private string $ projectId ;
19- private ?string $ environment ;
2018
2119 /**
2220 * Create a new Sentry exporter.
2321 *
2422 * @param string $dsn Sentry DSN (e.g., https://key@sentry.io/123)
2523 * @param string|null $environment Optional environment name (e.g., 'production')
24+ * @param string|null $release Optional release/version identifier (e.g., commit hash)
25+ * @param string|null $serverName Optional server name/identifier
2626 */
27- public function __construct (string $ dsn , ?string $ environment = null )
28- {
29- $ this ->dsn = $ dsn ;
30- $ this ->environment = $ environment ;
31- $ this ->parseDsn ($ dsn );
32- }
33-
34- private function parseDsn (string $ dsn ): void
35- {
27+ public function __construct (
28+ private string $ dsn ,
29+ private ?string $ environment = null ,
30+ private ?string $ release = null ,
31+ private ?string $ serverName = null
32+ ) {
3633 $ parsed = parse_url ($ dsn );
3734
3835 if ($ parsed === false ) {
@@ -94,7 +91,7 @@ private function buildEnvelope(Span $span): ?string
9491 {
9592 $ error = $ span ->getError ();
9693
97- if ($ error === null ) {
94+ if (! $ error instanceof \Throwable ) {
9895 return null ;
9996 }
10097
@@ -103,6 +100,7 @@ private function buildEnvelope(Span $span): ?string
103100 $ traceId = (string ) ($ attributes ['span.trace_id ' ] ?? '' );
104101 $ spanId = (string ) ($ attributes ['span.id ' ] ?? '' );
105102 $ parentId = $ attributes ['span.parent_id ' ] ?? null ;
103+ $ startedAt = (float ) ($ attributes ['span.started_at ' ] ?? microtime (true ));
106104 $ finishedAt = (float ) ($ attributes ['span.finished_at ' ] ?? microtime (true ));
107105 $ action = $ span ->getAction ();
108106
@@ -151,11 +149,18 @@ private function buildEnvelope(Span $span): ?string
151149 $ payloadData = [
152150 'level ' => 'error ' ,
153151 'platform ' => 'php ' ,
152+ 'sdk ' => ['name ' => 'utopia-php/span ' ],
153+ 'start_timestamp ' => $ startedAt ,
154154 'timestamp ' => $ finishedAt ,
155155 'transaction ' => $ action ,
156156 'message ' => $ error ->getMessage (),
157157 'contexts ' => [
158158 'trace ' => $ traceContext ,
159+ 'runtime ' => [
160+ 'name ' => 'php ' ,
161+ 'version ' => PHP_VERSION ,
162+ 'sapi ' => PHP_SAPI ,
163+ ],
159164 ],
160165 'exception ' => [
161166 'values ' => [[
@@ -171,6 +176,14 @@ private function buildEnvelope(Span $span): ?string
171176 $ payloadData ['environment ' ] = $ this ->environment ;
172177 }
173178
179+ if ($ this ->release !== null ) {
180+ $ payloadData ['release ' ] = $ this ->release ;
181+ }
182+
183+ if ($ this ->serverName !== null ) {
184+ $ payloadData ['server_name ' ] = $ this ->serverName ;
185+ }
186+
174187 $ payload = json_encode ($ payloadData );
175188
176189 if ($ header === false || $ itemHeader === false || $ payload === false ) {
0 commit comments