0


skywalking操作手册

1. Skyalking介绍

1.1 Skywalking概述

SkyWalking 是一个开源可观测性平台,用于收集、分析、聚合和可视化来自服务和云原生的数据 基础 设施。SkyWalking 提供了一种简单的方法来保持分布式系统的清晰视图,甚至可以跨云。 它是一个现代 APM,专为云原生、基于容器的分布式系统而设计。

1.2 Skywalking整体架构

在这里插入图片描述

SkyWalking在逻辑上分为四个部分:探针,平台后端,存储和UI。

  1. 探测器收集遥测数据,包括各种格式(SkyWalking,Zipkin,OpenTelemetry,Prometheus,Zabbix等)的指标,跟踪,日志和事件。 2. 平台后端支持数据聚合、分析和流流程,涵盖跟踪、指标、日志和事件。充当聚合器角色和/或接收者角色。 3. 存储通过开放/可插拔接口存储SkyWalking数据。您可以选择现有实现,例如 ElasticSearch,H2,MySQL,TiDB,BanyanDB,或者实现你自己的。 4. UI是一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。

2.Skyalking部署

安装包下载

https://skywalking.apache.org/downloads/
注意:目前最高版本为OAP 9.4.0版本【注意9.4.0 未测试jdk1.8 可能无法使用,因此建议使用的9.3.0版本 】,Agent版本为8.14

2.1 服务端OAP部署

2.1.1修改配置文件

进去config目录,找到oap配置文件 application.yml

在这里插入图片描述

里面有很多模块配置项,具体配置可以看官方文档,此处我们只修改oap数据源,其余保持默认,找到配置文件中的storage 模块,可以看到里面很多数据源配置,elasticserch,h2,mysql等,此处我们选择elasticsearch作为数据存储,修改selector 值即可。

在这里插入图片描述

2.1.2 启动OAP组件

进入bin目录

在这里插入图片描述

可以看到bin目录下有bat脚本和sh脚本,其中oapService是oap的启动脚本,其中分为两种类型,init和非init,如果用init的脚本启动,则会初始化oap的数据库相关表或者es 索引,非init则直接启动oap服务。所以第一次启动我们选择oapServiceInit.bat 启动,初始化es 相关索引,下次启动用oapService.bat启动即可。

2.2 服务端UI部署

2.2.1 修改配置文件

​ 进入webapp目录,webapp.yml为ui服务的配置文件,里面有端口号以及spring cloud gateway的相关配置

在这里插入图片描述

2.2.2 启动ui服务

进入bin目录,使用webappService.sh启动即可

2.3 客户端Agent部署

2.3.1 javaagent 目录介绍

Agent目录结构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dcDm7Gb4-1679988433405)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230328150916449.png)]

在这里插入图片描述

2.3.2 集成javaAgent插件

1、配置文件
Javaagent配置文件在 agent config目录下,具体参数请参考官网介绍,其中
agent.service_name 为服务名称,其他默认,我们修改此项即可。
在这里插入图片描述

部分配置说明:

  • agent.namespace:命名空间,可通过此参数实现隔离 agent.service_name:在链路追踪 UI 中展示的应用名,如果是微服务架构,可以和注册中心中的应用名一致 agent.is_cache_enhanced_class:如果为true,则SkyWalking代理会将所有检测到的类文件缓存到内存或磁盘文件中(由类缓存模式决定) collector.backend_service:后端Collector收集器的地址 logging.file_name:日志文件名 logging.level:日志等级 logging.max_file_size:日志文件大小控制 logging.max_history_files:历史日志文件个数控制 plugin.mount:挂载插件的文件夹名 plugin.mysql.trace_sql_parameters:收集sql的参数 agent.ignore_suffix,表示对请求追踪进行忽略,多个路径用逗号分隔,在实际的生产环境中某些请求是不需要被追踪的,例如心跳检查/health,监控指标/metrics等等,我们需要将对应的插件jar包apm-trace-ignore-plugin-8.4.0.jar拷贝到plugins目录下并进行对应的配置,配置文件内容部分如下
