Skip to content

Commit c22df17

Browse files
authored
feat: track dbname and other pdo attributes (#278)
1 parent 5db05ed commit c22df17

File tree

3 files changed

+75
-9
lines changed

3 files changed

+75
-9
lines changed

src/Instrumentation/PDO/src/PDOInstrumentation.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public static function register(): void
5353
}
5454
$span = Span::fromContext($scope->context());
5555

56-
$attributes = $pdoTracker->trackPdoAttributes($pdo);
56+
$dsn = $params[0] ?? '';
57+
58+
$attributes = $pdoTracker->trackPdoAttributes($pdo, $dsn);
5759
$span->setAttributes($attributes);
5860

5961
self::end($exception);

src/Instrumentation/PDO/src/PDOTracker.php

+63-5
Original file line numberDiff line numberDiff line change
@@ -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
}

src/Instrumentation/PDO/tests/Unit/PDOAttributeTrackerTest.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@
1111

1212
class PDOAttributeTrackerTest extends TestCase
1313
{
14-
public function testPdoCanBeTracked()
14+
public function testPdoCanBeTracked(): void
1515
{
16-
$pdo = new \PDO('sqlite::memory:');
16+
$dsn = 'sqlite::memory:';
17+
$pdo = new \PDO($dsn);
1718

1819
$objectMap = new PDOTracker();
19-
$objectMap->trackPdoAttributes($pdo);
20+
$objectMap->trackPdoAttributes($pdo, $dsn);
2021
$attributes = $objectMap->trackedAttributesForPdo($pdo);
2122
$span = Span::getInvalid();
2223

24+
/** @psalm-suppress InvalidArgument */
2325
$this->assertContains(TraceAttributes::DB_SYSTEM, array_keys($attributes));
26+
/** @psalm-suppress InvalidArgument */
27+
$this->assertContains(TraceAttributes::DB_NAME, array_keys($attributes));
28+
/** @psalm-suppress InvalidArrayAccess */
29+
$this->assertSame('memory', $attributes[TraceAttributes::DB_NAME]);
2430

2531
$stmt = $pdo->prepare('SELECT NULL LIMIT 0;');
2632
$objectMap->trackStatement($stmt, $pdo, $span->getContext());

0 commit comments

Comments
 (0)