Skip to content

Commit ca8d1dc

Browse files
committed
Added first test, fixed style and static analysis bugs
1 parent f223b7f commit ca8d1dc

File tree

6 files changed

+85
-7
lines changed

6 files changed

+85
-7
lines changed

.github/workflows/php.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ jobs:
139139
with:
140140
php-version: ${{ matrix.php-version }}
141141
coverage: xdebug
142-
extensions: ast, amqp, grpc, opentelemetry, rdkafka
142+
extensions: ast, amqp, grpc, opentelemetry, rdkafka, mysqli
143143

144144
- name: Validate composer.json and composer.lock
145145
run: composer validate
@@ -199,6 +199,11 @@ jobs:
199199
run: |
200200
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:29092,PLAINTEXT_HOST://localhost:9092 docker compose up kafka -d --wait
201201
202+
- name: Start Mysql
203+
if: ${{ matrix.project == 'Instrumentation/MySqli' }}
204+
run: |
205+
docker compose up mysql -d --wait
206+
202207
- name: Run PHPUnit
203208
working-directory: src/${{ matrix.project }}
204209
run: vendor/bin/phpunit

docker-compose.yaml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ services:
1414
PHP_IDE_CONFIG: ${PHP_IDE_CONFIG:-''}
1515
RABBIT_HOST: ${RABBIT_HOST:-rabbitmq}
1616
KAFKA_HOST: ${KAFKA_HOST:-kafka}
17+
MYSQL_HOST: ${MYSQL_HOST:-mysql}
18+
1719

1820
zipkin:
1921
image: openzipkin/zipkin-slim
@@ -61,4 +63,20 @@ services:
6163
volumes:
6264
- ./docker/kafka/update_run.sh:/tmp/update_run.sh
6365

64-
66+
mysql:
67+
image: mysql:8.0
68+
hostname: mysql
69+
ports:
70+
- "3306:3306/tcp"
71+
environment:
72+
MYSQL_ROOT_PASSWORD: root_password
73+
MYSQL_DATABASE: otel_db
74+
MYSQL_USER: otel_user
75+
MYSQL_PASSWORD: otel_passwd
76+
healthcheck:
77+
test: mysql -uotel_user -potel_passwd -e "USE otel_db;"
78+
interval: 30s
79+
timeout: 30s
80+
retries: 3
81+
volumes:
82+
- ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql

docker/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ RUN install-php-extensions \
77
opentelemetry \
88
mongodb \
99
amqp \
10-
rdkafka
10+
rdkafka \
11+
mysqli
1112

1213
USER php

src/Instrumentation/MySqli/src/MySqliInstrumentation.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,10 @@ public static function register(): void
338338
//TODO test to https://www.php.net/manual/en/mysqli.begin-transaction.php
339339
}
340340

