### 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
```