# If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,`.
#agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg}
2.3.3 javaagent集成

在这里插入图片描述

   常用配置:
   -javaagent:/opt/skwalking/skywalking-agent/skywalking-agent.jar
   -Dskywalking.agent.service_name=服务名
   -Dskywalking.collector.backed_service=127.0.0.1:11800  --OAP通讯地址

3.Skywalking自定义链路追踪

3.1 概念

Span

  1. EntrySpan代表服务提供商。它也是服务器端的端点。作为一个APM系统,我们的目标是 应用程序服务器。因此,几乎所有的服务和MQ消费者都是EntrySpan。
  2. LocalSpan 表示一种不涉及远程服务的普通 Java 方法。它既不是 MQ 生产者/消费者 也不是服务(例如 HTTP 服务)提供者/消费者。
  3. ExitSpan 表示服务的客户端或 MQ 生产者。它在SkyWalking的早期版本中被命名。 例如,通过JDBC访问数据库和读取Redis/Memcached被归类为ExitSpan。LeafSpan

ContextCarrier

为了实现分布式跟踪,必须绑定跨进程跟踪,并且上下文必须传播 在整个过程中。这就是ContextCarrier的用武之地。
以下是有关如何在分布式呼叫中使用上下文载体的步骤。A->B
1.在客户端创建一个新的空。ContextCarrier
2.创建退出跨度 或 用于启动 .ContextManager#createExitSpanContextManager#injectContextCarrier
3.将所有项目放入heads(例如HTTP HEAD),附件(例如Dubbo RPC框架)或消息(例如Kafka)中。ContextCarrier
4.通过服务调用传播到服务器端。ContextCarrier
5.在服务器端,从标题、附件或消息中获取所有项目。
6.创建 EntrySpan 或用于绑定客户端和服务器端。ContextManager#createEntrySpanContextManager#extract
服务器端使用 Tomcat 7 服务器插件

ContextCarrier contextCarrier = new ContextCarrier();
            CarrierItem next = contextCarrier.items();
            while (next.hasNext()) {
                next = next.next();
                next.setHeadValue(request.getHeader(next.getHeadKey()));
            }

ContextSnapshot

除了跨进程跟踪之外,还必须支持跨线程跟踪。例如,两个异步进程(内存中 MQ) 和批处理在 Java 中很常见。跨进程和跨线程跟踪非常相似,因为它们都需要传播 上下文,但跨线程跟踪不需要序列化。
以下是跨线程传播的三个步骤:
1.用于获取 ContextSnapshot 对象。ContextManager#capture
2.让子线程通过方法参数或由现有参数携带访问 ContextSnapshot
3.在子线程中使用。ContextManager#continued

3.2 Tracing API 接口跟踪

依赖工具包

 <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-trace</artifactId>
      <version>${skywalking.version}</version>
   </dependency>

使用 API 获取traceID。TraceContext.traceId()
使用 API 获取segmentID。TraceContext.segmentId()
使用 API 获取 spanId。TraceContext.spanId()
@Trace注释的方法将尝试使用给定的键 () 和 () 标记当前活动范围 如果根本没有活动跨度,则此注释无效。 可以重复使用,并且可以与 一起使用,请参阅下面的示例。 的与自定义增强跟踪中支持的内容相同。@TagTag#key()Tag#value()@Tag@TracevalueTag
在跟踪方法的上下文中添加自定义标记。ActiveSpan.tag(“key”, “val”)
ActiveSpan.error()将当前范围标记为错误状态。
ActiveSpan.error(String errorMsg)使用消息将当前范围标记为错误状态。
ActiveSpan.error(Throwable throwable)使用可抛出对象将当前范围标记为错误状态。
ActiveSpan.debug(String debugMsg)在当前范围中添加调试级别日志消息。
ActiveSpan.info(String infoMsg)在当前范围中添加信息级别日志消息。
ActiveSpan.setOperationName(String operationName)自定义操作名称。

3.2.1 侵入式追踪

