PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.16
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.16
1.10.25 1.10.24 1.10.23 1.10.22 1.10.21 1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 All 169 releases
woocommerce-pos / vendor_prefixed / sentry / sentry / src / State / Hub.php

Hub.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.16, at vendor_prefixed/sentry/sentry/src/State/Hub.php

350 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace WCPOS\Vendor\Sentry\State;
5
6 use WCPOS\Vendor\Psr\Log\NullLogger;
7 use WCPOS\Vendor\Sentry\Breadcrumb;
8 use WCPOS\Vendor\Sentry\CheckIn;
9 use WCPOS\Vendor\Sentry\CheckInStatus;
10 use WCPOS\Vendor\Sentry\ClientInterface;
11 use WCPOS\Vendor\Sentry\Event;
12 use WCPOS\Vendor\Sentry\EventHint;
13 use WCPOS\Vendor\Sentry\EventId;
14 use WCPOS\Vendor\Sentry\Integration\IntegrationInterface;
15 use WCPOS\Vendor\Sentry\MonitorConfig;
16 use WCPOS\Vendor\Sentry\Severity;
17 use WCPOS\Vendor\Sentry\Tracing\SamplingContext;
18 use WCPOS\Vendor\Sentry\Tracing\Span;
19 use WCPOS\Vendor\Sentry\Tracing\Transaction;
20 use WCPOS\Vendor\Sentry\Tracing\TransactionContext;
21 /**
22 * This class is a basic implementation of the {@see HubInterface} interface.
23 */
24 class Hub implements HubInterface
25 {
26 /**
27 * @var Layer[] The stack of client/scope pairs
28 */
29 private $stack = [];
30 /**
31 * @var EventId|null The ID of the last captured event
32 */
33 private $lastEventId;
34 /**
35 * Hub constructor.
36 *
37 * @param ClientInterface|null $client The client bound to the hub
38 * @param Scope|null $scope The scope bound to the hub
39 */
40 public function __construct(?ClientInterface $client = null, ?Scope $scope = null)
41 {
42 $this->stack[] = new Layer($client, $scope ?? new Scope());
43 }
44 /**
45 * {@inheritdoc}
46 */
47 public function getClient() : ?ClientInterface
48 {
49 return $this->getStackTop()->getClient();
50 }
51 /**
52 * {@inheritdoc}
53 */
54 public function getLastEventId() : ?EventId
55 {
56 return $this->lastEventId;
57 }
58 /**
59 * {@inheritdoc}
60 */
61 public function pushScope() : Scope
62 {
63 $clonedScope = clone $this->getScope();
64 $this->stack[] = new Layer($this->getClient(), $clonedScope);
65 return $clonedScope;
66 }
67 /**
68 * {@inheritdoc}
69 */
70 public function popScope() : bool
71 {
72 if (\count($this->stack) === 1) {
73 return \false;
74 }
75 return \array_pop($this->stack) !== null;
76 }
77 /**
78 * {@inheritdoc}
79 */
80 public function withScope(callable $callback)
81 {
82 $scope = $this->pushScope();
83 try {
84 return $callback($scope);
85 } finally {
86 $this->popScope();
87 }
88 }
89 /**
90 * {@inheritdoc}
91 */
92 public function configureScope(callable $callback) : void
93 {
94 $callback($this->getScope());
95 }
96 /**
97 * {@inheritdoc}
98 */
99 public function bindClient(ClientInterface $client) : void
100 {
101 $layer = $this->getStackTop();
102 $layer->setClient($client);
103 }
104 /**
105 * {@inheritdoc}
106 */
107 public function captureMessage(string $message, ?Severity $level = null, ?EventHint $hint = null) : ?EventId
108 {
109 $client = $this->getClient();
110 if ($client !== null) {
111 return $this->lastEventId = $client->captureMessage($message, $level, $this->getScope(), $hint);
112 }
113 return null;
114 }
115 /**
116 * {@inheritdoc}
117 */
118 public function captureException(\Throwable $exception, ?EventHint $hint = null) : ?EventId
119 {
120 $client = $this->getClient();
121 if ($client !== null) {
122 return $this->lastEventId = $client->captureException($exception, $this->getScope(), $hint);
123 }
124 return null;
125 }
126 /**
127 * {@inheritdoc}
128 */
129 public function captureEvent(Event $event, ?EventHint $hint = null) : ?EventId
130 {
131 $client = $this->getClient();
132 if ($client !== null) {
133 return $this->lastEventId = $client->captureEvent($event, $hint, $this->getScope());
134 }
135 return null;
136 }
137 /**
138 * {@inheritdoc}
139 */
140 public function captureLastError(?EventHint $hint = null) : ?EventId
141 {
142 $client = $this->getClient();
143 if ($client !== null) {
144 return $this->lastEventId = $client->captureLastError($this->getScope(), $hint);
145 }
146 return null;
147 }
148 /**
149 * {@inheritdoc}
150 *
151 * @param int|float|null $duration
152 */
153 public function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null) : ?string
154 {
155 $client = $this->getClient();
156 if ($client === null) {
157 return null;
158 }
159 $options = $client->getOptions();
160 $event = Event::createCheckIn();
161 $checkIn = new CheckIn($slug, $status, $checkInId, $options->getRelease(), $options->getEnvironment(), $duration, $monitorConfig);
162 $event->setCheckIn($checkIn);
163 $this->captureEvent($event);
164 return $checkIn->getId();
165 }
166 /**
167 * {@inheritdoc}
168 */
169 public function addBreadcrumb(Breadcrumb $breadcrumb) : bool
170 {
171 $client = $this->getClient();
172 if ($client === null) {
173 return \false;
174 }
175 $options = $client->getOptions();
176 $beforeBreadcrumbCallback = $options->getBeforeBreadcrumbCallback();
177 $maxBreadcrumbs = $options->getMaxBreadcrumbs();
178 if ($maxBreadcrumbs <= 0) {
179 return \false;
180 }
181 $breadcrumb = $beforeBreadcrumbCallback($breadcrumb);
182 if ($breadcrumb !== null) {
183 $this->getScope()->addBreadcrumb($breadcrumb, $maxBreadcrumbs);
184 }
185 return $breadcrumb !== null;
186 }
187 /**
188 * {@inheritdoc}
189 */
190 public function getIntegration(string $className) : ?IntegrationInterface
191 {
192 $client = $this->getClient();
193 if ($client !== null) {
194 return $client->getIntegration($className);
195 }
196 return null;
197 }
198 /**
199 * {@inheritdoc}
200 *
201 * @param array<string, mixed> $customSamplingContext Additional context that will be passed to the {@see SamplingContext}
202 */
203 public function startTransaction(TransactionContext $context, array $customSamplingContext = []) : Transaction
204 {
205 $transaction = new Transaction($context, $this);
206 $client = $this->getClient();
207 $options = $client !== null ? $client->getOptions() : null;
208 $logger = $options !== null ? $options->getLoggerOrNullLogger() : new NullLogger();
209 if ($options === null || !$options->isTracingEnabled()) {
210 $transaction->setSampled(\false);
211 $logger->warning(\sprintf('Transaction [%s] was started but tracing is not enabled.', (string) $transaction->getTraceId()), ['context' => $context]);
212 return $transaction;
213 }
214 $samplingContext = SamplingContext::getDefault($context);
215 $samplingContext->setAdditionalContext($customSamplingContext);
216 $sampleSource = 'context';
217 $sampleRand = $context->getMetadata()->getSampleRand();
218 if ($transaction->getSampled() === null) {
219 $tracesSampler = $options->getTracesSampler();
220 if ($tracesSampler !== null) {
221 $sampleRate = $tracesSampler($samplingContext);
222 $sampleSource = 'config:traces_sampler';
223 } else {
224 $parentSampleRate = $context->getMetadata()->getParentSamplingRate();
225 if ($parentSampleRate !== null) {
226 $sampleRate = $parentSampleRate;
227 $sampleSource = 'parent:sample_rate';
228 } else {
229 $sampleRate = $this->getSampleRate($samplingContext->getParentSampled(), $options->getTracesSampleRate() ?? 0);
230 $sampleSource = $samplingContext->getParentSampled() !== null ? 'parent:sampling_decision' : 'config:traces_sample_rate';
231 }
232 }
233 if (!$this->isValidSampleRate($sampleRate)) {
234 $transaction->setSampled(\false);
235 $logger->warning(\sprintf('Transaction [%s] was started but not sampled because sample rate (decided by %s) is invalid.', (string) $transaction->getTraceId(), $sampleSource), ['context' => $context]);
236 return $transaction;
237 }
238 $transaction->getMetadata()->setSamplingRate($sampleRate);
239 // Always overwrite the sample_rate in the DSC
240 $dynamicSamplingContext = $context->getMetadata()->getDynamicSamplingContext();
241 if ($dynamicSamplingContext !== null) {
242 $dynamicSamplingContext->set('sample_rate', (string) $sampleRate, \true);
243 }
244 if ($sampleRate === 0.0) {
245 $transaction->setSampled(\false);
246 $logger->info(\sprintf('Transaction [%s] was started but not sampled because sample rate (decided by %s) is %s.', (string) $transaction->getTraceId(), $sampleSource, $sampleRate), ['context' => $context]);
247 return $transaction;
248 }
249 $transaction->setSampled($sampleRand < $sampleRate);
250 }
251 if (!$transaction->getSampled()) {
252 $logger->info(\sprintf('Transaction [%s] was started but not sampled, decided by %s.', (string) $transaction->getTraceId(), $sampleSource), ['context' => $context]);
253 return $transaction;
254 }
255 $logger->info(\sprintf('Transaction [%s] was started and sampled, decided by %s.', (string) $transaction->getTraceId(), $sampleSource), ['context' => $context]);
256 $transaction->initSpanRecorder();
257 $profilesSampleSource = 'config:profiles_sample_rate';
258 $profilesSampler = $options->getProfilesSampler();
259 if ($profilesSampler !== null) {
260 $profilesSampleRate = $profilesSampler($samplingContext);
261 $profilesSampleSource = 'config:profiles_sampler';
262 } else {
263 $profilesSampleRate = $options->getProfilesSampleRate();
264 }
265 if ($profilesSampleRate === null) {
266 $logger->info(\sprintf('Transaction [%s] is not profiling because neither `profiles_sample_rate` nor `profiles_sampler` option is set.', (string) $transaction->getTraceId()));
267 } elseif (!$this->isValidSampleRate($profilesSampleRate)) {
268 $logger->warning(\sprintf('Transaction [%s] is not profiling because profile sample rate (decided by %s) is invalid.', (string) $transaction->getTraceId(), $profilesSampleSource));
269 } elseif ($this->sample($profilesSampleRate)) {
270 $logger->info(\sprintf('Transaction [%s] started profiling because it was sampled.', (string) $transaction->getTraceId()));
271 $transaction->initProfiler()->start();
272 } else {
273 $logger->info(\sprintf('Transaction [%s] is not profiling because it was not sampled.', (string) $transaction->getTraceId()));
274 }
275 return $transaction;
276 }
277 /**
278 * {@inheritdoc}
279 */
280 public function getTransaction() : ?Transaction
281 {
282 return $this->getScope()->getTransaction();
283 }
284 /**
285 * {@inheritdoc}
286 */
287 public function setSpan(?Span $span) : HubInterface
288 {
289 $this->getScope()->setSpan($span);
290 return $this;
291 }
292 /**
293 * {@inheritdoc}
294 */
295 public function getSpan() : ?Span
296 {
297 return $this->getScope()->getSpan();
298 }
299 /**
300 * Gets the scope bound to the top of the stack.
301 */
302 private function getScope() : Scope
303 {
304 return $this->getStackTop()->getScope();
305 }
306 /**
307 * Gets the topmost client/layer pair in the stack.
308 */
309 private function getStackTop() : Layer
310 {
311 return $this->stack[\count($this->stack) - 1];
312 }
313 private function getSampleRate(?bool $hasParentBeenSampled, float $fallbackSampleRate) : float
314 {
315 if ($hasParentBeenSampled === \true) {
316 return 1.0;
317 }
318 if ($hasParentBeenSampled === \false) {
319 return 0.0;
320 }
321 return $fallbackSampleRate;
322 }
323 /**
324 * @param mixed $sampleRate
325 */
326 private function sample($sampleRate) : bool
327 {
328 if ($sampleRate === 0.0 || $sampleRate === null) {
329 return \false;
330 }
331 if ($sampleRate === 1.0) {
332 return \true;
333 }
334 return \mt_rand(0, \mt_getrandmax() - 1) / \mt_getrandmax() < $sampleRate;
335 }
336 /**
337 * @param mixed $sampleRate
338 */
339 private function isValidSampleRate($sampleRate) : bool
340 {
341 if (!\is_float($sampleRate) && !\is_int($sampleRate)) {
342 return \false;
343 }
344 if ($sampleRate < 0 || $sampleRate > 1) {
345 return \false;
346 }
347 return \true;
348 }
349 }
350