summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/context/DebugScope.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/context/DebugScope.php')
-rw-r--r--vendor/open-telemetry/context/DebugScope.php94
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/open-telemetry/context/DebugScope.php b/vendor/open-telemetry/context/DebugScope.php
new file mode 100644
index 000000000..e9e4d53c5
--- /dev/null
+++ b/vendor/open-telemetry/context/DebugScope.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context;
+
+use function basename;
+use function count;
+use function debug_backtrace;
+use const DEBUG_BACKTRACE_IGNORE_ARGS;
+use function sprintf;
+use function trigger_error;
+
+/**
+ * @internal
+ */
+final class DebugScope implements ScopeInterface
+{
+ private const DEBUG_TRACE_CREATE = '__debug_trace_create';
+ private const DEBUG_TRACE_DETACH = '__debug_trace_detach';
+
+ private ContextStorageScopeInterface $scope;
+
+ public function __construct(ContextStorageScopeInterface $node)
+ {
+ $this->scope = $node;
+ $this->scope[self::DEBUG_TRACE_CREATE] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ }
+
+ public function detach(): int
+ {
+ $this->scope[self::DEBUG_TRACE_DETACH] ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+
+ $flags = $this->scope->detach();
+
+ if (($flags & ScopeInterface::DETACHED) !== 0) {
+ trigger_error(sprintf(
+ 'Scope: unexpected call to Scope::detach() for scope #%d, scope was already detached %s',
+ spl_object_id($this),
+ self::formatBacktrace($this->scope[self::DEBUG_TRACE_DETACH]),
+ ));
+ } elseif (($flags & ScopeInterface::MISMATCH) !== 0) {
+ trigger_error(sprintf(
+ 'Scope: unexpected call to Scope::detach() for scope #%d, scope successfully detached but another scope should have been detached first',
+ spl_object_id($this),
+ ));
+ } elseif (($flags & ScopeInterface::INACTIVE) !== 0) {
+ trigger_error(sprintf(
+ 'Scope: unexpected call to Scope::detach() for scope #%d, scope successfully detached from different execution context',
+ spl_object_id($this),
+ ));
+ }
+
+ return $flags;
+ }
+
+ public function __destruct()
+ {
+ if (!isset($this->scope[self::DEBUG_TRACE_DETACH])) {
+ trigger_error(sprintf(
+ 'Scope: missing call to Scope::detach() for scope #%d, created %s',
+ spl_object_id($this->scope),
+ self::formatBacktrace($this->scope[self::DEBUG_TRACE_CREATE]),
+ ));
+ }
+ }
+
+ private static function formatBacktrace(array $trace): string
+ {
+ $s = '';
+ for ($i = 0, $n = count($trace) + 1; ++$i < $n;) {
+ $s .= "\n\t";
+ $s .= 'at ';
+ if (isset($trace[$i]['class'])) {
+ $s .= strtr($trace[$i]['class'], ['\\' => '.']);
+ $s .= '.';
+ }
+ $s .= strtr($trace[$i]['function'] ?? '{main}', ['\\' => '.']);
+ $s .= '(';
+ if (isset($trace[$i - 1]['file'])) {
+ $s .= basename($trace[$i - 1]['file']);
+ if (isset($trace[$i - 1]['line'])) {
+ $s .= ':';
+ $s .= $trace[$i - 1]['line'];
+ }
+ } else {
+ $s .= 'Unknown Source';
+ }
+ $s .= ')';
+ }
+
+ return $s . "\n";
+ }
+}