### Spring Boot Auto-Configuration Source: https://context7.com/sofastack/sofa-tracer/llms.txt This is a standard Spring Boot application setup. Ensure SOFATracer dependencies are included for automatic configuration. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` -------------------------------- ### Custom Sampler Implementation Source: https://context7.com/sofastack/sofa-tracer/llms.txt Implement the Sampler interface to define custom sampling strategies. This example uses a consistent sampling rate based on the traceId's hash. ```java import com.alipay.common.tracer.core.samplers.Sampler; import com.alipay.common.tracer.core.samplers.SamplingStatus; import com.alipay.common. الترacer.core.span.SofaTracerSpan; import java.util.Map; import java.util.HashMap; public class CustomSampler implements Sampler { private final double samplingRate; public CustomSampler(double samplingRate) { this.samplingRate = samplingRate; } @Override public SamplingStatus sample(SofaTracerSpan sofaTracerSpan) { SamplingStatus status = new SamplingStatus(); String traceId = sofaTracerSpan.getSofaTracerSpanContext().getTraceId(); boolean sampled = Math.abs(traceId.hashCode() % 100) < (samplingRate * 100); status.setSampled(sampled); if (sampled) { Map tags = new HashMap<>(); tags.put("sampler.type", "custom"); tags.put("sampler.rate", samplingRate); status.setTags(tags); } return status; } @Override public String getType() { return "CustomSampler"; } @Override public void close() { } } ``` -------------------------------- ### SofaTracer - Core Tracer API Source: https://context7.com/sofastack/sofa-tracer/llms.txt The SofaTracer class is the core of SOFATracer, implementing the OpenTracing Tracer interface. It is used for creating, injecting, and extracting Span contexts. This example demonstrates building a SofaTracer instance with reporters and tags, and then creating and managing root and child Spans. ```APIDOC ## SofaTracer - Core Tracer API ### Description The `SofaTracer` class is the core component of SOFATracer, implementing the OpenTracing `Tracer` interface. It is responsible for creating, injecting, and extracting `Span` contexts, enabling the establishment and management of distributed tracing. ### Method N/A (This is a class for instantiation and usage) ### Endpoint N/A ### Parameters N/A ### Request Example ```java import com.alipay.common.tracer.core.SofaTracer; import com.alipay.common.tracer.core.span.SofaTracerSpan; import com.alipay.common.tracer.core.reporter.digest.DiskReporterImpl; import io.opentracing.tag.Tags; // Using Builder pattern to create SofaTracer instance SofaTracer sofaTracer = new SofaTracer.Builder("MyTracerType") .withClientReporter(new DiskReporterImpl("client-digest.log", ...)) .withServerReporter(new DiskReporterImpl("server-digest.log", ...)) .withTag("app.name", "my-application") .withTag("env", "production") .build(); // Create a root Span SofaTracerSpan rootSpan = (SofaTracerSpan) sofaTracer .buildSpan("http-request") .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) .withTag("request.url", "/api/users") .start(); // Create a child Span (inherits traceId from parent Span) SofaTracerSpan childSpan = (SofaTracerSpan) sofaTracer .buildSpan("database-query") .asChildOf(rootSpan) .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) .withTag("db.type", "mysql") .start(); // Execute business logic... // Finish Span (triggers log recording) childSpan.finish(); rootSpan.finish(); // Close Tracer sofaTracer.close(); ``` ### Response N/A (This is a code example for usage, not an API endpoint response.) ``` -------------------------------- ### SofaTracerSpanContext - Context Management Source: https://context7.com/sofastack/sofa-tracer/llms.txt SofaTracerSpanContext holds the context information for a Span, including traceId, spanId, sampling status, and baggage data. This example illustrates creating contexts, managing child IDs, setting and retrieving baggage items, serialization/deserialization, and sampling control. ```APIDOC ## SofaTracerSpanContext - Context Management ### Description `SofaTracerSpanContext` stores the contextual information for a `Span`, such as the trace ID, span ID, sampling decision, and baggage items. It facilitates the propagation of tracing information across distributed systems. ### Method N/A (This is a class for instantiation and usage) ### Endpoint N/A ### Parameters N/A ### Request Example ```java import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; import java.util.HashMap; import java.util.Map; // Create a root context SofaTracerSpanContext rootContext = SofaTracerSpanContext.rootStart(); String traceId = rootContext.getTraceId(); // Automatically generates a unique traceId String spanId = rootContext.getSpanId(); // Root spanId is "0" // Create a context with specified parameters SofaTracerSpanContext context = new SofaTracerSpanContext( "trace-id-123", // traceId "0.1", // spanId "0", // parentId true // isSampled ); // Get the ID for the next child Span String nextChildId = context.nextChildContextId(); // Returns "0.1.1" String lastChildId = context.lastChildContextId(); // Returns "0.1.0" // Business baggage data (for cross-process propagation) context.setBizBaggageItem("order.id", "ORD-001"); context.setBizBaggageItem("tenant.id", "TENANT-A"); String orderId = context.getBizBaggageItem("order.id"); // System baggage data context.setSysBaggageItem("trace.version", "2.0"); String version = context.getSysBaggageItem("trace.version"); // Add baggage items in bulk Map bizBaggage = new HashMap<>(); bizBaggage.put("user.name", "john"); bizBaggage.put("user.role", "admin"); context.addBizBaggage(bizBaggage); // Serialization and deserialization String serialized = context.serializeSpanContext(); // Format: "tcid=xxx&spid=xxx&pspid=xxx&sample=true&key1=value1..." SofaTracerSpanContext restored = SofaTracerSpanContext .deserializeFromString(serialized); // Sampling control context.setSampled(true); boolean sampled = context.isSampled(); // Clone context SofaTracerSpanContext cloned = context.cloneInstance(); ``` ### Response N/A (This is a code example for usage, not an API endpoint response.) ``` -------------------------------- ### Get TraceId in Controller Source: https://context7.com/sofastack/sofa-tracer/llms.txt In a Spring MVC controller, you can retrieve the current Span to add custom tags or extract the traceId for logging. ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.alipay.sofa.tracer.plugins.web.SofaTraceContextHolder; import com.alipay.sofa.tracer.core.span.SofaTracerSpan; import java.util.Map; import java.util.HashMap; import java.util.logging.Logger; @RestController public class UserController { private static final Logger logger = Logger.getLogger(UserController.class.getName()); // Assume userService is injected private UserService userService; @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { SofaTracerSpan span = SofaTraceContextHolder .getSofaTraceContext().getCurrentSpan(); if (span != null) { span.setTag("user.id", id.toString()); String traceId = span.getSofaTracerSpanContext().getTraceId(); logger.info("Processing request, traceId={}", traceId); } return userService.getUserById(id); } // Dummy classes for compilation static class User {} static class UserService { public User getUserById(Long id) { return new User(); } } static class OrderRequest {} static class Order {} static class OrderRepository { public Order save(Order order) { return order; } } } ``` -------------------------------- ### SofaTracerSpan - Span Representation Source: https://context7.com/sofastack/sofa-tracer/llms.txt SofaTracerSpan represents an operation unit within a distributed call chain. It includes operation name, timestamps, tags, and logs. This example shows how to set tags, operation names, log events, baggage items, report errors, and manage the span lifecycle. ```APIDOC ## SofaTracerSpan - Span Representation ### Description `SofaTracerSpan` represents a single operation within a distributed trace. It encapsulates details such as the operation name, start and end times, tags, and logged events. This class allows for detailed instrumentation of code execution paths. ### Method N/A (This is a class for instantiation and usage) ### Endpoint N/A ### Parameters N/A ### Request Example ```java import com.alipay.common.tracer.core.span.SofaTracerSpan; import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; import io.opentracing.tag.Tags; import java.util.HashMap; import java.util.Map; // Assume 'span' is an instance of SofaTracerSpan // Set Span tags span.setTag("http.method", "GET"); span.setTag("http.status_code", 200); span.setTag(Tags.ERROR.getKey(), false); // Set operation name span.setOperationName("getUserById"); // Log events span.log("Processing started"); span.log(System.currentTimeMillis(), "Database query executed"); // Log structured data using a Map Map logFields = new HashMap<>(); logFields.put("event", "error"); logFields.put("error.message", "Connection timeout"); span.log(logFields); // Set Baggage (data to be propagated across processes) span.setBaggageItem("user.id", "12345"); span.setBaggageItem("request.source", "mobile-app"); // Get Baggage items String userId = span.getBaggageItem("user.id"); // Report an error span.reportError("timeout_error", new HashMap() {{ put("timeout", "5000ms"); }}, new TimeoutException("Request timeout"), "my-app", "downstream-service"); // Get Span context SofaTracerSpanContext context = span.getSofaTracerSpanContext(); String traceId = context.getTraceId(); String spanId = context.getSpanId(); // Clone Span SofaTracerSpan clonedSpan = span.cloneInstance(); // Finish Span span.finish(); ``` ### Response N/A (This is a code example for usage, not an API endpoint response.) ``` -------------------------------- ### Initialize and Use SofaTracer Source: https://context7.com/sofastack/sofa-tracer/llms.txt Demonstrates creating a SofaTracer instance using the Builder pattern and managing Span lifecycles for root and child operations. ```java import com.alipay.common.tracer.core.SofaTracer; import com.alipay.common.tracer.core.span.SofaTracerSpan; import com.alipay.common.tracer.core.reporter.digest.DiskReporterImpl; import io.opentracing.tag.Tags; // 使用 Builder 模式创建 SofaTracer 实例 SofaTracer sofaTracer = new SofaTracer.Builder("MyTracerType") .withClientReporter(new DiskReporterImpl("client-digest.log", ...)) .withServerReporter(new DiskReporterImpl("server-digest.log", ...)) .withTag("app.name", "my-application") .withTag("env", "production") .build(); // 创建根 Span SofaTracerSpan rootSpan = (SofaTracerSpan) sofaTracer .buildSpan("http-request") .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) .withTag("request.url", "/api/users") .start(); // 创建子 Span (继承父 Span 的 traceId) SofaTracerSpan childSpan = (SofaTracerSpan) sofaTracer .buildSpan("database-query") .asChildOf(rootSpan) .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) .withTag("db.type", "mysql") .start(); // 执行业务逻辑... // 结束 Span (触发日志记录) childSpan.finish(); rootSpan.finish(); // 关闭 Tracer sofaTracer.close(); ``` -------------------------------- ### Configure SofaTracerSpanContext Source: https://context7.com/sofastack/sofa-tracer/llms.txt Demonstrates context creation, Baggage management, serialization, and sampling control. ```java import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; // 创建根节点上下文 SofaTracerSpanContext rootContext = SofaTracerSpanContext.rootStart(); String traceId = rootContext.getTraceId(); // 自动生成唯一的 traceId String spanId = rootContext.getSpanId(); // 根节点 spanId 为 "0" // 创建指定参数的上下文 SofaTracerSpanContext context = new SofaTracerSpanContext( "trace-id-123", // traceId "0.1", // spanId "0", // parentId true // isSampled ); // 获取下一个子 Span 的 ID String nextChildId = context.nextChildContextId(); // 返回 "0.1.1" String lastChildId = context.lastChildContextId(); // 返回 "0.1.0" // 业务透传数据 (Baggage) context.setBizBaggageItem("order.id", "ORD-001"); context.setBizBaggageItem("tenant.id", "TENANT-A"); String orderId = context.getBizBaggageItem("order.id"); // 系统透传数据 context.setSysBaggageItem("trace.version", "2.0"); String version = context.getSysBaggageItem("trace.version"); // 批量添加 Baggage Map bizBaggage = new HashMap<>(); bizBaggage.put("user.name", "john"); bizBaggage.put("user.role", "admin"); context.addBizBaggage(bizBaggage); // 序列化与反序列化 String serialized = context.serializeSpanContext(); // 格式: "tcid=xxx&spid=xxx&pspid=xxx&sample=true&key1=value1..." SofaTracerSpanContext restored = SofaTracerSpanContext .deserializeFromString(serialized); // 采样控制 context.setSampled(true); boolean sampled = context.isSampled(); // 克隆上下文 SofaTracerSpanContext cloned = context.cloneInstance(); ``` -------------------------------- ### Configure Custom Sampler Source: https://context7.com/sofastack/sofa-tracer/llms.txt Build a SofaTracer instance and provide your custom sampler implementation during the builder phase. ```java import com.alipay.sofa.tracer.core.SofaTracer; SofaTracer tracer = new SofaTracer.Builder("MyTracer") .withSampler(new CustomSampler(0.1)) // 10% 采样率 .build(); ``` -------------------------------- ### Integrate SOFATracer with Zipkin Source: https://context7.com/sofastack/sofa-tracer/llms.txt Configure ZipkinSofaTracerSpanRemoteReporter to export trace data to a Zipkin server. ```java import com.alipay.sofa.tracer.plugins.zipkin.ZipkinSofaTracerSpanRemoteReporter; import com.alipay.common.tracer.core.listener.SpanReportListenerHolder; import org.springframework.web.client.RestTemplate; // 配置 Zipkin Reporter RestTemplate restTemplate = new RestTemplate(); String zipkinBaseUrl = "http://localhost:9411"; ZipkinSofaTracerSpanRemoteReporter zipkinReporter = new ZipkinSofaTracerSpanRemoteReporter(restTemplate, zipkinBaseUrl); // 注册为全局 Span 报告监听器 SpanReportListenerHolder.addSpanReportListener(zipkinReporter); // 所有 Span 结束时会自动上报到 Zipkin // 手动刷新缓冲区 zipkinReporter.flush(); // 关闭 Reporter zipkinReporter.close(); ``` -------------------------------- ### Logback Configuration for MDC Source: https://context7.com/sofastack/sofa-tracer/llms.txt Configure Logback to include SOFATracer's traceId and spanId in log messages using MDC variables %X{SOFA-TraceId} and %X{SOFA-SpanId}. ```xml %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{SOFA-TraceId},%X{SOFA-SpanId}] [%thread] %-5level %logger{36} - %msg%n ``` -------------------------------- ### Implement Flexible Tracing with FlexibleTracer Source: https://context7.com/sofastack/sofa-tracer/llms.txt FlexibleTracer supports manual span creation or declarative tracing via the @Tracer annotation. Annotation-based tracing requires Spring AOP integration. ```java import com.alipay.sofa.tracer.plugin.flexible.FlexibleTracer; import com.alipay.sofa.tracer.plugin.flexible.annotations.Tracer; import com.alipay.common.tracer.core.span.SofaTracerSpan; // 创建 FlexibleTracer 实例 FlexibleTracer flexibleTracer = new FlexibleTracer(); // 手动埋点方式 public void manualTracingExample() { // 开始跟踪 SofaTracerSpan span = flexibleTracer.beforeInvoke("myBusinessMethod"); try { // 执行业务逻辑 doBusinessLogic(); // 正常结束 flexibleTracer.afterInvoke(); } catch (Exception e) { // 异常结束,记录错误信息 flexibleTracer.afterInvoke(e.getMessage()); throw e; } } // 注解方式 (需要配合 Spring AOP) @Service public class UserService { @Tracer(operateName = "createUser") public User createUser(String name, String email) { // 方法执行会自动被跟踪 User user = new User(name, email); userRepository.save(user); return user; } @Tracer(operateName = "getUserById") public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new UserNotFoundException(id)); } @Tracer // 不指定 operateName 时使用方法名 public List listAllUsers() { return userRepository.findAll(); } } ``` -------------------------------- ### Implement Custom Reporter and SpanEncoder Source: https://context7.com/sofastack/sofa-tracer/llms.txt Define a custom SpanEncoder to format span data and initialize a DiskReporterImpl for local logging. ```java import com.alipay.common.tracer.core.reporter.facade.Reporter; import com.alipay.common.tracer.core.reporter.digest.DiskReporterImpl; import com.alipay.common.tracer.core.appender.encoder.SpanEncoder; import com.alipay.common.tracer.core.span.SofaTracerSpan; // 自定义 SpanEncoder public class CustomSpanEncoder implements SpanEncoder { @Override public String encode(SofaTracerSpan span) { StringBuilder sb = new StringBuilder(); sb.append(span.getSofaTracerSpanContext().getTraceId()).append(","); sb.append(span.getSofaTracerSpanContext().getSpanId()).append(","); sb.append(span.getOperationName()).append(","); sb.append(span.getDurationMicroseconds()).append("ms"); return sb.toString(); } } // 创建磁盘 Reporter Reporter diskReporter = new DiskReporterImpl( "my-service-digest.log", // 日志文件名 ".yyyy-MM-dd", // 滚动策略 "7", // 保留天数 new CustomSpanEncoder(), // 摘要日志编码器 null, // 统计 Reporter (可选) "my-service-digest" // 日志名称 Key ); // 上报 Span diskReporter.report(span); // 关闭 Reporter diskReporter.close(); ``` -------------------------------- ### Define SOFATracer Properties Source: https://context7.com/sofastack/sofa-tracer/llms.txt Set global tracing parameters such as log policies, sampling, and output formats in application.properties. ```properties # application.properties # 应用名称 (必需) spring.application.name=my-application # 全局日志滚动策略 (按天/按小时) com.alipay.sofa.tracer.tracerGlobalRollingPolicy=.yyyy-MM-dd # 全局日志保留天数 com.alipay.sofa.tracer.tracerGlobalLogReserveDay=7 # 禁用所有摘要日志 com.alipay.sofa.tracer.disableDigestLog=false # 禁用特定类型的摘要日志 com.alipay.sofa.tracer.disableConfiguration[spring-mvc-digest]=true # 统计日志输出间隔 (秒) com.alipay.sofa.tracer.statLogInterval=60 # Baggage 最大长度 com.alipay.sofa.tracer.baggageMaxLength=1024 # JSON 格式输出 com.alipay.sofa.tracer.jsonOutput=true # 采样配置 com.alipay.sofa.tracer.samplerName=PercentageBasedSampler com.alipay.sofa.tracer.samplerPercentage=100 # 自定义采样规则类 com.alipay.sofa.tracer.samplerCustomRuleClassName=com.example.MySampler ``` -------------------------------- ### Configure Spring MVC Tracer Filter Source: https://context7.com/sofastack/sofa-tracer/llms.txt Register the SpringMvcSofaTracerFilter as a bean to enable automatic HTTP request tracing. ```java import com.alipay.sofa.tracer.plugins.springmvc.SpringMvcSofaTracerFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TracerConfiguration { @Bean public FilterRegistrationBean sofaTracerFilter() { FilterRegistrationBean registration = new FilterRegistrationBean<>(); SpringMvcSofaTracerFilter filter = new SpringMvcSofaTracerFilter(); filter.setAppName("my-web-app"); registration.setFilter(filter); registration.addUrlPatterns("/*"); registration.setName("sofaTracerFilter"); registration.setOrder(1); return registration; } } // 自动记录的信息包括: // - request.url: 请求 URL // - method: HTTP 方法 (GET/POST/...) // - req.size: 请求体大小 // - resp.size: 响应体大小 // - result.code: HTTP 状态码 // - local.app: 应用名称 // - error: 错误信息 (如有) ``` -------------------------------- ### Logging with TraceId and SpanId Source: https://context7.com/sofastack/sofa-tracer/llms.txt When using SLF4J with MDC integration, traceId and spanId are automatically included in log output, aiding in correlating logs across distributed systems. ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @Service public class OrderService { private static final Logger logger = LoggerFactory.getLogger(OrderService.class); // Assume orderRepository is injected private OrderRepository orderRepository; public Order createOrder(OrderRequest request) { logger.info("Creating order for user: {}", request.getUserId()); Order order = orderRepository.save(request.toOrder()); logger.info("Order created successfully: {}", order.getId()); return order; } // Dummy classes for compilation static class OrderRequest { public String getUserId() { return "123"; } public Order toOrder() { return new Order(); } } static class Order { public String getId() { return "order-123"; } } static class OrderRepository { public Order save(Order order) { return order; } } } ``` -------------------------------- ### Manage SofaTracerSpan Operations Source: https://context7.com/sofastack/sofa-tracer/llms.txt Covers setting tags, logging events, managing Baggage items, and reporting errors within a Span. ```java import com.alipay.common.tracer.core.span.SofaTracerSpan; import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; import io.opentracing.tag.Tags; // 设置 Span 标签 span.setTag("http.method", "GET"); span.setTag("http.status_code", 200); span.setTag(Tags.ERROR.getKey(), false); // 设置操作名称 span.setOperationName("getUserById"); // 记录日志事件 span.log("Processing started"); span.log(System.currentTimeMillis(), "Database query executed"); // 使用 Map 记录结构化日志 Map logFields = new HashMap<>(); logFields.put("event", "error"); logFields.put("error.message", "Connection timeout"); span.log(logFields); // 设置 Baggage (跨进程透传数据) span.setBaggageItem("user.id", "12345"); span.setBaggageItem("request.source", "mobile-app"); // 获取 Baggage String userId = span.getBaggageItem("user.id"); // 报告错误 span.reportError("timeout_error", new HashMap() {{ put("timeout", "5000ms"); }}, new TimeoutException("Request timeout"), "my-app", "downstream-service"); // 获取 Span 上下文 SofaTracerSpanContext context = span.getSofaTracerSpanContext(); String traceId = context.getTraceId(); String spanId = context.getSpanId(); // 克隆 Span SofaTracerSpan clonedSpan = span.cloneInstance(); // 结束 Span span.finish(); ``` -------------------------------- ### Propagate Trace Context Across Threads Source: https://context7.com/sofastack/sofa-tracer/llms.txt Use SofaTracerRunnable, SofaTracerCallable, or TracedExecutorService to automatically propagate trace context to asynchronous tasks. ```java import com.alipay.common.tracer.core.async.SofaTracerRunnable; import com.alipay.common.tracer.core.async.SofaTracerCallable; import com.alipay.common.tracer.core.async.TracedExecutorService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; ExecutorService executor = Executors.newFixedThreadPool(10); // 方式一:使用 SofaTracerRunnable 包装 Runnable task = () -> { // 此处可以获取到父线程的 traceId SofaTracerSpan currentSpan = SofaTraceContextHolder .getSofaTraceContext().getCurrentSpan(); System.out.println("TraceId: " + currentSpan.getSofaTracerSpanContext().getTraceId()); // 执行业务逻辑... }; // 自动捕获当前线程上下文并传递 executor.submit(new SofaTracerRunnable(task)); // 方式二:使用 SofaTracerCallable 包装 Callable callable = () -> { SofaTracerSpan span = SofaTraceContextHolder .getSofaTraceContext().getCurrentSpan(); // 执行业务逻辑... return "result-" + span.getSofaTracerSpanContext().getTraceId(); }; Future future = executor.submit(new SofaTracerCallable<>(callable)); String result = future.get(); // 方式三:使用 TracedExecutorService 包装整个线程池 ExecutorService tracedExecutor = new TracedExecutorService( executor, SofaTraceContextHolder.getSofaTraceContext() ); // 所有提交的任务自动传递上下文 tracedExecutor.submit(() -> { // 自动获取到父线程的跟踪上下文 doAsyncWork(); }); // CompletableFuture 场景 CompletableFuture.supplyAsync( new SofaTracerCallable<>(() -> fetchData()), tracedExecutor ).thenAccept(data -> processData(data)); ``` -------------------------------- ### Manage Thread-Local Span Context with SofaTraceContextHolder Source: https://context7.com/sofastack/sofa-tracer/llms.txt Use SofaTraceContextHolder to push, pop, and inspect spans within a single thread. Ensure spans are finished after popping to avoid resource leaks. ```java import com.alipay.common.tracer.core.holder.SofaTraceContextHolder; import com.alipay.common.tracer.core.context.trace.SofaTraceContext; import com.alipay.common.tracer.core.span.SofaTracerSpan; // 获取当前线程的 Trace 上下文 SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); // 将 Span 压入线程上下文栈 sofaTraceContext.push(serverSpan); // 获取当前 Span (不移除) SofaTracerSpan currentSpan = sofaTraceContext.getCurrentSpan(); // 弹出当前 Span SofaTracerSpan poppedSpan = sofaTraceContext.pop(); // 检查栈是否为空 boolean isEmpty = sofaTraceContext.isEmpty(); // 获取栈大小 int size = sofaTraceContext.getThreadLocalSpanSize(); // 清空线程上下文 sofaTraceContext.clear(); // 典型使用场景:服务端接收请求 public void handleRequest(HttpServletRequest request) { SofaTraceContext ctx = SofaTraceContextHolder.getSofaTraceContext(); // 创建服务端 Span SofaTracerSpan serverSpan = createServerSpan(request); ctx.push(serverSpan); try { // 处理业务逻辑 processBusinessLogic(); // 调用下游服务时创建客户端 Span SofaTracerSpan clientSpan = createClientSpan(); ctx.push(clientSpan); try { callDownstreamService(); } finally { ctx.pop().finish(); // 结束客户端 Span } } finally { ctx.pop().finish(); // 结束服务端 Span } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.