44
55use Closure ;
66use Illuminate \Contracts \Foundation \Application ;
7- use Illuminate \Support \Facades \Context as LaravelContext ;
87use Illuminate \Support \Facades \Log ;
98use OpenTelemetry \API \Globals ;
109use OpenTelemetry \API \Trace \NoopTracer ;
10+ use OpenTelemetry \API \Trace \NoopTracerProvider ;
1111use OpenTelemetry \API \Trace \Span ;
1212use OpenTelemetry \API \Trace \SpanContextValidator ;
1313use OpenTelemetry \API \Trace \SpanInterface ;
1818use OpenTelemetry \Context \ContextInterface ;
1919use OpenTelemetry \Context \Propagation \TextMapPropagatorInterface ;
2020use OpenTelemetry \Context \ScopeInterface ;
21+ use Throwable ;
2122
2223class Measure
2324{
2425 private static ?SpanInterface $ rootSpan = null ;
2526
2627 private static ?ScopeInterface $ rootScope = null ;
2728
29+ private static ?bool $ enabled = null ;
30+
2831 public function __construct (protected Application $ app ) {}
2932
3033 // ======================= Enable/Disable Management =======================
3134
3235 public function enable (): void
3336 {
34- LaravelContext:: addHidden ( ' otel.tracing. enabled' , true ) ;
37+ self :: $ enabled = true ;
3538 }
3639
3740 public function disable (): void
3841 {
39- LaravelContext:: addHidden ( ' otel.tracing. enabled' , false ) ;
42+ self :: $ enabled = false ;
4043 }
4144
4245 public function isEnabled (): bool
4346 {
44- // If context has not been set, fall back to the general config.
45- if (LaravelContext::missingHidden ('otel.tracing.enabled ' )) {
47+ if (self ::$ enabled === null ) {
4648 return config ('otel.enabled ' , true );
4749 }
4850
49- return LaravelContext:: getHidden ( ' otel.tracing. enabled' ) ;
51+ return self :: $ enabled ;
5052 }
5153
5254 public function reset (): void
5355 {
54- LaravelContext:: addHidden ( ' otel.tracing. enabled' , config ( ' otel.enabled ' , true )) ;
56+ self :: $ enabled = null ;
5557
5658 // Only end root span in Octane mode
5759 // In FPM mode, each request is a separate process, so root span management is handled by middleware
@@ -67,7 +69,7 @@ public function reset(): void
6769 */
6870 public function startRootSpan (string $ name , array $ attributes = [], ?ContextInterface $ parentContext = null ): SpanInterface
6971 {
70- $ parentContext = $ parentContext ?: \ OpenTelemetry \ Context \ Context::getRoot ();
72+ $ parentContext = $ parentContext ?: Context::getRoot ();
7173 $ tracer = $ this ->tracer ();
7274
7375 $ span = $ tracer ->spanBuilder ($ name )
@@ -122,7 +124,7 @@ public function endRootSpan(): void
122124 if (self ::$ rootScope ) {
123125 try {
124126 self ::$ rootScope ->detach ();
125- } catch (\ Throwable $ e ) {
127+ } catch (Throwable $ e ) {
126128 // Scope may have already been detached, ignore errors
127129 }
128130 self ::$ rootScope = null ;
@@ -171,14 +173,14 @@ public function trace(string $name, Closure $callback, array $attributes = []):
171173 ->setAttributes ($ attributes )
172174 ->startSpan ();
173175
174- $ scope = $ span ->storeInContext (\ OpenTelemetry \ Context \ Context::getCurrent ())->activate ();
176+ $ scope = $ span ->storeInContext (Context::getCurrent ())->activate ();
175177
176178 try {
177179 $ result = $ callback ($ span );
178180 $ span ->setStatus (StatusCode::STATUS_OK );
179181
180182 return $ result ;
181- } catch (\ Throwable $ e ) {
183+ } catch (Throwable $ e ) {
182184 $ span ->recordException ($ e );
183185 $ span ->setStatus (StatusCode::STATUS_ERROR , $ e ->getMessage ());
184186 throw $ e ;
@@ -194,7 +196,8 @@ public function trace(string $name, Closure $callback, array $attributes = []):
194196 public function end (): void
195197 {
196198 $ span = Span::getCurrent ();
197- if ($ span && $ span !== Span::getInvalid ()) {
199+
200+ if ($ span !== Span::getInvalid ()) {
198201 $ span ->end ();
199202 }
200203 }
@@ -212,7 +215,7 @@ public function addEvent(string $name, array $attributes = []): void
212215 /**
213216 * Record exception
214217 */
215- public function recordException (\ Throwable $ exception , array $ attributes = []): void
218+ public function recordException (Throwable $ exception , array $ attributes = []): void
216219 {
217220 $ this ->activeSpan ()->recordException ($ exception , $ attributes );
218221 }
@@ -236,7 +239,17 @@ public function tracer(): TracerInterface
236239 return new NoopTracer ;
237240 }
238241
239- return $ this ->app ->get (TracerInterface::class);
242+ try {
243+ return $ this ->app ->get (TracerInterface::class);
244+ } catch (Throwable $ e ) {
245+ Log::error ('OpenTelemetry: Tracer not found ' , [
246+ 'error ' => $ e ->getMessage (),
247+ 'line ' => $ e ->getLine (),
248+ 'file ' => $ e ->getFile (),
249+ ]);
250+
251+ return new NoopTracer ;
252+ }
240253 }
241254
242255 /**
@@ -301,7 +314,7 @@ public function extractContextFromPropagationHeaders(array $headers): ContextInt
301314 */
302315 public function flush (): void
303316 {
304- Globals::tracerProvider ()->forceFlush ();
317+ Globals::tracerProvider ()? ->forceFlush();
305318 }
306319
307320 /**
@@ -318,15 +331,9 @@ public function isOctane(): bool
318331 public function isRecording (): bool
319332 {
320333 $ tracerProvider = Globals::tracerProvider ();
321- if (method_exists ($ tracerProvider , 'getSampler ' )) {
322- $ sampler = $ tracerProvider ->getSampler ();
323-
324- // This is a simplified check. A more robust check might involve checking sampler decision.
325- return ! ($ sampler instanceof \OpenTelemetry \SDK \Trace \Sampler \NeverOffSampler);
326- }
327334
328335 // Fallback for NoopTracerProvider or other types
329- return ! ($ tracerProvider instanceof \ OpenTelemetry \ API \ Trace \ NoopTracerProvider);
336+ return ! ($ tracerProvider instanceof NoopTracerProvider);
330337 }
331338
332339 /**
@@ -342,7 +349,6 @@ public function getStatus(): array
342349 return [
343350 'is_recording ' => $ isRecording ,
344351 'is_noop ' => ! $ isRecording ,
345- 'active_spans_count ' => Context::storage ()->count (),
346352 'current_trace_id ' => $ traceId !== '00000000000000000000000000000000 ' ? $ traceId : null ,
347353 'tracer_provider ' => [
348354 'class ' => get_class ($ tracerProvider ),
0 commit comments