如果要用@tag或@tags注解,前提是必须要使用@Trace注解,不然仅仅给业务方法加@Tag注解的话,SkyWalking也不会显示
@Tag注解中key我们可以自定义,而value的写法就固定了,如果要查看返回值就只能写returnedObj,如果要查看请求参数就只能用arg,下标代表第几个请求参数
返回值的对象,注意要重写toString()方法,不然在SkyWalking的界面中显示的只是一个对象的内存地址

3.2.2 非侵入式追踪

  1. 激活插件,将插件从optional-plugins/apm-customize-enhance-plugin-x.x.x.jar移动到plugin/apm-customize-enhance-plugin-x.x.x.jar
  2. 在agent.config中配置plugin.customize.enhance_file,指明增强规则文件,比如/absolute/path/to/customize_enhance.xml
  3. customize_enhance.xml中配置增强规则
<?xml version="1.0" encoding="UTF-8"?>
<enhanced>
    <class class_name="test.apache.skywalking.testcase.customize.service.TestService1">
        <method method="staticMethod()" operation_name="/is_static_method" static="true"/>
        <method method="staticMethod(java.lang.String,int.class,java.util.Map,java.util.List,[Ljava.lang.Object;)" operation_name="/is_static_method_args" static="true">
            <operation_name_suffix>arg[0]</operation_name_suffix>
            <tag key="tag_1">arg[2].['k1']</tag>
            <tag key="tag_2">arg[4].[1]</tag>
        </method>
        <method method="method()" static="false"/>
    </class>
</enhanced>

文件中的配置说明
配置说明class_name要被增强的类method类的拦截器方法operation_name如果进行了配置,将用它替代默认的operation_nameoperation_name_suffix表示在operation_name后添加动态数据static方法是否为静态方法tag将在local span中添加一个tag。key的值需要在XML节点上表示。log将在local span中添加一个log。key的值需要在XML节点上表示。arg[x]表示输入的参数值。比如args[0]表示第一个参数。.[x]当正在被解析的对象是Array或List,你可以用这个表达式得到对应index上的对象。.[‘key’]当正在被解析的对象是Map, 你可以用这个表达式得到map的key。

3.3 openTracing API 接口跟踪

依赖工具包,例如使用 maven 或 gradle

   <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-opentracing</artifactId>
      <version>{project.release.version}</version>
   </dependency>

代码示例:

Tracer tracer = new SkywalkingTracer();
Tracer.SpanBuilder spanBuilder = tracer.buildSpan("/yourApplication/yourService");

3.4 跨线程追踪

​ SkyWalking提供了跨线程构建Trace的能力,通过对 Callable、Runnable、Supplier 这3种接口的实现者进行增强拦截,将 Trace 的上下文信息传递到子线程中,实现了异步链路追踪。有非常多的方式来实现Callable,Runnable,Supplier 这3种接口。
SkyWalking提供了一种既通用又快捷的方式来规范这一现象:
1.只拦截增强带有@TraceCrossThread 注解的类;
2.通过装饰的方式包装任务,避免大刀阔斧的修改
原始类提供的包装类拦截方法使用技巧CallableCallableWrappercallCallableWrapper.of(xxxCallable)RunnableRunnableWrapperrunRunnableWrapper.of(xxxRunable)SupplierSupplierWrappergetSupplierWrapper.of(xxxSupplier)
包装类 都有注解 @TraceCrossThread ,skywalking内部的拦截匹配逻辑是,标注了@TraceCrossThread的类,拦截 其名称为call 或run或 get ,且没有入参的方法;对使用者来说大致分为2种方式:
1.自定义类,实现接口 Callable、Runnable、Supplier,加@TraceCrossThread注解。当需要有更多的自定义属性时,考虑这种方式;参考 CallableWrapper、RunnableWrapper 、SupplierWrapper 的实现方式。
通过xxxWrapper.of 装饰的方式,即CallableWrapper.of(xxxCallable)、RunnableWrapper.of(xxxRunable)、SupplierWrapper.of(xxxSupplier)。大多情况下,通过这种包装模式即可。
依赖工具包,例如使用 maven 或 gradle

 <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-trace</artifactId>
      <version>${skywalking.version}</version>
   </dependency>

