### Start JVM Services with Agent Options Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test This script demonstrates how to start JVM-based services using `java -jar`. It includes the required `${agent_opts}` for agent installation and allows explicit setting of `skywalking.agent.service_name`. ```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 & ``` -------------------------------- ### Test Maven Settings Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Run this command to build artifacts, sources, and sign them, verifying your Maven environment setup. ```bash ./mvnw clean install(this will build artifacts, sources and sign) ``` -------------------------------- ### Jetty Agent Setup Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme Configure the Java agent by adding the -javaagent argument to the JAVA_OPTIONS environment variable in jetty.sh. ```shell export JAVA_OPTIONS="${JAVA_OPTIONS} -javaagent:/path/to/skywalking-agent/skywalking-agent.jar" ``` -------------------------------- ### JAR File Application Agent Setup Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme Integrate the Java agent by adding the -javaagent argument to the JVM startup command line before the -jar argument. ```shell java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -jar yourApp.jar ``` -------------------------------- ### Logback Configuration with AsyncAppender and MDC Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x Example logback.xml demonstrating support for AsyncAppender and MDC trace ID logging. No additional configuration is needed for AsyncAppender. ```xml %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n 0 1024 true ``` -------------------------------- ### Create Counter and Histogram Meters Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Demonstrates how to create and operate a counter and a histogram meter using `MeterFactory`. These are examples of meters that can be tested. ```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); ``` -------------------------------- ### Log4j2.xml with AsyncRoot Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x Example configuration for Log4j2 using AsyncRoot, which automatically includes SkyWalking trace IDs in logs without additional setup. ```xml ``` -------------------------------- ### Set up Witness Methods for Plugin Activation Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Example of specifying witness methods that must exist for the plugin to be activated. This provides a more granular activation condition based on method availability. ```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; } ``` -------------------------------- ### GitHub Actions Job Matrix Example Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test An example of a GitHub Actions job matrix configuration for running plugin tests. This snippet shows how to include a scenario test directory name in the matrix. ```yaml jobs: PluginsTest: name: Plugin runs-on: ubuntu-latest timeout-minutes: 90 strategy: fail-fast: true matrix: case: # ... - # ... ``` -------------------------------- ### Example: Match Specific Class by Name Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Example of implementing `enhanceClass` to match a specific class by its fully qualified name. This is the recommended approach for defining target classes. ```java @Override protected ClassMatch enhanceClassName() { return byName("org.apache.catalina.core.StandardEngineValve"); } ``` -------------------------------- ### Set up Witness Classes for Plugin Activation Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Example of specifying witness classes that must exist for the plugin to be activated. This ensures the plugin is only loaded when relevant classes are present 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" }; } ``` -------------------------------- ### Configure Trace Ignore Paths Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/agent-optional-plugins/trace-ignore-plugin Example of configuring trace ignore paths using the `trace.ignore_path` property. Multiple paths should be separated by commas. ```properties trace.ignore_path=/your/path/1/**,/your/path/2/** ``` -------------------------------- ### Log4j2.xml with Mixed Sync & Async Loggers Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x Example of a mixed synchronous and asynchronous logging configuration in Log4j2. This setup requires the disruptor jar on the classpath for versions 2.9 and higher. ```xml %d %p %class{1.} [%t] [%traceId] %location %m %ex%n ``` -------------------------------- ### Windows Tomcat Agent Setup Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme Add the Java agent as a JVM argument by modifying the catalina.bat script. Ensure the agent path is correct. ```shell set "CATALINA_OPTS=-javaagent:/path/to/skywalking-agent/skywalking-agent.jar" ``` -------------------------------- ### GatewayFilter Example Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/agent-optional-plugins/spring-gateway A simple example of a GatewayFilter that logs a message when it runs. It demonstrates basic filter functionality within Spring Gateway. ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.server.GatewayFilter; import org.springframework.web.server.GatewayFilterChain; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @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); } } ``` -------------------------------- ### Initialize SkywalkingTracer Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/opentracing Instantiate the SkywalkingTracer and create a SpanBuilder for tracing requests. This is the basic setup for using the OpenTracing API with SkyWalking. ```java Tracer tracer = new SkywalkingTracer(); Tracer.SpanBuilder spanBuilder = tracer.buildSpan("/yourApplication/yourService"); ``` -------------------------------- ### Maven POM Configuration for Test Framework Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Example Maven POM configuration showing how to define the test framework version and dependencies, including httpclient. It also demonstrates setting the final package name. ```xml 4.3 org.apache.httpcomponents httpclient ${test.framework.version} ... httpclient-4.3.x-scenario .... ``` -------------------------------- ### Linux Tomcat Agent Setup Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/readme Add the Java agent as a JVM argument by modifying the catalina.sh script. Ensure the agent path is correct. ```shell CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS ``` -------------------------------- ### Continue Tracing with doOnEach and Contextual Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-webflux Demonstrates continuing tracing using doOnEach for signal processing and deferContextual for context-aware operations within a reactive stream. This example shows integration with logging and deferred execution. ```java Mono.just("key").subscribeOn(Schedulers.boundedElastic()) .doOnEach(WebFluxSkyWalkingOperators.continueTracing(SignalType.ON_NEXT, () -> log.info("test log with tid"))) .flatMap(key -> Mono.deferContextual(ctx -> WebFluxSkyWalkingOperators.continueTracing(Context.of(ctx), () -> { redis.hasKey(key); return Mono.just("SUCCESS"); }) )); ... ``` -------------------------------- ### Docker Image Usage Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/containerization Example of using the SkyWalking Java Agent Docker image. This image hosts pre-built agent jars and offers convenient configurations for containerized scenarios. ```dockerfile FROM apache/skywalking-java-agent:8.5.0-jdk8 # ... build your java application ``` -------------------------------- ### Log with Arguments Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x Example of logging a message with multiple arguments using Log4j 2. When transmit_formatted is false, these arguments are sent as tags. ```java log.info("{} {}", 1, 2, 3); ``` -------------------------------- ### Docker Compose Healthcheck Configuration in YAML Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test This example shows how to format Docker Compose health check configurations within the `configuration.yml` file, adapting the standard Docker Compose format for use in this context by prefixing each item with a hyphen and enclosing them in quotes. ```yaml healthcheck: - 'test: ["CMD", "curl", "-f", "http://localhost"]' - "interval: 1m30s" - "timeout: 10s" - "retries: 3" - "start_period: 40s" ``` -------------------------------- ### OSGi Class Loading Error Example Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/faq/osgi This stack trace illustrates a `java.lang.NoClassDefFoundError` that can occur when the SkyWalking agent's classes are not accessible within an OSGi bundle's isolated classloader. ```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) ``` -------------------------------- ### Kubernetes Agent as Sidecar Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/containerization Installs the SkyWalking Java agent as a sidecar container in Kubernetes. This method injects the agent into the application pod, enabling native tracing without complex injector setups. ```yaml apiVersion: v1 kind: Pod metadata: name: agent-as-sidecar spec: restartPolicy: Never volumes: - name: skywalking-agent emptyDir: { } initContainers: - name: agent-container image: apache/skywalking-java-agent:8.7.0-alpine volumeMounts: - name: skywalking-agent mountPath: /agent command: [ "/bin/sh" ] args: [ "-c", "cp -R /skywalking/agent /agent/" ] containers: - name: app-container image: springio/gs-spring-boot-docker volumeMounts: - name: skywalking-agent mountPath: /skywalking env: - name: JAVA_TOOL_OPTIONS value: "-javaagent:/skywalking/agent/skywalking-agent.jar" ``` -------------------------------- ### Get Span ID Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace-read-context Use `TraceContext.spanId()` to get the current span ID. The value is accessible only if the current thread is part of an active trace. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("spanId", TraceContext.spanId()); ``` -------------------------------- ### Compile Project from Downloaded Source Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/compiling Compile the SkyWalking Java project using Maven wrapper after downloading the source code tarball. ```shell ./mvnw clean package ``` -------------------------------- ### Create Release Package Script Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Run this bash script to create the source and binary release packages, including GPG signatures and SHA512 checksums. ```bash export RELEASE_VERSION=x.y.z (example: RELEASE_VERSION=5.0.0-alpha) cd tools/releasing bash create_release.sh ``` -------------------------------- ### Prepare Release with Maven Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Use these Maven commands to clean previous release artifacts and prepare for a new release, automatically handling version submodules. ```bash ./mvnw release:clean ./mvnw release:prepare -DautoVersionSubmodules=true -Pall ``` -------------------------------- ### JVM-container Test Project Structure Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Illustrates the directory structure for a JVM-container based test project, including startup scripts, configuration files, and source code. ```text [plugin-scenario] |- [bin] |- startup.sh |- [config] |- expectedData.yaml |- [src] |- [main] |- ... |- [resource] |- log4j2.xml |- pom.xml |- configuration.yml |- support-version.list [] = directory ``` -------------------------------- ### Define a Custom Exception Class Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/how-to-tolerate-exceptions Example of defining a custom exception class that extends RuntimeException. This is a prerequisite for demonstrating exception toleration. ```java package org.apache.skywalking.apm.agent.core.context.status; public class TestNamedMatchException extends RuntimeException { public TestNamedMatchException() { } public TestNamedMatchException(final String message) { super(message); } ... } ``` ```java package org.apache.skywalking.apm.agent.core.context.status; public class TestHierarchyMatchException extends TestNamedMatchException { public TestHierarchyMatchException() { } public TestHierarchyMatchException(final String message) { super(message); } ... } ``` -------------------------------- ### Configure Observation Registry with Skywalking Handlers Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-micrometer-1.10 Set up the Micrometer Observation Registry by adding Skywalking's meter and tracing handlers. This enables Skywalking to collect metrics and traces from Micrometer instrumentations. ```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() )); ``` -------------------------------- ### Get Segment ID Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace-read-context Use `TraceContext.segmentId()` to retrieve the current segment ID. This API returns a value only when the thread is under active tracing. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("segmentId", TraceContext.segmentId()); ``` -------------------------------- ### Get Trace ID Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace-read-context Use `TraceContext.traceId()` to obtain the current trace ID. Ensure the current thread is being traced for this value to be available. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("traceId", TraceContext.traceId()); ``` -------------------------------- ### Clone and Compile Project Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/compiling Clone the SkyWalking Java repository from GitHub and compile the project using Maven wrapper. This command builds all modules. ```shell git clone https://github.com/apache/skywalking-java.git cd skywalking-java ./mvnw clean package -Pall ``` -------------------------------- ### Build and Push Docker Images Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/compiling Builds and pushes agent Docker images based on alpine, Java 8, and Java 11. ```shell make docker.push.alpine docker.push.java8 docker.push.java11 ``` -------------------------------- ### Maven Settings Configuration Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Configure your ~/.m2/settings.xml file with server IDs, usernames, and encrypted passwords for Apache snapshots and releases. ```xml ... apache.snapshots.https apache.releases.https ... ``` -------------------------------- ### Configure SkywalkingMeterRegistry Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-micrometer Instantiate and configure SkywalkingMeterRegistry to forward Micrometer metrics. Optionally, provide a configuration to specify counters for agent-side rate limiting or use a composite registry to combine with other registries like Prometheus. ```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()); ``` -------------------------------- ### Resetting Collection Type Configuration Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configurations Use this to override default collection type configurations by setting the property to an empty value. Example shown for Kafka topics. ```properties plugin.kafka.topics= ``` -------------------------------- ### Get Span ID using TraceContext Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace Retrieve the current span ID using the `TraceContext.spanId()` API. This ID identifies a specific operation within a segment. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("spanId", TraceContext.spanId()); ``` -------------------------------- ### Get Segment ID using TraceContext Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace Retrieve the current segment ID using the `TraceContext.segmentId()` API. This ID uniquely identifies a segment within a trace. ```java import org.apache.skywalking.apm.toolkit.trace.TraceContext; ... modelAndView.addObject("segmentId", TraceContext.segmentId()); ``` -------------------------------- ### Build Docker Images Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/compiling Builds agent Docker images based on alpine, Java 8, Java 11, and Java 17 images by default. ```shell make docker.alpine docker.java8 docker.java11 ``` -------------------------------- ### Resetting Map Type Configuration Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configurations Use this to override default map type configurations by setting the property to an empty value. Example shown for Kafka producer configuration. ```properties plugin.kafka.producer_config[]= ``` -------------------------------- ### Configure Log4j Layout for SkyWalking Context Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-log4j-1.x Replace %T with %T{SW_CTX} in the ConversionPattern to include SkyWalking context details like service name, instance name, trace ID, etc. ```properties log4j.appender.CONSOLE.layout.ConversionPattern=%d [%T{SW_CTX}] %-5p %c{1}:%L - %m%n ``` -------------------------------- ### Configure Logback to Print SkyWalking Context Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x Replace %tid or %X{tid} with %sw_ctx or %X{sw_ctx} in your logback.xml pattern to display the full SkyWalking context, including service name, instance name, trace ID, and span ID. ```xml %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{sw_ctx}] [%thread] %-5level %logger{36} -%msg%n ``` -------------------------------- ### Kafka Consumer with Poll and Invoke Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-kafka Example of a Kafka consumer thread that uses the @KafkaPollAndInvoke annotation to trace poll and invoke operations. Ensure the KafkaConsumer is properly configured and subscribed to topics. ```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; } } ``` -------------------------------- ### AbstractSpan Methods Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Provides essential methods for configuring spans, including setting components, layers, tags, logs, and operation names. These are crucial for EntrySpan and ExitSpan. ```java /** * Set the component id, which defines in {@link ComponentsDefine} * * @param component * @return the span for chaining. */ AbstractSpan setComponent(Component component); AbstractSpan setLayer(SpanLayer layer); /** * Set a key:value tag on the Span. * * @return this Span instance, for chaining */ AbstractSpan tag(String key, String value); /** * Record an exception event of the current walltime timestamp. * * @param t any subclass of {@link Throwable}, which occurs in this span. * @return the Span, for chaining */ AbstractSpan log(Throwable t); AbstractSpan errorOccurred(); /** * Record an event at a specific timestamp. * * @param timestamp The explicit timestamp for the log record. * @param event the events * @return the Span, for chaining */ AbstractSpan log(long timestamp, Map event); /** * Sets the string name for the logical operation this span represents. * * @return this Span instance, for chaining */ AbstractSpan setOperationName(String endpointName); ``` -------------------------------- ### Manipulate Correlation Context in Gateway Filter Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-webflux Within a Gateway Filter, use WebFluxSkyWalkingTraceContext to set and get correlation data. This enables passing contextual information between upstream and downstream services. ```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); } ``` -------------------------------- ### Run Plugin Test Script Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Command to execute plugin tests from the SkyWalking home directory. Ensure the `SKYWALKING_HOME` environment variable is set correctly. ```bash cd ${SKYWALKING_HOME} bash ./test/plugin/run.sh -f ${scenario_name} ``` -------------------------------- ### Get Custom Data from Trace Context Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace-correlation-context Use `TraceContext.getCorrelation()` to retrieve custom data from the tracing context using its key. The method returns an Optional containing the value if found. ```java Optional value = TraceContext.getCorrelation("customKey"); ``` -------------------------------- ### Tomcat-container Test Project Structure Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Illustrates the directory structure for a Tomcat-container based test project, including configuration files and web application structure. ```text [plugin-scenario] |- [config] |- expectedData.yaml |- [src] |- [main] |- ... |- [resource] |- log4j2.xml |- [webapp] |- [WEB-INF] |- web.xml |- pom.xml |- configuration.yml |- support-version.list [] = directory ``` -------------------------------- ### Add Plugin Definition to skywalking-plugin.def Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Configuration entry in `skywalking-plugin.def` to map a version range to the instrumentation class. This activates the plugin for specific Tomcat versions. ```properties tomcat-7.x/8.x=TomcatInstrumentation ``` -------------------------------- ### GlobalFilter Example with Trace Context Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/agent-optional-plugins/spring-gateway Demonstrates how to access trace context (traceId, segmentId, spanId) within a GlobalFilter in Spring Gateway. This is useful for log framework integration and manual trace context usage. ```java import org.apache.skywalking.agent.core.context.TraceContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; @Component public class Filter1 implements GlobalFilter, Ordered { private static final Logger log = LoggerFactory.getLogger(Filter1.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { // Available trace context // For log framework integration(trace context log output) and manual trace context usage. String traceId = TraceContext.traceId(); log.info("available traceId: {}", traceId); String segmentId = TraceContext.segmentId(); log.info("available segmentId: {}", segmentId); int spanId = TraceContext.spanId(); log.info("available spanId: {}", spanId); return chain.filter(exchange); } @Override public int getOrder() { return -100; } } ``` -------------------------------- ### Check Apache License Header Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Use the Apache SkyWalking Eyes Docker image to check for correct Apache License headers in the source code. ```bash docker run --rm -v $(pwd):/github/workspace apache/skywalking-eyes header check ``` -------------------------------- ### Configure Client-Side TLS with mTLS Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/tls Configure the agent for mutual TLS (mTLS) by specifying the paths to the CA certificate, client private key, and client certificate chain. This requires the gRPC server to be started with mTLS enabled. ```properties agent.force_tls=${SW_AGENT_FORCE_TLS:true} agent.ssl_trusted_ca_path=${SW_AGENT_SSL_TRUSTED_CA_PATH:/ca/ca.crt} agent.ssl_key_path=${SW_AGENT_SSL_KEY_PATH:/ca/client.pem} agent.ssl_cert_chain_path=${SW_AGENT_SSL_CERT_CHAIN_PATH:/ca/client.crt} collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:skywalking-oap:11801} ``` -------------------------------- ### Release Docker Images Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Commands to clone the repository, download the agent tarball, extract it, and then build and push Docker images for various Java versions using Make targets. ```bash export SW_VERSION=x.y.z git clone --depth 1 --branch v$SW_VERSION https://github.com/apache/skywalking-java.git cd skywalking-java curl -O https://dist.apache.org/repos/dist/release/skywalking/java-agent/$SW_VERSION/apache-skywalking-java-agent-$SW_VERSION.tgz tar -xzvf apache-skywalking-java-agent-$SW_VERSION.tgz export NAME=skywalking-java-agent export HUB=apache export TAG=$SW_VERSION make docker.push.alpine docker.push.java8 docker.push.java11 docker.push.java17 docker.push.java21 ``` -------------------------------- ### Perform Release with Maven Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Execute this command to stage the release artifacts into a temporary repository, skipping tests. ```bash ./mvnw release:perform -DskipTests -Pall ``` -------------------------------- ### JVM Boot Error with -Djava.ext.dirs in JDK 11+ Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/faq/ext-dirs This error occurs when attempting to use the -Djava.ext.dirs system property with JDK 11 or later, as the extension class loader mechanism is no longer supported. ```shell /lib/ext exists, extensions mechanism no longer supported; Use -classpath instead. .Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. ``` -------------------------------- ### Plugin Directory Structure Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/how-to-disable-plugin This snippet shows the typical directory structure of the SkyWalking Java Agent, highlighting the location of plugin JAR files. ```text +-- skywalking-agent +-- activations apm-toolkit-log4j-1.x-activation.jar apm-toolkit-log4j-2.x-activation.jar apm-toolkit-logback-1.x-activation.jar ... +-- config agent.config +-- plugins apm-dubbo-plugin.jar apm-feign-default-http-9.x.jar apm-httpClient-4.x-plugin.jar ..... skywalking-agent.jar ``` -------------------------------- ### Define Conversion Rules for Trace ID and SkyWalking Context Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x Add conversion rules in logback.xml to enable the use of %tid and %sw_ctx pattern converters for custom JSON logging. ```xml ``` -------------------------------- ### Prepare and Finish Async Span Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-tracer Use prepareForAsync to keep a span alive for asynchronous operations and asyncFinish to signal its completion. ```java import org.apache.skywalking.apm.toolkit.trace.SpanRef; import org.apache.skywalking.apm.toolkit.trace.Tracer; ... SpanRef spanRef = Tracer.createLocalSpan("${operationName}"); spanRef.prepareForAsync(); // the span does not finish because of the prepareForAsync() operation Tracer.stopSpan(); Thread thread = new Thread(() -> { ... spanRef.asyncFinish(); }); thread.start(); thread.join(); ``` -------------------------------- ### Bootstrap Class Instrumentation Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Implement bootstrap instrumentation by overriding `isBootstrapInstrumentation()` and returning true. This affects JRE core and should be used cautiously. ```java public class URLInstrumentation extends ClassEnhancePluginDefine { private static String CLASS_NAME = "java.net.URL"; @Override protected ClassMatch enhanceClass() { return byName(CLASS_NAME); } @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[] { new ConstructorInterceptPoint() { @Override public ElementMatcher getConstructorMatcher() { return any(); } @Override public String getConstructorInterceptor() { return "org.apache.skywalking.apm.plugin.jre.httpurlconnection.Interceptor2"; } } }; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[0]; } @Override public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } @Override public boolean isBootstrapInstrumentation() { return true; } } ``` -------------------------------- ### Capture and Continue Context Snapshot Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-tracer Use Tracer.capture() to capture segment info and Tracer.continued() to load it for cross-thread tracing. ```java import org.apache.skywalking.apm.toolkit.trace.Tracer; import org.apache.skywalking.apm.toolkit.trace.ContextSnapshotRef; import org.apache.skywalking.apm.toolkit.trace.SpanRef; ... ContextSnapshotRef contextSnapshotRef = Tracer.capture(); Thread thread = new Thread(() -> { SpanRef spanRef = Tracer.createLocalSpan("${operationName}"); Tracer.continued(contextSnapshotRef); ... }); thread.start(); thread.join(); ``` -------------------------------- ### Create Entry Span Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-tracer Use Tracer.createEntrySpan() to create an entry span. The second parameter can be a ContextCarrierRef for extracting context information. ```java import org.apache.skywalking.apm.toolkit.trace.Tracer; ... SpanRef spanRef = Tracer.createEntrySpan("${operationName}", null); ``` -------------------------------- ### Generate Test Case Project Usage Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/plugin-test Displays the usage instructions for the `generator.sh` script, which helps in creating a new test case project for SkyWalking plugins. ```bash bash ${SKYWALKING_HOME}/test/plugin/generator.sh ``` -------------------------------- ### YAML Configuration Format for CDS Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configuration-discovery Defines the structure for dynamic agent configurations using YAML. Service names map to their specific configuration key-value pairs. ```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: ... ``` -------------------------------- ### Define Target Class Match Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Abstract method to define how to match target classes for instrumentation. Use string literals for class names to avoid ClassLoader issues. ```java protected abstract ClassMatch enhanceClass(); ``` -------------------------------- ### Implement InstanceMethodsAroundInterceptor (V1 API) Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/java-plugin-development-guide Implement this interface to create interceptors for instance methods using the V1 API. It provides methods to hook into the execution flow before, after, and during exceptions of a target method. ```java /** * A interceptor, which intercept method's invocation. The target methods will be defined in {@link * ClassEnhancePluginDefine}'s subclass, most likely in {@link ClassInstanceMethodsEnhancePluginDefine} */ public interface InstanceMethodsAroundInterceptor { /** * called before target method invocation. * * @param result change this result, if you want to truncate the method. * @throws Throwable */ void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable; /** * called after target method invocation. Even method's invocation triggers an exception. * * @param ret the method's original return value. * @return the method's actual return value. * @throws Throwable */ Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable; /** * called when occur exception. * * @param t the exception occur. */ void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t); } ``` -------------------------------- ### Configure GRPCLogClientAppender for Log Forwarding Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x Add the GRPCLogClientAppender to logback.xml to forward logs to SkyWalking OAP server or Satellite using gRPC. It automatically attaches trace, segment, and span IDs. ```xml %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n ``` -------------------------------- ### Maven Dependency for Micrometer Toolkit Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-micrometer-1.10 Add this dependency to your project's pom.xml to include the Micrometer toolkit for SkyWalking. ```xml org.apache.skywalking apm-toolkit-micrometer-1.10 ${skywalking.version} ``` -------------------------------- ### Verify Release Candidate Signature Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/release-java-agent Verify the PGP signature of the source code distribution package using GPG. ```bash gpg --verify apache-skywalking-java-agent-x.y.z-src.tgz.asc apache-skywalking-apm-x.y.z-src.tgz ``` -------------------------------- ### Build Docker Images with Custom Registry and Name Source: https://skywalking.apache.org/docs/skywalking-java/latest/en/contribution/compiling Builds agent Docker images with a specified private Docker registry and custom image name. ```shell make docker.alpine HUB=gcr.io/skywalking NAME=sw-agent ```