341+
/** @param non-empty-string $spanName */
341342
private static function constructPreHook(string $spanName, int $paramsOffset, CachedInstrumentation $instrumentation, MySqliTracker $tracker, $obj, array $params, ?string $class, ?string $function, ?string $filename, ?int $lineno): void
342343
{
344+
$attributes = [];
343345
$attributes[TraceAttributes::SERVER_ADDRESS] = $params[$paramsOffset + 0] ?? get_cfg_var('mysqli.default_host');
344346
$attributes[TraceAttributes::SERVER_PORT] = $params[$paramsOffset + 4] ?? get_cfg_var('mysqli.default_port');
345347
$attributes[TraceAttributes::DB_USER] = $params[$paramsOffset + 1] ?? get_cfg_var('mysqli.default_user');
@@ -370,6 +372,7 @@ private static function constructPostHook(int $paramsOffset, CachedInstrumentati
370372

371373
}
372374

375+
/** @param non-empty-string $spanName */
373376
private static function queryPreHook(string $spanName, CachedInstrumentation $instrumentation, MySqliTracker $tracker, $obj, array $params, ?string $class, ?string $function, ?string $filename, ?int $lineno): void
374377
{
375378
self::startSpan($spanName, $instrumentation, $class, $function, $filename, $lineno, []);
@@ -421,6 +424,7 @@ private static function multiQueryPostHook(CachedInstrumentation $instrumentatio
421424

422425
}
423426

427+
/** @param non-empty-string $spanName */
424428
private static function nextResultPreHook(string $spanName, CachedInstrumentation $instrumentation, MySqliTracker $tracker, $obj, array $params, ?string $class, ?string $function, ?string $filename, ?int $lineno): void
425429
{
426430
$span = self::startSpan($spanName, $instrumentation, $class, $function, $filename, $lineno, []);
@@ -545,6 +549,7 @@ private static function stmtConstructPostHook(CachedInstrumentation $instrumenta
545549
}
546550
}
547551

552+
/** @param non-empty-string $spanName */
548553
private static function stmtExecutePreHook(string $spanName, CachedInstrumentation $instrumentation, MySqliTracker $tracker, $obj, array $params, ?string $class, ?string $function, ?string $filename, ?int $lineno): void
549554
{
550555
self::startSpan($spanName, $instrumentation, $class, $function, $filename, $lineno, []);
@@ -568,6 +573,7 @@ private static function stmtExecutePostHook(CachedInstrumentation $instrumentati
568573

569574
}
570575

576+
/** @param non-empty-string $spanName */
571577
private static function stmtNextResultPreHook(string $spanName, CachedInstrumentation $instrumentation, MySqliTracker $tracker, $obj, array $params, ?string $class, ?string $function, ?string $filename, ?int $lineno): void
572578
{
573579
$span = self::startSpan($spanName, $instrumentation, $class, $function, $filename, $lineno, []);
@@ -603,6 +609,7 @@ private static function stmtNextResultPostHook(CachedInstrumentation $instrument
603609
self::endSpan($attributes, $exception, $errorStatus);
604610
}
605611

612+
/** @param non-empty-string $spanName */
606613
private static function startSpan(string $spanName, CachedInstrumentation $instrumentation, ?string $class, ?string $function, ?string $filename, ?int $lineno, iterable $attributes) : SpanInterface
607614
{
608615
$parent = Context::getCurrent();
@@ -624,7 +631,7 @@ private static function startSpan(string $spanName, CachedInstrumentation $instr
624631
return $span;
625632
}
626633

627-
private static function endSpan(array $attributes, ?\Throwable $exception, ?string $errorStatus)
634+
private static function endSpan(iterable $attributes, ?\Throwable $exception, ?string $errorStatus)
628635
{
629636
$scope = Context::storage()->scope();
630637
if (!$scope) {
@@ -661,6 +668,7 @@ private static function dropSpan()
661668
private static function extractQueryCommand($query) : ?string
662669
{
663670
$query = preg_replace("/\r\n|\n\r|\r/", "\n", $query);
671+
/** @psalm-suppress PossiblyInvalidArgument */
664672
if (preg_match('/^\s*(?:--[^\n]*\n|\/\*[\s\S]*?\*\/\s*)*([a-zA-Z_][a-zA-Z0-9_]*)/i', $query, $matches)) {
665673
return strtoupper($matches[1]);
666674
}

src/Instrumentation/MySqli/src/MySqliTracker.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public function getNextMySqliMultiQuery(mysqli $mysqli) : ?string
4848

4949
public function storeMySqliAttributes(mysqli $mysqli, ?string $hostname = null, ?string $username = null, ?string $database = null, ?int $port = null, ?string $socket = null)
5050
{
51+
$attributes = [];
5152
$attributes[TraceAttributes::DB_SYSTEM] = 'mysql';
5253
$attributes[TraceAttributes::SERVER_ADDRESS] = $hostname ?? get_cfg_var('mysqli.default_host');
5354
$attributes[TraceAttributes::SERVER_PORT] = $port ?? get_cfg_var('mysqli.default_port');
@@ -66,7 +67,7 @@ public function addMySqliAttribute($mysqli, string $attribute, bool|int|float|st
6667
$this->mySqliToAttributes[$mysqli][$attribute] = $value;
6768
}
6869

69-
public function getMySqliAttributes(mysqli $mysqli) : iterable
70+
public function getMySqliAttributes(mysqli $mysqli) : array
7071
{
7172
return $this->mySqliToAttributes[$mysqli] ?? [];
7273
}
@@ -76,7 +77,7 @@ public function trackMySqliFromStatement(mysqli $mysqli, mysqli_stmt $mysqli_stm
7677
$this->statementToMySqli[$mysqli_stmt] = WeakReference::create($mysqli);
7778
}
7879

79-
public function getMySqliAttributesFromStatement(mysqli_stmt $stmt) : iterable
80+
public function getMySqliAttributesFromStatement(mysqli_stmt $stmt) : array
8081
{
8182
$mysqli = ($this->statementToMySqli[$stmt] ?? null)?->get();
8283
if (!$mysqli) {
@@ -94,7 +95,7 @@ public function addStatementAttribute(mysqli_stmt $stmt, string $attribute, bool
9495
$this->statementAttributes[$stmt][$attribute] = $value;
9596
}
9697

97-
public function getStatementAttributes(mysqli_stmt $stmt) : iterable
98+
public function getStatementAttributes(mysqli_stmt $stmt) : array
9899
{
99100
if (!$this->statementAttributes->offsetExists($stmt)) {
100101
return [];

src/Instrumentation/MySqli/tests/Integration/MySqliInstrumentationTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
namespace OpenTelemetry\Tests\Instrumentation\MySqli\Integration;
66

77
use ArrayObject;
8+
use mysqli;
89
use OpenTelemetry\API\Instrumentation\Configurator;
910
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
1011
use OpenTelemetry\Context\ScopeInterface;
1112
use OpenTelemetry\SDK\Trace\ImmutableSpan;
1213
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
1314
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
1415
use OpenTelemetry\SDK\Trace\TracerProvider;
16+
use OpenTelemetry\SemConv\TraceAttributes;
1517
use PHPUnit\Framework\TestCase;
1618

1719
class MySqliInstrumentationTest extends TestCase
@@ -20,6 +22,12 @@ class MySqliInstrumentationTest extends TestCase
2022
/** @var ArrayObject<int, ImmutableSpan> */
2123
private ArrayObject $storage;
2224

25+
private string $mysqlHost;
26+
27+
private string $user;
28+
private string $passwd;
29+
private string $database;
30+
2331
public function setUp(): void
2432
{
2533
$this->storage = new ArrayObject();
@@ -33,6 +41,12 @@ public function setUp(): void
3341
->withTracerProvider($tracerProvider)
3442
->withPropagator(TraceContextPropagator::getInstance())
3543
->activate();
44+
45+
$this->mysqlHost = getenv('MYSQL_HOST') ?: 'localhost';
46+
47+
$this->user = 'otel_user';
48+
$this->passwd = 'otel_passwd';
49+
$this->database = 'otel_db';
3650
}
3751

3852
public function tearDown(): void
@@ -42,6 +56,37 @@ public function tearDown(): void
4256

4357
public function test_mysqli_connect(): void
4458
{
59+
$mysqli = new mysqli($this->mysqlHost, $this->user, $this->passwd, $this->database);
60+
$mysqli->connect($this->mysqlHost, $this->user, $this->passwd, $this->database);
61+
mysqli_connect($this->mysqlHost, $this->user, $this->passwd, $this->database);
62+
63+
$mysqli->real_connect($this->mysqlHost, $this->user, $this->passwd, $this->database);
64+
mysqli_real_connect($mysqli, $this->mysqlHost, $this->user, $this->passwd, $this->database);
65+
66+
$this->assertCount(5, $this->storage);
67+
68+
$span = $this->storage->offsetGet(0);
69+
$this->assertSame('mysqli::__construct', $span->getName());
70+
71+
$span = $this->storage->offsetGet(1);
72+
$this->assertSame('mysqli::connect', $span->getName());
73+
74+
$span = $this->storage->offsetGet(2);
75+
$this->assertSame('mysqli_connect', $span->getName());
76+
77+
$span = $this->storage->offsetGet(3);
78+
$this->assertSame('mysqli::real_connect', $span->getName());
79+
80+
$span = $this->storage->offsetGet(4);
81+
$this->assertSame('mysqli_real_connect', $span->getName());
82+
83+
for ($i = 0; $i < 5; $i++) {
84+
$span = $this->storage->offsetGet($i);
85+
$this->assertEquals($this->mysqlHost, $span->getAttributes()->get(TraceAttributes::SERVER_ADDRESS));
86+
$this->assertEquals($this->user, $span->getAttributes()->get(TraceAttributes::DB_USER));
87+
$this->assertEquals($this->database, $span->getAttributes()->get(TraceAttributes::DB_NAMESPACE));
88+
$this->assertEquals('mysql', $span->getAttributes()->get(TraceAttributes::DB_SYSTEM));
89+
}
4590
}
4691

4792
// to be continued

0 commit comments

Comments
 (0)