### Start JVM Service with Agent Options Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Example of starting a Java application with agent options and custom service name. Ensure `${agent_opts}` is included for agent installation. ```bash home="$(cd "$(dirname $0)"; pwd)" java -jar ${agent_opts} "-Dskywalking.agent.service_name=jettyserver-scenario" ${home}/../libs/jettyserver-scenario.jar & sleep 1 java -jar ${agent_opts} "-Dskywalking.agent.service_name=jettyclient-scenario" ${home}/../libs/jettyclient-scenario.jar & ``` -------------------------------- ### JVM Agent Configuration Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Example configuration for the SkyWalking Java agent, specifying agent type, entry and health check endpoints, startup script, running mode, environment variables, and external service dependencies. ```yaml type: jvm # or tomcat entryService: http://localhost:8080/case # Entry endpoint (GET) healthCheck: http://localhost:8080/health # Health check endpoint (HEAD) startScript: ./bin/startup.sh # JVM-container only runningMode: default # default|with_optional|with_bootstrap withPlugins: apm-spring-annotation-plugin-*.jar # For optional/bootstrap modes environment: - KEY=value dependencies: # External services (docker-compose style) mysql: image: mysql:8.0 hostname: mysql environment: - MYSQL_ROOT_PASSWORD=root ``` -------------------------------- ### Full Maven Build with Tests Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Execute a clean install of the entire project, including running all tests. ```bash ./mvnw clean install ``` -------------------------------- ### GitHub Actions Job Configuration Example Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Example of a GitHub Actions job configuration for running plugin tests. This snippet shows how to define a job that runs on Ubuntu and includes a matrix strategy for test cases. ```yaml jobs: PluginsTest: name: Plugin runs-on: ubuntu-latest timeout-minutes: 90 strategy: fail-fast: true matrix: case: # ... - # ... ``` -------------------------------- ### Support Version List Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md A list of supported versions for the agent, with optional Maven properties for specific versions. Comments are supported using '#'. ```list # One version per line, use # for comments # Only include ONE version per minor version (not all patch versions) 4.3.6 4.4.1 4.5.0 # Optional: extra Maven properties per version (comma-separated key=value) # Useful when different versions need different dependency versions 2.7.14,spring.boot.version=2.5.15 ``` -------------------------------- ### Compiling Protobuf Sources Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Command to compile protobuf sources, necessary for IDE setup. ```bash ./mvnw compile -Dmaven.test.skip=true ``` -------------------------------- ### Release Script Quick Start Source: https://github.com/apache/skywalking-java/blob/main/docs/en/contribution/release-java-agent.md Commands to initiate the release process using the `release.sh` script. Includes preparing for vote and promoting after the vote passes. ```shell # Step 1: Build, stage, upload, and generate vote email ./tools/releasing/release.sh prepare-vote x.y.z # (send vote email to dev@skywalking.apache.org, wait 72h for vote to pass) # Step 2: Promote, push Docker images, generate announce email, and clean up ./tools/releasing/release.sh vote-passed [old_version_to_remove] ``` -------------------------------- ### Example Meter Creation Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Demonstrates how to create and operate a counter and a histogram meter using the MeterFactory. This is typically done within a meter plugin. ```java MeterFactory.counter("test_counter").tag("ck1", "cv1").build().increment(1d); MeterFactory.histogram("test_histogram").tag("hk1", "hv1").steps(1d, 5d, 10d).build().addValue(2d); ``` -------------------------------- ### Initialize OpenTracing Tracer Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Opentracing.md Instantiate the SkywalkingTracer and create a SpanBuilder for tracing requests. This is the basic setup for using OpenTracing with SkyWalking. ```java Tracer tracer = new SkywalkingTracer(); Tracer.SpanBuilder spanBuilder = tracer.buildSpan("/yourApplication/yourService"); ``` -------------------------------- ### CI Maven Build with Javadoc Verification Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Run a comprehensive Maven build for CI environments, including verification, installation, and Javadoc generation with verification. ```bash ./mvnw clean verify install javadoc:javadoc ``` -------------------------------- ### GatewayFilter Example Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/agent-optional-plugins/spring-gateway.md A basic example of a GatewayFilter that logs a message when it runs. It demonstrates the standard filter execution flow within Spring Gateway. ```java import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component public class GatewayFilter1 implements GatewayFilter { private static final Logger log = LoggerFactory.getLogger(GatewayFilter1.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // Available trace context log.info("gatewayFilter1 running"); return chain.filter(exchange); } } ``` -------------------------------- ### JVM Container Startup Script Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md A bash script for starting the SkyWalking Java agent within a JVM container. It requires the `agent_opts` variable to be set with agent parameters. ```bash #!/bin/bash home="$(cd "$(dirname $0)"; pwd)" # ${agent_opts} is REQUIRED - contains agent parameters java -jar ${agent_opts} ${home}/../libs/your-scenario.jar & ``` -------------------------------- ### JAR File Application Agent Configuration Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/README.md Add the -javaagent argument to the JVM command line when starting a JAR file application. ```shell java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -jar yourApp.jar ``` -------------------------------- ### Logback Configuration with AsyncAppender and MDC Trace ID Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-logback-1.x.md Example logback.xml configuration demonstrating the use of AsyncAppender along with TraceIdMDCPatternLogbackLayout for printing trace IDs. No additional configuration is needed for AsyncAppender support. ```xml %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n 0 1024 true ``` -------------------------------- ### Configuration Discovery Service (CDS) YAML Format Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/configuration-discovery.md Example of the YAML format used for dynamic configurations fetched by the CDS. This structure defines service names and their associated configurations. ```yaml configurations: //service name serviceA: // Configurations of service A // Key and Value are determined by the agent side. // Check the agent setup doc for all available configurations. key1: value1 key2: value2 ... serviceB: ... ``` -------------------------------- ### V2 Instrumentation Class Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Defines the instrumentation for a target class using the V2 API. Specify the class to enhance and the interceptor for instance methods. ```java public class XxxInstrumentation extends ClassInstanceMethodsEnhancePluginDefineV2 { @Override protected ClassMatch enhanceClass() { return NameMatch.byName("target.class.Name"); } @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[] { ... }; } @Override public InstanceMethodsInterceptV2Point[] getInstanceMethodsInterceptV2Points() { return new InstanceMethodsInterceptV2Point[] { new InstanceMethodsInterceptV2Point() { @Override public ElementMatcher getMethodsMatcher() { return named("targetMethod"); } @Override public String getMethodsInterceptorV2() { return "org.apache.skywalking.apm.plugin.xxx.XxxInterceptor"; } @Override public boolean isOverrideArgs() { return false; } } }; } } ``` -------------------------------- ### Meter Plugin Expectation Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Defines expected meter items for testing meter plugins. Includes service name, meter size, and details for counters, gauges, and histograms. ```yaml meterItems: - serviceName: your-scenario meterSize: ge 1 meters: - meterId: name: test_counter tags: - {name: key1, value: value1} # Note: uses 'name' not 'key' singleValue: gt 0 # For counter/gauge - meterId: name: test_histogram tags: - {name: key1, value: value1} histogramBuckets: # For histogram - 0.0 - 1.0 - 5.0 - 10.0 ``` -------------------------------- ### Maven POM Configuration for Test Framework Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Example Maven POM configuration specifying the test framework version and dependency. The `finalName` should match the test case folder name. ```xml 4.3 org.apache.httpcomponents httpclient ${test.framework.version} ... httpclient-4.3.x-scenario .... ``` -------------------------------- ### SegmentA Span List Example Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Illustrates the expected spans for SegmentA, representing the Case Servlet access. Includes Tomcat entry span and HttpClient exit span. ```yaml - segmentId: not null spans: - operationName: /httpclient-case/case/context-propagate parentSpanId: 0 spanId: 1 startTime: nq 0 endTime: nq 0 isError: false spanLayer: Http spanType: Exit componentId: eq 2 tags: - {key: url, value: 'http://127.0.0.1:8080/httpclient-case/case/context-propagate'} - {key: http.method, value: GET} - {key: http.status_code, value: '200'} logs: [] peer: 127.0.0.1:8080 - operationName: /httpclient-case/case/httpclient parentSpanId: -1 spanId: 0 startTime: nq 0 endTime: nq 0 spanLayer: Http isError: false spanType: Entry componentId: 1 tags: - {key: url, value: 'http://localhost:{SERVER_OUTPUT_PORT}/httpclient-case/case/httpclient'} - {key: http.method, value: GET} - {key: http.status_code, value: '200'} logs: [] peer: null ``` -------------------------------- ### CI Workflow Configuration for Plugin Tests Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Example of how to add SkyWalking plugin tests to CI workflows. Specifies which workflow files to modify based on JDK version and provides a sample matrix configuration. ```yaml matrix: case: - your-scenario-scenario ``` -------------------------------- ### Trace Plugin Expectation Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Defines expected trace segment items for testing tracing plugins. Includes service name, segment size, and details of individual segments and spans. ```yaml segmentItems: - serviceName: your-scenario segmentSize: ge 1 # Operators: eq, ge, gt, nq segments: - segmentId: not null spans: - operationName: /your/endpoint parentSpanId: -1 # -1 for root span spanId: 0 spanLayer: Http # Http, DB, RPC_FRAMEWORK, MQ, CACHE, Unknown spanType: Entry # Entry, Exit, Local startTime: nq 0 endTime: nq 0 componentId: 1 isError: false peer: '' # Empty string for Entry/Local, required for Exit skipAnalysis: false tags: - {key: url, value: not null} - {key: http.method, value: GET} - {key: http.status_code, value: '200'} logs: [] refs: [] # SegmentRefs for cross-process/cross-thread ``` -------------------------------- ### Apply Custom Tags and Trace Annotation Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-trace.md Annotate methods with `@Trace` to enable tracing and use `@Tag` to add custom tags based on method arguments or return values. This example demonstrates adding multiple tags and tracing a method. ```java @Trace @Tag(key = "tag1", value = "arg[0]") @Tag(key = "tag2", value = "arg[1]") @Tag(key = "username", value = "returnedObj.username") @Tag(key = "age", value = "returnedObj.age") public User methodYouWantToTrace(String param1, String param2) { // ActiveSpan.setOperationName("Customize your own operation name, if this is an entry span, this would be an endpoint name"); // ... } ``` -------------------------------- ### Example of Enhanced Class with New Naming Policies Source: https://github.com/apache/skywalking-java/blob/main/changes/changes-9.0.0.md This Java code demonstrates how an enhanced class utilizes the new naming policies for auxiliary classes, fields, and methods. It includes examples of interceptor delegate fields, origin method cache values, and renamed origin methods. ```java import sample.mybatis.controller.HotelController$sw$auxiliary$19cja42; import sample.mybatis.controller.HotelController$sw$auxiliary$p257su0; import sample.mybatis.domain.Hotel; import sample.mybatis.service.HotelService; @RequestMapping(value={"/hotel"}) @RestController public class HotelController implements EnhancedInstance { @Autowired @lazy private HotelService hotelService; private volatile Object _$EnhancedClassField_ws; // Interceptor delegate fields public static volatile /* synthetic */ InstMethodsInter sw$delegate$td03673$ain2do0$8im5jm1; public static volatile /* synthetic */ InstMethodsInter sw$delegate$td03673$ain2do0$edkmf61; public static volatile /* synthetic */ ConstructorInter sw$delegate$td03673$ain2do0$qs9unv1; public static volatile /* synthetic */ InstMethodsInter sw$delegate$td03673$fl4lnk1$m3ia3a2; public static volatile /* synthetic */ InstMethodsInter sw$delegate$td03673$fl4lnk1$sufrvp1; public static volatile /* synthetic */ ConstructorInter sw$delegate$td03673$fl4lnk1$cteu7s1; // Origin method cache value field private static final /* synthetic */ Method cachedValue$sw$td03673$g5sobj1; public HotelController() { this(null); sw$delegate$td03673$ain2do0$qs9unv1.intercept(this, new Object[0]); } private /* synthetic */ HotelController(sw.auxiliary.p257su0 p257su02) { } @GetMapping(value={"city/{cityId}"}) public Hotel selectByCityId(@PathVariable(value="cityId") int n) { // call interceptor with auxiliary type and parameters and origin method object return (Hotel)sw$delegate$td03673$ain2do0$8im5jm1.intercept(this, new Object[]{n}, new HotelController$sw$auxiliary$19cja42(this, n), cachedValue$sw$td03673$g5sobj1); } // Renamed origin method private /* synthetic */ Hotel sw$origin$selectByCityId$a8458p3(int cityId) { /*22*/ return this.hotelService.selectByCityId(cityId); } // Accessor of renamed origin method, calling from auxiliary type final /* synthetic */ Hotel sw$origin$selectByCityId$a8458p3$accessor$sw$td03673(int n) { // Calling renamed origin method return this.sw$origin$selectByCityId$a8458p3(n); } @OverRide public Object getSkyWalkingDynamicField() { return this._$EnhancedClassField_ws; } @OverRide public void setSkyWalkingDynamicField(Object object) { this._$EnhancedClassField_ws = object; } static { ClassLoader.getSystemClassLoader().loadClass("org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.Nexus").getMethod("initialize", Class.class, Integer.TYPE).invoke(null, HotelController.class, -1072476370); // Method object cachedValue$sw$td03673$g5sobj1 = HotelController.class.getMethod("selectByCityId", Integer.TYPE); } } ``` -------------------------------- ### Support Version List Format with Maven Properties Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Demonstrates the format for the `support-version.list` file, showing how to specify target versions and optionally include Maven properties for dependency version overrides. ```text # Simple version 2.3.10.RELEASE # Version with extra Maven properties (passed as -D flags) 2.7.14,spring.boot.version=2.5.15 ``` -------------------------------- ### Define an Annotated Exception Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md Example of a custom exception class annotated with @IgnoredException. ```java package org.apache.skywalking.apm.agent.core.context.status; @IgnoredException public class TestAnnotatedException extends RuntimeException { public TestAnnotatedException() { } public TestAnnotatedException(final String message) { super(message); } ... } ``` -------------------------------- ### Define a Custom Exception Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md Example of a custom exception class that extends RuntimeException. ```java package org.apache.skywalking.apm.agent.core.context.status; public class TestNamedMatchException extends RuntimeException { public TestNamedMatchException() { } public TestNamedMatchException(final String message) { super(message); } ... } ``` -------------------------------- ### Compile from Downloaded Source Source: https://github.com/apache/skywalking-java/blob/main/docs/en/contribution/compiling.md Compile the SkyWalking Java project from downloaded source code archives using the Maven wrapper. ```shell ./mvnw clean package ``` -------------------------------- ### Initialize Observation Registry with Skywalking Handlers Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer-1.10.md Configure the Micrometer Observation Registry with Skywalking's meter and tracing handlers to enable metrics and trace collection. ```java // Here we create the Observation Registry with attached handlers ObservationRegistry registry = ObservationRegistry.create(); // Here we add a meter handler registry.observationConfig() .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler( new SkywalkingMeterHandler(new SkywalkingMeterRegistry()) ); // Here we add tracing handlers registry.observationConfig() .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler( new SkywalkingSenderTracingHandler(), new SkywalkingReceiverTracingHandler(), new SkywalkingDefaultTracingHandler() )); ``` -------------------------------- ### Define a Hierarchical Custom Exception Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/How-to-tolerate-exceptions.md Example of a custom exception class that extends another custom exception. ```java package org.apache.skywalking.apm.agent.core.context.status; public class TestHierarchyMatchException extends TestNamedMatchException { public TestHierarchyMatchException() { } public TestHierarchyMatchException(final String message) { super(message); } ... } ``` -------------------------------- ### Get Segment ID Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-trace-read-context.md Retrieve the current segment ID using the `TraceContext.segmentId()` API. This information is accessible only when the thread is under tracing. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("segmentId", TraceContext.segmentId()); ``` -------------------------------- ### Get Trace ID Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-trace-read-context.md Obtain the current trace ID using the `TraceContext.traceId()` API. This value is only available when the current thread is traced. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("traceId", TraceContext.traceId()); ``` -------------------------------- ### Set Up Witness Methods for Plugin Activation Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Java-Plugin-Development-Guide.md Optionally, define `witnessMethods` to activate the plugin only when specific methods exist in the target application. ```java // The plugin is activated only when the foo.Bar#hello method exists. @Override protected List witnessMethods() { List witnessMethodList = new ArrayList<>(); WitnessMethod witnessMethod = new WitnessMethod("foo.Bar", ElementMatchers.named("hello")); witnessMethodList.add(witnessMethod); return witnessMethodList; } ``` -------------------------------- ### Docker Build Commands Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Commands to build the Docker image for the SkyWalking Java Agent. ```bash make build make docker ``` -------------------------------- ### Clone and Compile from GitHub Source: https://github.com/apache/skywalking-java/blob/main/docs/en/contribution/compiling.md Clone the SkyWalking Java repository from GitHub and compile the project using Maven wrapper. ```shell git clone https://github.com/apache/skywalking-java.git cd skywalking-java ./mvnw clean package -Pall ``` -------------------------------- ### Kafka Consumer with Poll and Invoke Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-kafka.md Example of a Kafka consumer thread that uses the pollAndInvoke method to process messages and make HTTP requests. ```java public class ConsumerThread2 extends Thread { @Override public void run() { Properties consumerProperties = new Properties(); //...consumerProperties.put() KafkaConsumer consumer = new KafkaConsumer<>(consumerProperties); consumer.subscribe(topicPattern, new NoOpConsumerRebalanceListener()); while (true) { if (pollAndInvoke(consumer)) break; } consumer.close(); } @KafkaPollAndInvoke private boolean pollAndInvoke(KafkaConsumer consumer) { try { Thread.sleep(1000); } catch (InterruptedException e) { } ConsumerRecords records = consumer.poll(100); if (!records.isEmpty()) { OkHttpClient client = new OkHttpClient.Builder().build(); Request request = new Request.Builder().url("http://localhost:8080/kafka-scenario/case/kafka-thread2-ping").build(); Response response = null; try { response = client.newCall(request).execute(); } catch (IOException e) { } response.body().close(); return true; } return false; } } ``` -------------------------------- ### Running Maven Tests Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Commands to execute unit tests, full verification including checkstyle, or skip tests during the build process. ```bash # Unit tests ./mvnw test ``` ```bash # Full verification including checkstyle ./mvnw clean verify ``` ```bash # Skip tests during build ./mvnw package -Dmaven.test.skip=true ``` -------------------------------- ### Get Span ID Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-trace-read-context.md Access the current span ID via the `TraceContext.spanId()` API. The span ID is available only if the current thread is being traced. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("spanId", TraceContext.spanId()); ``` -------------------------------- ### JVM-container Test Project Structure Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Illustrates the directory structure for a test project using the JVM-container base image. This includes directories for binaries, configuration, source code, and resource files. ```text [plugin-scenario] |- [bin] |- startup.sh |- [config] |- expectedData.yaml |- [src] |- [main] |- ... |- [resource] |- log4j2.xml |- pom.xml |- configuration.yml |- support-version.list [] = directory ``` -------------------------------- ### Set Up Witness Classes for Plugin Activation Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Java-Plugin-Development-Guide.md Optionally, define `witnessClasses` to activate the plugin only when specific classes exist in the target application. ```java // The plugin is activated only when the foo.Bar class exists. @Override protected String[] witnessClasses() { return new String[] { "foo.Bar" }; } ``` -------------------------------- ### Manipulate Correlation Context in Gateway Filter Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-webflux.md Set and get correlation data within a GatewayFilterChain using WebFluxSkyWalkingTraceContext. Useful for upstream and downstream nodes. ```java @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain){ // Set correlation data can be retrieved by upstream nodes. WebFluxSkyWalkingTraceContext.putCorrelation(exchange, "key1", "value"); // Get correlation data Optional value2 = WebFluxSkyWalkingTraceContext.getCorrelation(exchange, "key2"); // dosomething... return chain.filter(exchange); } ``` -------------------------------- ### Clone SkyWalking Java Agent with Submodules Source: https://github.com/apache/skywalking-java/blob/main/CLAUDE.md Clone the repository and initialize all Git submodules to ensure all necessary components are downloaded. ```bash git clone --recurse-submodules https://github.com/apache/skywalking-java.git ``` -------------------------------- ### SegmentB Span List Example Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Shows the expected spans for SegmentB, representing the ContextPropagateServlet access. Includes a Tomcat entry span and a cross-process reference to SegmentA. ```yaml - segmentId: not null spans: - operationName: /httpclient-case/case/context-propagate parentSpanId: -1 spanId: 0 tags: - {key: url, value: 'http://127.0.0.1:8080/httpclient-case/case/context-propagate'} - {key: http.method, value: GET} - {key: http.status_code, value: '200'} logs: [] startTime: nq 0 endTime: nq 0 spanLayer: Http isError: false spanType: Entry componentId: 1 peer: null refs: - {parentEndpoint: /httpclient-case/case/httpclient, networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: not null, traceId: not null} ``` -------------------------------- ### V2 Interceptor Class Example Source: https://github.com/apache/skywalking-java/blob/main/apm-sniffer/apm-sdk-plugin/CLAUDE.md Implements the V2 interceptor interface to define logic for method execution phases. Uses MethodInvocationContext to pass data between phases. ```java public class XxxInterceptor implements InstanceMethodsAroundInterceptorV2 { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInvocationContext context) { AbstractSpan span = ContextManager.createLocalSpan("operationName"); context.setContext(span); // Pass to afterMethod/handleMethodException } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret, MethodInvocationContext context) { AbstractSpan span = (AbstractSpan) context.getContext(); span.asyncFinish(); return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t, MethodInvocationContext context) { AbstractSpan span = (AbstractSpan) context.getContext(); span.log(t); } } ``` -------------------------------- ### Build and Push Specific Docker Images Source: https://github.com/apache/skywalking-java/blob/main/docs/en/contribution/compiling.md Build and push Docker images for the agent based on Alpine, Java 8, and Java 11 to a registry. ```shell make docker.push.alpine docker.push.java8 docker.push.java11 ``` -------------------------------- ### Kafka Reporter Basic Configuration Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/advanced-reporters.md Configure the Kafka reporter with backend service addresses and Kafka bootstrap servers. Ensure the Kafka fetcher is enabled in the OAP server. ```properties # Backend service addresses. collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800} # Kafka producer configuration plugin.kafka.bootstrap_servers=${SW_KAFKA_BOOTSTRAP_SERVERS:localhost:9092} plugin.kafka.get_topic_timeout=${SW_GET_TOPIC_TIMEOUT:10} ``` -------------------------------- ### Log formatted message with arguments Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-log4j-2.x.md Example of logging a formatted message with multiple arguments using `log.info`. When `transmit_formatted` is false, this will be sent as un-formatted data with 'argument.N' tags. ```java log.info("{} {} {}", 1, 2, 3); ``` -------------------------------- ### Create EntrySpan and Extract ContextCarrier (Server-side) Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Java-Plugin-Development-Guide.md This snippet shows how to extract context carrier information from HTTP headers and create an EntrySpan on the server side to continue distributed tracing. ```java ContextCarrier contextCarrier = new ContextCarrier(); CarrierItem next = contextCarrier.items(); while (next.hasNext()) { next = next.next(); next.setHeadValue(request.getHeader(next.getHeadKey())); } span = ContextManager.createEntrySpan(“/span/operation/name”, contextCarrier); ``` -------------------------------- ### Configure Trace Ignore Paths via Configuration File Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/agent-optional-plugins/trace-ignore-plugin.md Create an `apm-trace-ignore-plugin.config` file in the `/agent/config/` directory and define the `trace.ignore_path` property with comma-separated URL patterns to ignore. ```properties trace.ignore_path=/your/path/1/**,/your/path/2/** ``` -------------------------------- ### Example NoClassDefFoundError in OSGi Source: https://github.com/apache/skywalking-java/blob/main/docs/en/faq/osgi.md This stack trace illustrates a common `java.lang.NoClassDefFoundError` that occurs when the SkyWalking agent's classes are not accessible in an OSGi environment due to classloader isolation. ```java java.lang.NoClassDefFoundError: org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/EnhancedInstance at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419) at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383) at ch.qos.logback.classic.Logger.log(Logger.java:765) at org.apache.commons.logging.impl.SLF4JLocationAwareLog.error(SLF4JLocationAwareLog.java:216) at org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:771) at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:748) at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) at by.kolodyuk.osgi.springboot.SpringBootBundleActivator.start(SpringBootBundleActivator.java:21) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:849) at org.apache.felix.framework.Felix.activateBundle(Felix.java:2429) at org.apache.felix.framework.Felix.startBundle(Felix.java:2335) at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1566) at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:297) at java.base/java.lang.Thread.run(Thread.java:829) ``` -------------------------------- ### Initialize SkywalkingMeterRegistry Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer.md Instantiate SkywalkingMeterRegistry to forward Micrometer metrics to the OAP server. Optionally, configure it to rate specific counters or use a composite registry. ```java import org.apache.skywalking.apm.meter.micrometer.SkywalkingMeterRegistry; import java.util.Arrays; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.micrometer.prometheus.PrometheusConfig; SkywalkingMeterRegistry registry = new SkywalkingMeterRegistry(); // If you has some counter want to rate by agent side SkywalkingConfig config = new SkywalkingConfig(Arrays.asList("test_rate_counter")); new SkywalkingMeterRegistry(config); // Also you could using composite registry to combine multiple meter registry, such as collect to Skywalking and prometheus CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); compositeRegistry.add(new PrometheusMeterRegistry(PrometheusConfig.DEFAULT)); compositeRegistry.add(new SkywalkingMeterRegistry()); ``` -------------------------------- ### Running Plugin Tests Source: https://github.com/apache/skywalking-java/blob/main/docs/en/setup/service-agent/java-agent/Plugin-test.md Bash command to run plugin tests from the SkyWalking home directory. Ensure the agent is recompiled if changes are made to `./apm-sniffer`. ```bash cd ${SKYWALKING_HOME} bash ./test/plugin/run.sh -f ${scenario_name} ```