TraceableEvent::processTrace()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 12
ccs 8
cts 8
cp 1
crap 2
rs 10
1
<?php
2
3
namespace ZoiloMora\ElasticAPM\Events;
4
5
use ZoiloMora\ElasticAPM\Helper\Cryptography;
6
use ZoiloMora\ElasticAPM\Helper\DistributedTracing;
7
use ZoiloMora\ElasticAPM\Helper\Encoding;
8
9
/**
10
 * Traceable Event - Distributed Tracing
11
 */
12
abstract class TraceableEvent extends Event
13
{
14
    const TRACE_ID_BITS = 128;
15
16
    /**
17
     * Hex encoded 128 random bits ID of the correlated trace.
18
     *
19
     * @var string
20
     */
21
    protected $traceId;
22
23
    /**
24
     * Hex encoded 64 random bits ID of the parent transaction or span.
25
     * Only root transactions of a trace do not have a parent_id, otherwise it needs to be set.
26
     *
27
     * @var string|null
28
     */
29
    protected $parentId;
30
31
    /**
32
     * @param string|null $traceId
33
     * @param string|null $parentId
34
     *
35
     * @throws \Exception
36
     */
37 28
    public function __construct($traceId = null, $parentId = null)
38
    {
39 28
        parent::__construct();
40
41 28
        $this->processTrace($traceId, $parentId);
42 26
    }
43
44
    /**
45
     * @return string
46
     */
47 7
    public function traceId()
48
    {
49 7
        return $this->traceId;
50
    }
51
52
    /**
53
     * @return string|null
54
     */
55 5
    public function parentId()
56
    {
57 5
        return $this->parentId;
58
    }
59
60
    /**
61
     * Get the Distributed Tracing Value of this Event
62
     *
63
     * @return string
64
     */
65 3
    public function distributedTracing()
66
    {
67 3
        $distributedTracing = new DistributedTracing(
68 3
            $this->traceId,
69 3
            $this->id
70 3
        );
71
72 3
        return (string) $distributedTracing;
73
    }
74
75
    /**
76
     * @param mixed $traceId
77
     * @param mixed $parentId
78
     *
79
     * @return void
80
     *
81
     * @throws \Exception
82
     */
83 28
    private function processTrace($traceId, $parentId)
84
    {
85 28
        $this->assertTraceId($traceId);
86 27
        $this->assertParentId($parentId);
87
88 26
        $this->traceId = $traceId;
89 26
        $this->parentId = $parentId;
90
91 26
        $this->processDistributedTrace();
92
93 26
        if (null === $this->traceId) {
94 8
            $this->traceId = Cryptography::generateRandomBitsInHex(self::TRACE_ID_BITS);
95 8
        }
96 26
    }
97
98
    /**
99
     * @return void
100
     *
101
     * @throws \Exception
102
     */
103 26
    private function processDistributedTrace()
104
    {
105 26
        $distributedTracing = DistributedTracing::discoverDistributedTracing();
106
107 26
        if (null === $distributedTracing) {
108 25
            return;
109
        }
110
111 1
        if (null === $this->traceId) {
112 1
            $this->traceId = $distributedTracing->traceId();
113 1
        }
114
115 1
        if (null === $this->parentId) {
116 1
            $this->parentId = $distributedTracing->parentId();
117 1
        }
118 1
    }
119
120
    /**
121
     * @param mixed $traceId
122
     *
123
     * @return void
124
     *
125
     * @throws \InvalidArgumentException
126
     */
127 28
    private function assertTraceId($traceId)
128
    {
129 28
        if (null !== $traceId && false === is_string($traceId)) {
130 1
            throw new \InvalidArgumentException('[traceId] must be of string type.');
131
        }
132 27
    }
133
134
    /**
135
     * @param mixed $parentId
136
     *
137
     * @return void
138
     *
139
     * @throws \InvalidArgumentException
140
     */
141 27
    private function assertParentId($parentId)
142
    {
143 27
        if (null !== $parentId && false === is_string($parentId)) {
144 1
            throw new \InvalidArgumentException('[parentId] must be of string type.');
145
        }
146 26
    }
147
148
    /**
149
     * @return array
150
     */
151 4
    public function jsonSerialize()
152
    {
153 4
        return array_merge(
154 4
            parent::jsonSerialize(),
155
            [
156 4
                'trace_id' => Encoding::keywordField($this->traceId),
157 4
                'parent_id' => Encoding::keywordField($this->parentId),
158
            ]
159 4
        );
160
    }
161
}
162