用法 1.

 @TraceCrossThread
    public static class MyCallable<String> implements Callable<String> {
        @Override
        public String call() throws Exception {
            return null;
        }
    }...
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    executorService.submit(new MyCallable());

用法 2.

    ExecutorService executorService = Executors.newFixedThreadPool(1);
    executorService.submit(CallableWrapper.of(new Callable<String>() {
        @Override public String call() throws Exception {
            return null;
        }
}));
或
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    executorService.execute(RunnableWrapper.of(new Runnable() {
        @Override public void run() {
            //your code        }
    }));

用法 3.

    @TraceCrossThread
    public class MySupplier<String> implements Supplier<String> {
        @Override
        public String get() {
            return null;
        }
    }...
    CompletableFuture.supplyAsync(new MySupplier<String>());
或
    CompletableFuture.supplyAsync(SupplierWrapper.of(()->{
            return "SupplierWrapper";
    })).thenAccept(System.out::println);

用法 4.

    CompletableFuture.supplyAsync(SupplierWrapper.of(() -> {
        return "SupplierWrapper";
    })).thenAcceptAsync(ConsumerWrapper.of(c -> {
        // your code visit(url)        System.out.println("ConsumerWrapper");
    }));
或
    CompletableFuture.supplyAsync(SupplierWrapper.of(() -> {
        return "SupplierWrapper";
    })).thenApplyAsync(FunctionWrapper.of(f -> {
        // your code visit(url)        return "FunctionWrapper";
    }));

3.5自定义插件

3.5.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itmuch.skywalking</groupId>
    <artifactId>apm-string-plugin</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <shade.package>org.apache.skywalking.apm.dependencies</shade.package>
        <shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
        <shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-agent-core</artifactId>
            <version>8.12.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-util</artifactId>
            <version>8.8.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>false</shadedArtifactAttached>
                            <createDependencyReducedPom>true</createDependencyReducedPom>
                            <createSourcesJar>true</createSourcesJar>
                            <shadeSourcesContent>true</shadeSourcesContent>
                            <relocations>
                                <relocation>
                                    <pattern>${shade.net.bytebuddy.source}</pattern>
                                    <shadedPattern>${shade.net.bytebuddy.target}</shadedPattern>
                                </relocation>
                            </relocations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3.5.2 继承ClassInstanceMethodsEnhancePluginDefine

非静态

package com.itmuch.skywalking.plugin.define;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.DeclaredInstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;

public class DemoMethodInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

    public static final String INTERCEPT_CLASS="com.springboot.master.service.impl.AsyncServiceImpl";

    @Override
    protected ClassMatch enhanceClass() {
        return NameMatch.byName(INTERCEPT_CLASS);
    }

    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[0];
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[]{
                new DeclaredInstanceMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        System.out.println("-----------------------------");
                        return ElementMatchers.named("getCityName");
                    }

                    @Override
                    public String getMethodsInterceptor() {
                        return "com.itmuch.skywalking.plugin.DemoMethodInterceptor";

                    }

                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                }
        };
    }
}

静态

package com.itmuch.skywalking.plugin.define;

import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;

public class StringReplaceInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
    @Override
    protected ClassMatch enhanceClass() {
        // 指定想要监控的类
        return NameMatch.byName("org.apache.commons.lang3.StringUtils");
    }

    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[0];
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        // 指定想要监控的实例方法,每个实例方法对应一个InstanceMethodsInterceptPoint
        return new InstanceMethodsInterceptPoint[0];
    }

    @Override
    public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
        // 指定想要监控的静态方法,每一个方法对应一个StaticMethodsInterceptPoint
        return new StaticMethodsInterceptPoint[]{
                new StaticMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher getMethodsMatcher() {
                        // 静态方法名称
                        return ElementMatchers.named("replace");
                    }

                    @Override
                    public String getMethodsInterceptor() {
                        // 该静态方法的监控拦截器类名全路径
                        return "com.itmuch.skywalking.plugin.StringReplaceInterceptor";
                    }

                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                }
        };
    }
}

