@@ -59,25 +59,34 @@ public function trackedAttributesForStatement(PDOStatement $statement): iterable
5959
6060 /**
6161 * @param PDO $pdo
62+ * @param string $dsn
6263 * @return iterable<non-empty-string, bool|int|float|string|array|null>
6364 */
64- public function trackPdoAttributes (PDO $ pdo ): iterable
65+ public function trackPdoAttributes (PDO $ pdo, string $ dsn ): iterable
6566 {
66- $ attributes = [] ;
67+ $ attributes = self :: extractAttributesFromDSN ( $ dsn ) ;
6768
6869 try {
70+ /** @var string $dbSystem */
6971 $ dbSystem = $ pdo ->getAttribute (PDO ::ATTR_DRIVER_NAME );
70- /** @psalm-suppress PossiblyInvalidArgument */
72+ /** @psalm-suppress InvalidArrayAssignment */
7173 $ attributes [TraceAttributes::DB_SYSTEM ] = self ::mapDriverNameToAttribute ($ dbSystem );
7274 } catch (\Error ) {
7375 // if we catched an exception, the driver is likely not supporting the operation, default to "other"
76+ /** @psalm-suppress PossiblyInvalidArrayAssignment */
7477 $ attributes [TraceAttributes::DB_SYSTEM ] = 'other_sql ' ;
7578 }
7679
77- return $ this ->pdoToAttributesMap [$ pdo ] = $ attributes ;
80+ $ this ->pdoToAttributesMap [$ pdo ] = $ attributes ;
81+
82+ return $ attributes ;
7883 }
7984
80- public function trackedAttributesForPdo (PDO $ pdo )
85+ /**
86+ * @param PDO $pdo
87+ * @return iterable<non-empty-string, bool|int|float|string|array|null>
88+ */
89+ public function trackedAttributesForPdo (PDO $ pdo ): iterable
8190 {
8291 return $ this ->pdoToAttributesMap [$ pdo ] ?? [];
8392 }
@@ -106,4 +115,53 @@ private static function mapDriverNameToAttribute(?string $driverName): string
106115 default => 'other_sql ' ,
107116 };
108117 }
118+
119+ /**
120+ * Extracts attributes from a DSN string
121+ *
122+ * @param string $dsn
123+ * @return iterable<non-empty-string, bool|int|float|string|array|null>
124+ */
125+ private static function extractAttributesFromDSN (string $ dsn ): iterable
126+ {
127+ $ attributes = [];
128+ if (str_starts_with ($ dsn , 'sqlite::memory: ' )) {
129+ $ attributes [TraceAttributes::DB_SYSTEM ] = 'sqlite ' ;
130+ $ attributes [TraceAttributes::DB_NAME ] = 'memory ' ;
131+
132+ return $ attributes ;
133+ } elseif (str_starts_with ($ dsn , 'sqlite: ' )) {
134+ $ attributes [TraceAttributes::DB_SYSTEM ] = 'sqlite ' ;
135+ $ attributes [TraceAttributes::DB_NAME ] = substr ($ dsn , 7 );
136+
137+ return $ attributes ;
138+ } elseif (str_starts_with ($ dsn , 'sqlite ' )) {
139+ $ attributes [TraceAttributes::DB_SYSTEM ] = 'sqlite ' ;
140+ $ attributes [TraceAttributes::DB_NAME ] = $ dsn ;
141+
142+ return $ attributes ;
143+ }
144+
145+ if (preg_match ('/user=([^;]*)/ ' , $ dsn , $ matches )) {
146+ $ user = $ matches [1 ];
147+ if ($ user !== '' ) {
148+ $ attributes [TraceAttributes::DB_USER ] = $ user ;
149+ }
150+ }
151+ if (preg_match ('/host=([^;]*)/ ' , $ dsn , $ matches )) {
152+ $ host = $ matches [1 ];
153+ if ($ host !== '' ) {
154+ $ attributes [TraceAttributes::NET_PEER_NAME ] = $ host ;
155+ $ attributes [TraceAttributes::SERVER_ADDRESS ] = $ host ;
156+ }
157+ }
158+ if (preg_match ('/dbname=([^;]*)/ ' , $ dsn , $ matches )) {
159+ $ dbname = $ matches [1 ];
160+ if ($ dbname !== '' ) {
161+ $ attributes [TraceAttributes::DB_NAME ] = $ dbname ;
162+ }
163+ }
164+
165+ return $ attributes ;
166+ }
109167}
0 commit comments