@Override
    public <T> Optional<SpanEvent> onProviderSpanStart(TracingRequest tracingRequest, ExtractService<T> extractService,
            T carrier) {
        if (!isTracing) {
            return Optional.empty();
        }

        // Obtain TraceId, SpanId and other data from the protocol carrier
        extractService.getFromCarrier(tracingRequest, carrier);
        if (!filterSpanDepth(tracingRequest)) {
            return Optional.empty();
        }
        long startTime = System.currentTimeMillis();
        SpanEventContext spanEventContext = new SpanEventContext(tracingRequest);
        SpanEvent spanEvent = spanEventContext.getSpanEvent();
        spanEvent.setStartTime(startTime);
        threadLocal.set(spanEventContext);
        return Optional.of(spanEvent);
    }
@Test
    public void onProviderSpanStart() {
        try (MockedStatic<ServiceManager> mockedStatic = Mockito.mockStatic(ServiceManager.class)) {
            mockedStatic.when(() -> ServiceManager.getService(GatewayClient.class))
                    .thenReturn(new NettyGatewayClient());
            TracingServiceImpl tracingService = new TracingServiceImpl();

            // Service is stopped.
            tracingService.stop();
            TracingRequest tracingRequest = new TracingRequest("", "", "", "", "");
            Assert.assertFalse(tracingService.onProviderSpanStart(tracingRequest, extractService, header).isPresent());

            // SpanIdPrefix is too long.
            tracingService.start();
            String spanIdPrefix = RandomStringUtils.randomNumeric(STRING_SIZE);
            header.put(SPAN_ID_PREFIX, spanIdPrefix);
            Assert.assertFalse(tracingService.onProviderSpanStart(tracingRequest, extractService, header).isPresent());
            tracingService.stop();

            // The normal condition root span.
            tracingService.start();
            header.put(SPAN_ID_PREFIX, "");
            Optional<SpanEvent> spanEventOptional =
                    tracingService.onProviderSpanStart(tracingRequest, extractService, header);
            Assert.assertTrue(spanEventOptional.isPresent());
            Assert.assertFalse(spanEventOptional.get().getTraceId().isEmpty());
            Assert.assertEquals(INIT_PARENT_SPAN_ID, spanEventOptional.get().getSpanId());
            Assert.assertEquals("", spanEventOptional.get().getParentSpanId());
            tracingService.stop();

            // The normal condition children span
            tracingService.start();
            String traceId = TracingUtils.generateTraceId();
            header.put(TRACE_ID, traceId);
            header.put(PARENT_SPAN_ID, INIT_PARENT_SPAN_ID);
            header.put(SPAN_ID_PREFIX, INIT_SPAN_ID_PREFIX);
            spanEventOptional = tracingService.onProviderSpanStart(tracingRequest, extractService, header);
            Assert.assertTrue(spanEventOptional.isPresent());
            Assert.assertEquals(traceId, spanEventOptional.get().getTraceId());
            Assert.assertEquals(INIT_SPAN_ID, spanEventOptional.get().getSpanId());
            Assert.assertEquals(INIT_PARENT_SPAN_ID, spanEventOptional.get().getParentSpanId());
            tracingService.stop();
        }
    }