3.5.3 实现MethodsAroundInterceptor

静态方法实现StaticMethodsAroundInterceptor

package com.itmuch.skywalking.plugin;

import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;

import java.lang.reflect.Method;

public class StringReplaceInterceptor implements StaticMethodsAroundInterceptor {
    @Override
    public void beforeMethod(Class aClass, Method method, Object[] argumentsTypes, Class[] classes, MethodInterceptResult methodInterceptResult) {
        // 创建span(监控的开始),本质上是往ThreadLocal对象里面设值
        AbstractSpan span = ContextManager.createLocalSpan("replace");

        /*
         * 可用ComponentsDefine工具类指定Skywalking官方支持的组件
         * 也可自己new OfficialComponent或者Component
         * 不过在Skywalking的控制台上不会被识别,只会显示N/A
         */
        span.setComponent(ComponentsDefine.TOMCAT);

        span.tag(new StringTag(1000, "params"), argumentsTypes[0].toString());
        // 指定该调用的layer,layer是个枚举
        span.setLayer(SpanLayer.CACHE);
    }

    @Override
    public Object afterMethod(Class aClass, Method method, Object[] objects, Class[] classes, Object o) {
        String retString = (String) o;
        // 激活span,本质上是读取ThreadLocal对象
        AbstractSpan span = ContextManager.activeSpan();
        // 停止span(监控的结束),本质上是清理ThreadLocal对象
        ContextManager.stopSpan();
        return retString;
    }

    @Override
    public void handleMethodException(Class aClass, Method method, Object[] objects, Class[] classes, Throwable throwable) {
        AbstractSpan activeSpan = ContextManager.activeSpan();

        // 记录日志
        activeSpan.log(throwable);
        activeSpan.errorOccurred();
    }
}

非静态方法实现InstanceMethodsAroundInterceptor

package com.itmuch.skywalking.plugin;

import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;

import java.lang.reflect.Method;

public class DemoMethodInterceptor implements InstanceMethodsAroundInterceptor {

    @Override
    public void beforeMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, MethodInterceptResult methodInterceptResult) throws Throwable {
        // 创建span(监控的开始),本质上是往ThreadLocal对象里面设值
        AbstractSpan span = ContextManager.createLocalSpan("demo");

        /*
         * 可用ComponentsDefine工具类指定Skywalking官方支持的组件
         * 也可自己new OfficialComponent或者Component
         * 不过在Skywalking的控制台上不会被识别,只会显示N/A
         */
        span.setComponent(ComponentsDefine.TOMCAT);

        span.tag(new StringTag(1000, "params"), "demo");
        // 指定该调用的layer,layer是个枚举
        span.setLayer(SpanLayer.CACHE);    }

    @Override
    public Object afterMethod(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Object o) throws Throwable {
        String retString = (String) o;
        // 激活span,本质上是读取ThreadLocal对象
        AbstractSpan span = ContextManager.activeSpan();
        // 停止span(监控的结束),本质上是清理ThreadLocal对象
        ContextManager.stopSpan();
        return retString;
    }

    @Override
    public void handleMethodException(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Throwable throwable) {

    }
}

3.5.3 在resourse目录下编写skywalking-plugin.def文件

Plugin=com.itmuch.skywalking.plugin.define.StringReplaceInstrumentation
Plugin=com.itmuch.skywalking.plugin.define.DemoMethodInstrumentation

Key随意写 ,value为继承ClassInstanceMethodsEnhancePluginDefine类的全路径,注意多个key最好保持一致

文件名固定为skywalking-plugin.def


本文转载自: https://blog.csdn.net/weixin_45172742/article/details/129931862
版权归原作者 水落大海 所有, 如有侵权,请联系我们删除。

“skywalking操作手册”的评论:

还没有评论