diff --git a/src/Instrumentation/PDO/composer.json b/src/Instrumentation/PDO/composer.json index 36025ebb..501947f2 100644 --- a/src/Instrumentation/PDO/composer.json +++ b/src/Instrumentation/PDO/composer.json @@ -13,7 +13,11 @@ "ext-pdo": "*", "ext-opentelemetry": "*", "open-telemetry/api": "^1.0", - "open-telemetry/sem-conv": "^1.24" + "open-telemetry/sem-conv": "^1.24", + "symfony/polyfill-mbstring": "^1.31" + }, + "suggest": { + "ext-mbstring": "For better performance than symfony/polyfill-mbstring" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3", diff --git a/src/Instrumentation/PDO/src/PDOInstrumentation.php b/src/Instrumentation/PDO/src/PDOInstrumentation.php index 16ae59ee..312c3104 100644 --- a/src/Instrumentation/PDO/src/PDOInstrumentation.php +++ b/src/Instrumentation/PDO/src/PDOInstrumentation.php @@ -70,7 +70,7 @@ public static function register(): void $builder = self::makeBuilder($instrumentation, 'PDO::query', $function, $class, $filename, $lineno) ->setSpanKind(SpanKind::KIND_CLIENT); if ($class === PDO::class) { - $builder->setAttribute(TraceAttributes::DB_STATEMENT, $params[0] ?? 'undefined'); + $builder->setAttribute(TraceAttributes::DB_STATEMENT, mb_convert_encoding($params[0] ?? 'undefined', 'UTF-8')); } $parent = Context::getCurrent(); $span = $builder->startSpan(); @@ -93,7 +93,7 @@ public static function register(): void $builder = self::makeBuilder($instrumentation, 'PDO::exec', $function, $class, $filename, $lineno) ->setSpanKind(SpanKind::KIND_CLIENT); if ($class === PDO::class) { - $builder->setAttribute(TraceAttributes::DB_STATEMENT, $params[0] ?? 'undefined'); + $builder->setAttribute(TraceAttributes::DB_STATEMENT, mb_convert_encoding($params[0] ?? 'undefined', 'UTF-8')); } $parent = Context::getCurrent(); $span = $builder->startSpan(); @@ -116,7 +116,7 @@ public static function register(): void $builder = self::makeBuilder($instrumentation, 'PDO::prepare', $function, $class, $filename, $lineno) ->setSpanKind(SpanKind::KIND_CLIENT); if ($class === PDO::class) { - $builder->setAttribute(TraceAttributes::DB_STATEMENT, $params[0] ?? 'undefined'); + $builder->setAttribute(TraceAttributes::DB_STATEMENT, mb_convert_encoding($params[0] ?? 'undefined', 'UTF-8')); } $parent = Context::getCurrent(); $span = $builder->startSpan(); diff --git a/src/Instrumentation/PDO/tests/Integration/PDOInstrumentationTest.php b/src/Instrumentation/PDO/tests/Integration/PDOInstrumentationTest.php index 2fb65d95..3fcd1b3c 100644 --- a/src/Instrumentation/PDO/tests/Integration/PDOInstrumentationTest.php +++ b/src/Instrumentation/PDO/tests/Integration/PDOInstrumentationTest.php @@ -187,4 +187,31 @@ public function test_execute_and_fetch_all_spans_linked_to_prepared_statement_sp $this->assertCount(1, $fetchAllSpan->getLinks()); $this->assertEquals($prepareSpan->getContext(), $fetchAllSpan->getLinks()[0]->getSpanContext()); } + + /** + * Tests that the db statement is encoded as UTF-8, this is relevant for grpc exporter which expects UTF-8 encoding. + */ + public function test_encode_db_statement_as_utf8(): void + { + //setup + $db = self::createDB(); + $db->exec($this->fillDB()); + + $non_utf8_id = mb_convert_encoding('rückwärts', 'ISO-8859-1', 'UTF-8'); + + $db->prepare("SELECT id FROM technology WHERE id = '{$non_utf8_id}'"); + $span_db_prepare = $this->storage->offsetGet(2); + $this->assertTrue(mb_check_encoding($span_db_prepare->getAttributes()->get(TraceAttributes::DB_STATEMENT), 'UTF-8')); + $this->assertCount(3, $this->storage); + + $db->query("SELECT id FROM technology WHERE id = '{$non_utf8_id}'"); + $span_db_query = $this->storage->offsetGet(3); + $this->assertTrue(mb_check_encoding($span_db_query->getAttributes()->get(TraceAttributes::DB_STATEMENT), 'UTF-8')); + $this->assertCount(4, $this->storage); + + $db->exec("SELECT id FROM technology WHERE id = '{$non_utf8_id}'"); + $span_db_exec = $this->storage->offsetGet(4); + $this->assertTrue(mb_check_encoding($span_db_exec->getAttributes()->get(TraceAttributes::DB_STATEMENT), 'UTF-8')); + $this->assertCount(5, $this->storage); + } }