Skywalking-08(OAL原理——如何动态生成Class类)

OAL 如何动态生成 Class 类 代码入口 【Skywalking-08(OAL原理——如何动态生成Class类)】org.apache.skywalking.oal.rt.OALRuntime#start 方法

public void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException { if (!IS_RT_TEMP_FOLDER_INIT_COMPLETED) { prepareRTTempFolder(); IS_RT_TEMP_FOLDER_INIT_COMPLETED = true; }this.currentClassLoader = currentClassLoader; Reader read; try { read = ResourceUtils.read(oalDefine.getConfigFile()); } catch (FileNotFoundException e) { throw new ModuleStartException("Can't locate " + oalDefine.getConfigFile(), e); }OALScripts oalScripts; try { ScriptParser scriptParser = ScriptParser.createFromFile(read, oalDefine.getSourcePackage()); // 解析oal脚本,生成OALScripts对象 oalScripts = scriptParser.parse(); } catch (IOException e) { throw new ModuleStartException("OAL script parse analysis failure.", e); } // OALScripts对象动态生成需要的类 this.generateClassAtRuntime(oalScripts); }

时序图 OALRuntime-generate-class-at-runtime.sdt 该文件可以在 IDEASequence Diagram 插件中打开
Skywalking-08(OAL原理——如何动态生成Class类)
文章图片

案例 启动 OAP 配置中,配置下环境变量 SW_OAL_ENGINE_DEBUG=Y,这样能在工作目录下的 oal-rt 目录下找到生成的 Class 文件。
通过如下目录结构,可以看出有三种 Class
  • dispatcher :调度器,将指标对象发送 MetricsStreamProcessor (指标处理器)
  • metrics :指标类,存储指标数据
  • StorageBuilder :存储构造器,实现类 StorageBuilder 接口,提供 mapStorageData 之间互转的方法
oal-rt ├── dispatcher │├── ServiceInstanceJVMClassDispatcher.class │└── ServiceInstanceJVMThreadDispatcher.class └── metrics ├── InstanceJvmClassLoadedClassCountMetrics.class ├── InstanceJvmClassTotalLoadedClassCountMetrics.class ├── InstanceJvmClassUnloadedClassCountMetrics.class ├── InstanceJvmThreadDaemonCountMetrics.class ├── InstanceJvmThreadDeadlockedMetrics.class ├── InstanceJvmThreadLiveCountMetrics.class └── builder ├── InstanceJvmClassLoadedClassCountMetricsBuilder.class ├── InstanceJvmClassTotalLoadedClassCountMetricsBuilder.class ├── InstanceJvmClassUnloadedClassCountMetricsBuilder.class ├── InstanceJvmThreadDaemonCountMetricsBuilder.class ├── InstanceJvmThreadDeadlockedMetricsBuilder.class └── InstanceJvmThreadLiveCountMetricsBuilder.class

指标类
package org.apache.skywalking.oap.server.core.source.oal.rt.metrics; import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.metrics.LongAvgMetrics; import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics; import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo; import org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData; import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData.Builder; import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.builder.InstanceJvmClassLoadedClassCountMetricsBuilder; import org.apache.skywalking.oap.server.core.storage.annotation.Column; @Stream( name = "instance_jvm_class_loaded_class_count", scopeId = 11000, builder = InstanceJvmClassLoadedClassCountMetricsBuilder.class, processor = MetricsStreamProcessor.class ) public class InstanceJvmClassLoadedClassCountMetrics extends LongAvgMetrics implements WithMetadata { @Column( columnName = "entity_id", length = 512 ) private String entityId; @Column( columnName = "service_id", length = 256 ) private String serviceId; public InstanceJvmClassLoadedClassCountMetrics() { }public String getEntityId() { return this.entityId; }public void setEntityId(String var1) { this.entityId = var1; }public String getServiceId() { return this.serviceId; }public void setServiceId(String var1) { this.serviceId = var1; }public String id() { String var1 = String.valueOf(this.getTimeBucket()); var1 = String.valueOf(var1).concat(String.valueOf("_" + this.entityId)); return var1; }public int hashCode() { byte var1 = 17; int var2 = 31 * var1 + this.entityId.hashCode(); var2 = 31 * var2 + (int)this.getTimeBucket(); return var2; }public int remoteHashCode() { byte var1 = 17; int var2 = 31 * var1 + this.entityId.hashCode(); return var2; }public boolean equals(Object var1) { if (this == var1) { return true; } else if (var1 == null) { return false; } else if (this.getClass() != var1.getClass()) { return false; } else { InstanceJvmClassLoadedClassCountMetrics var2 = (InstanceJvmClassLoadedClassCountMetrics)var1; if (!this.entityId.equals(var2.entityId)) { return false; } else { return this.getTimeBucket() == var2.getTimeBucket(); } } }public Builder serialize() { Builder var1 = RemoteData.newBuilder(); var1.addDataStrings(this.getEntityId()); var1.addDataStrings(this.getServiceId()); var1.addDataLongs(this.getSummation()); var1.addDataLongs(this.getCount()); var1.addDataLongs(this.getValue()); var1.addDataLongs(this.getTimeBucket()); return var1; }public void deserialize(RemoteData var1) { this.setEntityId(var1.getDataStrings(0)); this.setServiceId(var1.getDataStrings(1)); this.setSummation(var1.getDataLongs(0)); this.setCount(var1.getDataLongs(1)); this.setValue(var1.getDataLongs(2)); this.setTimeBucket(var1.getDataLongs(3)); }public MetricsMetaInfo getMeta() { return new MetricsMetaInfo("instance_jvm_class_loaded_class_count", 11000, this.entityId); }public Metrics toHour() { InstanceJvmClassLoadedClassCountMetrics var1 = new InstanceJvmClassLoadedClassCountMetrics(); var1.setEntityId(this.getEntityId()); var1.setServiceId(this.getServiceId()); var1.setSummation(this.getSummation()); var1.setCount(this.getCount()); var1.setValue(this.getValue()); var1.setTimeBucket(this.toTimeBucketInHour()); return var1; }public Metrics toDay() { InstanceJvmClassLoadedClassCountMetrics var1 = new InstanceJvmClassLoadedClassCountMetrics(); var1.setEntityId(this.getEntityId()); var1.setServiceId(this.getServiceId()); var1.setSummation(this.getSummation()); var1.setCount(this.getCount()); var1.setValue(this.getValue()); var1.setTimeBucket(this.toTimeBucketInDay()); return var1; } }

存储构造器
package org.apache.skywalking.oap.server.core.source.oal.rt.metrics.builder; import java.util.HashMap; import java.util.Map; import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.InstanceJvmClassLoadedClassCountMetrics; import org.apache.skywalking.oap.server.core.storage.StorageBuilder; import org.apache.skywalking.oap.server.core.storage.StorageData; public class InstanceJvmClassLoadedClassCountMetricsBuilder implements StorageBuilder { public InstanceJvmClassLoadedClassCountMetricsBuilder() { }public Map data2Map(StorageData var1) { InstanceJvmClassLoadedClassCountMetrics var2 = (InstanceJvmClassLoadedClassCountMetrics)var1; HashMap var3 = new HashMap(); var3.put((Object)"entity_id", var2.getEntityId()); var3.put((Object)"service_id", var2.getServiceId()); var3.put((Object)"summation", new Long(var2.getSummation())); var3.put((Object)"count", new Long(var2.getCount())); var3.put((Object)"value", new Long(var2.getValue())); var3.put((Object)"time_bucket", new Long(var2.getTimeBucket())); return var3; }public StorageData map2Data(Map var1) { InstanceJvmClassLoadedClassCountMetrics var2 = new InstanceJvmClassLoadedClassCountMetrics(); var2.setEntityId((String)var1.get("entity_id")); var2.setServiceId((String)var1.get("service_id")); var2.setSummation(((Number)var1.get("summation")).longValue()); var2.setCount(((Number)var1.get("count")).longValue()); var2.setValue(((Number)var1.get("value")).longValue()); var2.setTimeBucket(((Number)var1.get("time_bucket")).longValue()); return var2; } }

调度器
package org.apache.skywalking.oap.server.core.source.oal.rt.dispatcher; import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher; import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor; import org.apache.skywalking.oap.server.core.source.ServiceInstanceJVMClass; import org.apache.skywalking.oap.server.core.source.Source; import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.InstanceJvmClassLoadedClassCountMetrics; import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.InstanceJvmClassTotalLoadedClassCountMetrics; import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.InstanceJvmClassUnloadedClassCountMetrics; public class ServiceInstanceJVMClassDispatcher implements SourceDispatcher { private void doInstanceJvmClassLoadedClassCount(ServiceInstanceJVMClass var1) { InstanceJvmClassLoadedClassCountMetrics var2 = new InstanceJvmClassLoadedClassCountMetrics(); var2.setTimeBucket(var1.getTimeBucket()); var2.setEntityId(var1.getEntityId()); var2.setServiceId(var1.getServiceId()); var2.combine(var1.getLoadedClassCount(), (long)1); MetricsStreamProcessor.getInstance().in(var2); }private void doInstanceJvmClassUnloadedClassCount(ServiceInstanceJVMClass var1) { InstanceJvmClassUnloadedClassCountMetrics var2 = new InstanceJvmClassUnloadedClassCountMetrics(); var2.setTimeBucket(var1.getTimeBucket()); var2.setEntityId(var1.getEntityId()); var2.setServiceId(var1.getServiceId()); var2.combine(var1.getUnloadedClassCount(), (long)1); MetricsStreamProcessor.getInstance().in(var2); }private void doInstanceJvmClassTotalLoadedClassCount(ServiceInstanceJVMClass var1) { InstanceJvmClassTotalLoadedClassCountMetrics var2 = new InstanceJvmClassTotalLoadedClassCountMetrics(); var2.setTimeBucket(var1.getTimeBucket()); var2.setEntityId(var1.getEntityId()); var2.setServiceId(var1.getServiceId()); var2.combine(var1.getTotalLoadedClassCount(), (long)1); MetricsStreamProcessor.getInstance().in(var2); }public void dispatch(Source var1) { ServiceInstanceJVMClass var2 = (ServiceInstanceJVMClass)var1; this.doInstanceJvmClassLoadedClassCount(var2); this.doInstanceJvmClassUnloadedClassCount(var2); this.doInstanceJvmClassTotalLoadedClassCount(var2); }public ServiceInstanceJVMClassDispatcher() { } }

分享并记录所学所见

    推荐阅读