Skip to content

Commit 25d414f

Browse files
author
Kirill Nesmeyanov
committed
Improve tracing logic
1 parent 322eb31 commit 25d414f

File tree

6 files changed

+123
-19
lines changed

6 files changed

+123
-19
lines changed

src/Runtime/Parser/TraceableTypeParser.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,33 @@ public function __construct(
1717

1818
public function getStatementByDefinition(#[Language('PHP')] string $definition): TypeStatement
1919
{
20-
$span = $this->tracer->start('type-lang::parsing');
20+
$span = $this->tracer->start(\sprintf('Parsing by definition [%s]', $definition));
2121

2222
try {
23-
return $this->delegate->getStatementByDefinition($definition);
23+
$span->setAttribute('value', $definition);
24+
25+
$result = $this->delegate->getStatementByDefinition($definition);
26+
27+
$span->setAttribute('result', $result);
28+
29+
return $result;
2430
} finally {
2531
$span->stop();
2632
}
2733
}
2834

2935
public function getStatementByValue(mixed $value): TypeStatement
3036
{
31-
$span = $this->tracer->start('type-lang::parsing');
37+
$span = $this->tracer->start(\sprintf('Parsing by value [%s]', \get_debug_type($value)));
3238

3339
try {
34-
return $this->delegate->getStatementByValue($value);
40+
$span->setAttribute('value', $value);
41+
42+
$result = $this->delegate->getStatementByValue($value);
43+
44+
$span->setAttribute('result', $result);
45+
46+
return $result;
3547
} finally {
3648
$span->stop();
3749
}

src/Runtime/Repository/TraceableTypeRepository.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ public function getTypeByDefinition(
2424
string $definition,
2525
?\ReflectionClass $context = null,
2626
): TypeInterface {
27-
$span = $this->tracer->start('type-lang::fetching');
27+
$span = $this->tracer->start(\sprintf('Fetching by definition [%s]', $definition));
2828

2929
try {
30+
$span->setAttribute('value', $definition);
31+
3032
$result = $this->delegate->getTypeByDefinition($definition, $context);
33+
34+
$span->setAttribute('result', $result);
3135
} finally {
3236
$span->stop();
3337
}
@@ -37,10 +41,14 @@ public function getTypeByDefinition(
3741

3842
public function getTypeByValue(mixed $value, ?\ReflectionClass $context = null): TypeInterface
3943
{
40-
$span = $this->tracer->start('type-lang::fetching');
44+
$span = $this->tracer->start(\sprintf('Fetching by value [%s]', \get_debug_type($value)));
4145

4246
try {
47+
$span->setAttribute('value', $value);
48+
4349
$result = $this->delegate->getTypeByValue($value, $context);
50+
51+
$span->setAttribute('result', $result);
4452
} finally {
4553
$span->stop();
4654
}
@@ -50,10 +58,14 @@ public function getTypeByValue(mixed $value, ?\ReflectionClass $context = null):
5058

5159
public function getTypeByStatement(TypeStatement $statement, ?\ReflectionClass $context = null): TypeInterface
5260
{
53-
$span = $this->tracer->start('type-lang::fetching');
61+
$span = $this->tracer->start(\sprintf('Fetching by statement "%s"', \get_debug_type($statement)));
5462

5563
try {
64+
$span->setAttribute('value', $statement);
65+
5666
$result = $this->delegate->getTypeByStatement($statement, $context);
67+
68+
$span->setAttribute('result', $result);
5769
} finally {
5870
$span->stop();
5971
}

src/Runtime/Repository/TraceableTypeRepository/TraceableType.php

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace TypeLang\Mapper\Runtime\Repository\TraceableTypeRepository;
66

77
use TypeLang\Mapper\Runtime\Context;
8+
use TypeLang\Mapper\Runtime\Path\Entry\ObjectEntry;
89
use TypeLang\Mapper\Runtime\Tracing\TracerInterface;
910
use TypeLang\Mapper\Type\TypeInterface;
1011

@@ -14,34 +15,96 @@
1415
*/
1516
final class TraceableType implements TypeInterface
1617
{
18+
/**
19+
* @var non-empty-string
20+
*/
21+
private readonly string $name;
22+
1723
public function __construct(
1824
private readonly TracerInterface $tracer,
1925
private readonly TypeInterface $delegate,
20-
) {}
26+
) {
27+
$this->name = self::getShortName($this->delegate::class)
28+
. '#' . \spl_object_id($this->delegate);
29+
}
30+
31+
/**
32+
* @param non-empty-string $fqn
33+
*
34+
* @return non-empty-string
35+
*/
36+
private static function getShortName(string $fqn): string
37+
{
38+
/** @var non-empty-list<non-empty-string> $parts */
39+
$parts = \explode('\\', $fqn);
40+
41+
return \end($parts);
42+
}
43+
44+
/**
45+
* @return list<non-empty-string>
46+
*/
47+
private static function getPath(Context $context): array
48+
{
49+
$result = [];
50+
51+
foreach ($context->getPath() as $entry) {
52+
$result[] = match (true) {
53+
$entry instanceof ObjectEntry => self::getShortName($entry->value),
54+
default => (string) $entry,
55+
};
56+
}
57+
58+
/** @var list<non-empty-string> */
59+
return $result;
60+
}
61+
62+
private static function getCurrentPath(Context $context): string
63+
{
64+
$result = self::getPath($context);
65+
66+
if ($result === []) {
67+
return '<root>';
68+
}
69+
70+
return \end($result);
71+
}
2172

2273
public function match(mixed $value, Context $context): bool
2374
{
24-
$span = $this->tracer->start(\sprintf(
25-
'type-lang::matching(%s)',
26-
$this->delegate::class . '#' . \spl_object_id($this->delegate),
27-
));
75+
$span = $this->tracer->start(\vsprintf('Type matching [%s at %s]', [
76+
$this->name,
77+
self::getCurrentPath($context),
78+
]));
2879

2980
try {
30-
return $this->delegate->match($value, $context);
81+
$span->setAttribute('value', $value);
82+
83+
$result = $this->delegate->match($value, $context);
84+
85+
$span->setAttribute('result', $result);
86+
87+
return $result;
3188
} finally {
3289
$span->stop();
3390
}
3491
}
3592

3693
public function cast(mixed $value, Context $context): mixed
3794
{
38-
$span = $this->tracer->start(\sprintf(
39-
'type-lang::casting(%s)',
40-
$this->delegate::class . '#' . \spl_object_id($this->delegate),
41-
));
95+
$span = $this->tracer->start(\vsprintf('Type casting [%s at %s]', [
96+
$this->name,
97+
self::getCurrentPath($context),
98+
]));
4299

43100
try {
44-
return $this->delegate->cast($value, $context);
101+
$span->setAttribute('value', $value);
102+
103+
$result = $this->delegate->cast($value, $context);
104+
105+
$span->setAttribute('result', $result);
106+
107+
return $result;
45108
} finally {
46109
$span->stop();
47110
}

src/Runtime/Tracing/SpanInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
interface SpanInterface
88
{
9+
/**
10+
* Sets a single attribute on the span.
11+
*
12+
* @param non-empty-string $key
13+
*/
14+
public function setAttribute(string $key, mixed $value): void;
15+
916
/**
1017
* Marks this span as completed.
1118
*/

src/Runtime/Tracing/SymfonyStopwatchTracer.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99

1010
final class SymfonyStopwatchTracer implements TracerInterface
1111
{
12+
/**
13+
* @param non-empty-string|null $category
14+
*/
1215
public function __construct(
1316
public readonly Stopwatch $stopwatch,
17+
private readonly ?string $category = 'type-lang',
1418
) {}
1519

1620
public function start(string $name): SpanInterface
1721
{
1822
return new SymfonyStopwatchSpan(
19-
event: $this->stopwatch->start($name),
23+
event: $this->stopwatch->start($name, $this->category),
2024
);
2125
}
2226
}

src/Runtime/Tracing/SymfonyStopwatchTracer/SymfonyStopwatchSpan.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ public function __construct(
1717
private readonly StopwatchEvent $event,
1818
) {}
1919

20+
public function setAttribute(string $key, mixed $value): void
21+
{
22+
// Do nothing
23+
// Symfony stopwatch does not support attributes
24+
}
25+
2026
public function stop(): void
2127
{
2228
$this->event->stop();

0 commit comments

Comments
 (0)