Issues (22)

src/Standard/Span.php (2 issues)

1
<?php
2
/**
3
 * OpenTracing::Span
4
 * User: moyo
5
 * Date: 23/11/2017
6
 * Time: 3:28 PM
7
 */
8
9
namespace Carno\Tracing\Standard;
10
11
use Carno\Tracing\Chips\RelatedEndpoints;
12
use Carno\Tracing\Chips\SpanInfoGetter;
13
use Carno\Tracing\Chips\Timestamp;
14
use Carno\Tracing\Contracts\Protocol;
15
use Carno\Tracing\Contracts\Transport;
16
use OpenTracing\Span as SpanAPI;
17
use OpenTracing\SpanContext;
18
19
class Span implements SpanAPI
20
{
21
    use Timestamp;
22
    use SpanInfoGetter, RelatedEndpoints;
23
24
    /**
25
     * operate not permit
26
     */
27
    private const E_FINISHED = 'This span is already finished';
28
29
    /**
30
     * @var string
31
     */
32
    private $operation = null;
33
34
    /**
35
     * @var Protocol
36
     */
37
    private $serializer = null;
38
39
    /**
40
     * @var Transport
41
     */
42
    private $transporter = null;
43
44
    /**
45
     * @var Context
46
     */
47
    private $context = null;
48
49
    /**
50
     * @var int
51
     */
52
    private $startAt = null;
53
54
    /**
55
     * @var int
56
     */
57
    private $endAt = null;
58
59
    /**
60
     * @var bool
61
     */
62
    private $finished = false;
63
64
    /**
65
     * @var array
66
     */
67
    private $tags = [];
68
69
    /**
70
     * @var array
71
     */
72
    private $logs = [];
73
74
    /**
75
     * Span constructor.
76
     * @param Protocol $serializer
77
     * @param Transport $transporter
78
     * @param Context $context
79
     * @param int $startTime
80
     */
81
    public function __construct(
82
        Protocol $serializer,
83
        Transport $transporter,
84
        Context $context,
85
        int $startTime = null
86
    ) {
87
        $this->serializer = $serializer;
88
        $this->transporter = $transporter;
89
        $this->context = $context;
90
        $this->startAt = $startTime ?? $this->microseconds();
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    public function getOperationName() : string
97
    {
98
        return $this->operation ?? 'none';
99
    }
100
101
    /**
102
     * @param string $newOperationName
103
     */
104
    public function overwriteOperationName($newOperationName) : void
105
    {
106
        if (!$this->permitted()) {
107
            return;
108
        }
109
110
        $this->operation = $newOperationName;
111
    }
112
113
    /**
114
     * @return SpanContext
115
     */
116
    public function getContext() : SpanContext
117
    {
118
        return $this->context;
119
    }
120
121
    /**
122
     * @param array $tags
123
     */
124
    public function setTags(array $tags) : void
125
    {
126
        if (!$this->permitted()) {
127
            return;
128
        }
129
130
        $this->tags = array_merge($this->tags, $tags);
131
    }
132
133
    /**
134
     * @param array $fields
135
     * @param int $timestamp
136
     */
137
    public function log(array $fields = [], $timestamp = null) : void
138
    {
139
        if (!$this->permitted()) {
140
            return;
141
        }
142
143
        $fields && $this->logs[] = [$timestamp ?? $this->microseconds(), $fields];
0 ignored issues
show
Bug Best Practice introduced by
The expression $fields of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
144
    }
145
146
    /**
147
     * @param string $key
148
     * @return string
149
     */
150
    public function getBaggageItem($key) : ?string
151
    {
152
        return $this->getContext()->getBaggageItem($key);
153
    }
154
155
    /**
156
     * @param string $key
157
     * @param string $value
158
     */
159
    public function addBaggageItem($key, $value) : void
160
    {
161
        if (!$this->permitted()) {
162
            return;
163
        }
164
165
        $this->context = $this->context->withBaggageItem($key, $value);
166
    }
167
168
    /**
169
     * @param int $finishTime
170
     * @param array $logRecords
171
     */
172
    public function finish($finishTime = null, array $logRecords = []) : void
173
    {
174
        if (!$this->permitted()) {
175
            return;
176
        }
177
178
        $this->endAt = $finishTime ?? $this->microseconds();
179
180
        if ($logRecords) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $logRecords of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
181
            foreach ($logRecords as $logRecord) {
182
                $this->log($logRecord, $this->microseconds());
183
            }
184
        }
185
186
        $this->transporter->loading($this->serializer->serialize($this));
187
188
        $this->finished = true;
189
    }
190
191
    /**
192
     * @return bool
193
     */
194
    private function permitted() : bool
195
    {
196
        if ($this->finished) {
197
            trigger_error(self::E_FINISHED, E_USER_WARNING);
198
            return false;
199
        }
200
        return true;
201
    }
202
}
203