From 1fdda35129ebb1c411eb4eb3c67a0dcf530f85b3 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 9 Nov 2022 14:28:35 +0200 Subject: [PATCH 1/5] feat(RelayOpenTelemetry): add db.statement attribute --- src/Psr/Tracing/RelayOpenTelemetry.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Psr/Tracing/RelayOpenTelemetry.php b/src/Psr/Tracing/RelayOpenTelemetry.php index ac3587a..5cb3c09 100644 --- a/src/Psr/Tracing/RelayOpenTelemetry.php +++ b/src/Psr/Tracing/RelayOpenTelemetry.php @@ -112,9 +112,13 @@ public function __call(string $name, array $arguments) return $this->relay->{$name}(...$arguments); } + $stmt = $name . ' ' . implode(' ', $arguments); + $stmt = substr($stmt, 0, 1000); + $span = $this->tracer->spanBuilder('Relay::' . strtolower($name)) ->setAttribute('db.operation', strtoupper($name)) ->setAttribute('db.system', 'redis') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); From 8e0d3ddbfb7188e63cf4673776b97ad72c93d291 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 11 Nov 2022 13:53:37 +0200 Subject: [PATCH 2/5] chore: add db.statement for scan methods as well --- src/Psr/Tracing/RelayOpenTelemetry.php | 76 +++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/src/Psr/Tracing/RelayOpenTelemetry.php b/src/Psr/Tracing/RelayOpenTelemetry.php index 5cb3c09..ceb7bff 100644 --- a/src/Psr/Tracing/RelayOpenTelemetry.php +++ b/src/Psr/Tracing/RelayOpenTelemetry.php @@ -112,12 +112,12 @@ public function __call(string $name, array $arguments) return $this->relay->{$name}(...$arguments); } - $stmt = $name . ' ' . implode(' ', $arguments); - $stmt = substr($stmt, 0, 1000); + $operation = strtoupper($name); + $stmt = $this->fmtStmt($operation, $arguments); $span = $this->tracer->spanBuilder('Relay::' . strtolower($name)) - ->setAttribute('db.operation', strtoupper($name)) ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', $operation) ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -156,9 +156,11 @@ public static function __callStatic(string $name, array $arguments) */ public function scan(&$iterator, $match = null, int $count = 0, ?string $type = null) { + $stmt = $this->fmtScan('SCAN', null, $iterator, $match, $count, $type); $span = $this->tracer->spanBuilder('Relay::scan') - ->setAttribute('db.operation', 'SCAN') ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', 'SCAN') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -184,9 +186,11 @@ public function scan(&$iterator, $match = null, int $count = 0, ?string $type = */ public function hscan($key, &$iterator, $match = null, int $count = 0) { + $stmt = $this->fmtScan('HSCAN', $key, $iterator, $match, $count); $span = $this->tracer->spanBuilder('Relay::hscan') - ->setAttribute('db.operation', 'HSCAN') ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', 'HSCAN') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -212,9 +216,11 @@ public function hscan($key, &$iterator, $match = null, int $count = 0) */ public function sscan($key, &$iterator, $match = null, int $count = 0) { + $stmt = $this->fmtScan('SSCAN', $key, $iterator, $match, $count); $span = $this->tracer->spanBuilder('Relay::sscan') - ->setAttribute('db.operation', 'SSCAN') ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', 'SSCAN') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -240,9 +246,11 @@ public function sscan($key, &$iterator, $match = null, int $count = 0) */ public function zscan($key, &$iterator, $match = null, int $count = 0) { + $stmt = $this->fmtScan('ZSCAN', $key, $iterator, $match, $count); $span = $this->tracer->spanBuilder('Relay::zscan') - ->setAttribute('db.operation', 'ZSCAN') ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', 'ZSCAN') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -324,4 +332,58 @@ public function executeBufferedTransaction(Transaction $transaction) $span->end(); } } + + /** + * Formats $name and $arguments for db.statement attribute. + * + * @param string $name + * @param array $arguments + * @return string + */ + protected function fmtStmt(string $name, array $arguments) + { + $acc = [$name]; + + $len = 0; + foreach ($arguments as $value) { + $str = strval($value); + $len += strlen($str); + if ($len > 1000) { + break; + } + array_push($acc, $str); + } + + return implode(' ', $acc); + } + + /** + * Formats SCAN command arguments. + * + * @param string $name + * @param mixed $key + * @param mixed $iterator + * @param mixed $match + * @param int $count + * @param ?string $type + * @return string + */ + protected function fmtScan($name, $key, $iterator, $match = null, int $count = 0, ?string $type = null) + { + $args = [$name]; + if ($key) { + array_push($args, $key); + } + array_push($args, $iterator); + if ($match) { + array_push($args, 'MATCH', $match); + } + if ($count > 0) { + array_push($args, 'COUNT', $count); + } + if ($type) { + array_push($args, 'TYPE', $type); + } + return implode(' ', $args); + } } From e12e89d9cfa26afc4ca9f7add8fee3b2f27eb5f5 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 11 Nov 2022 14:14:35 +0200 Subject: [PATCH 3/5] chore: add db.statement for transactions as well --- src/Psr/Tracing/RelayOpenTelemetry.php | 59 +++++++++++++++++++++----- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/Psr/Tracing/RelayOpenTelemetry.php b/src/Psr/Tracing/RelayOpenTelemetry.php index ceb7bff..0b227c7 100644 --- a/src/Psr/Tracing/RelayOpenTelemetry.php +++ b/src/Psr/Tracing/RelayOpenTelemetry.php @@ -113,7 +113,7 @@ public function __call(string $name, array $arguments) } $operation = strtoupper($name); - $stmt = $this->fmtStmt($operation, $arguments); + $stmt = $this->fmtCommand($operation, $arguments); $span = $this->tracer->spanBuilder('Relay::' . strtolower($name)) ->setAttribute('db.system', 'redis') @@ -310,9 +310,11 @@ public function executeBufferedTransaction(Transaction $transaction) ? 'pipeline' : 'multi'; - $span = $this->tracer->spanBuilder('Relay::exec') - ->setAttribute('db.operation', 'EXEC') + $stmt = $this->fmtCommands($transaction->commands); + $span = $this->tracer->spanBuilder('Relay::' . $method) ->setAttribute('db.system', 'redis') + ->setAttribute('db.operation', 'EXEC') + ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); @@ -334,27 +336,64 @@ public function executeBufferedTransaction(Transaction $transaction) } /** - * Formats $name and $arguments for db.statement attribute. + * Formats multiple commands for db.statement attribute. + * + * @param array $commands + * @return string + */ + protected function fmtCommands(array $commands) + { + $acc = []; + $len = 0; + foreach ($commands as $command) { + $command = $this->fmtCommand($command[0], $command[1]); + $len += strlen($command); + if ($len > 5000) { + break; + } + array_push($acc, $command); + } + return implode(PHP_EOL, $acc); + } + + /** + * Formats a single command for db.statement attribute. * * @param string $name * @param array $arguments * @return string */ - protected function fmtStmt(string $name, array $arguments) + protected function fmtCommand(string $operation, array $arguments) { - $acc = [$name]; - + $acc = [$operation]; $len = 0; + $this->fmtArguments($acc, $len, $arguments); + return implode(' ', $acc); + } + + /** + * Formats passed arguments as strings. + * + * @param array $acc + * @param array $arguments + * @return void + */ + protected function fmtArguments(&$acc, int &$len, $arguments) + { foreach ($arguments as $value) { + if (is_array($value)) { + $this->fmtArguments($acc, $len, $value); + continue; + } + $str = strval($value); $len += strlen($str); if ($len > 1000) { + array_push($acc, '...'); break; } array_push($acc, $str); } - - return implode(' ', $acc); } /** @@ -368,7 +407,7 @@ protected function fmtStmt(string $name, array $arguments) * @param ?string $type * @return string */ - protected function fmtScan($name, $key, $iterator, $match = null, int $count = 0, ?string $type = null) + protected function fmtScan(string $name, $key, $iterator, $match = null, int $count = 0, ?string $type = null) { $args = [$name]; if ($key) { From 669138b951fa8a52536f994d8a24c7ccea8a8c25 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 11 Nov 2022 14:19:21 +0200 Subject: [PATCH 4/5] chore: better operation for executeBufferedTransaction --- src/Psr/Tracing/RelayOpenTelemetry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Psr/Tracing/RelayOpenTelemetry.php b/src/Psr/Tracing/RelayOpenTelemetry.php index 0b227c7..f59a275 100644 --- a/src/Psr/Tracing/RelayOpenTelemetry.php +++ b/src/Psr/Tracing/RelayOpenTelemetry.php @@ -313,7 +313,7 @@ public function executeBufferedTransaction(Transaction $transaction) $stmt = $this->fmtCommands($transaction->commands); $span = $this->tracer->spanBuilder('Relay::' . $method) ->setAttribute('db.system', 'redis') - ->setAttribute('db.operation', 'EXEC') + ->setAttribute('db.operation', $method) ->setAttribute('db.statement', $stmt) ->setSpanKind(SpanKind::KIND_CLIENT) ->startSpan(); From 8c20a1c2e452a9f46a46e71576ae61b838036843 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Tue, 22 Nov 2022 14:39:45 +0200 Subject: [PATCH 5/5] chore: limit max string len --- src/Psr/Tracing/RelayOpenTelemetry.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Psr/Tracing/RelayOpenTelemetry.php b/src/Psr/Tracing/RelayOpenTelemetry.php index f59a275..ade59ad 100644 --- a/src/Psr/Tracing/RelayOpenTelemetry.php +++ b/src/Psr/Tracing/RelayOpenTelemetry.php @@ -62,6 +62,13 @@ class RelayOpenTelemetry '_prefix', ]; + /** + * Maximum string length when formatting commands for OpenTelemetry. + * + * @var int + */ + protected const MAX_STR_LEN = 100; + /** * Creates a new instance. * @@ -387,6 +394,10 @@ protected function fmtArguments(&$acc, int &$len, $arguments) } $str = strval($value); + if (strlen($str) > self::MAX_STR_LEN) { + $str = substr($str, 0, self::MAX_STR_LEN - 3) + '...'; + } + $len += strlen($str); if ($len > 1000) { array_push($acc, '...');