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 该文件可以在 IDEA
的 Sequence Diagram
插件中打开
请添加图片描述
案例
启动 OAP
配置中,配置下环境变量 SW_OAL_ENGINE_DEBUG=Y
,这样能在工作目录下的 oal-rt
目录下找到生成的 Class
文件。
通过如下目录结构,可以看出有三种 Class
:
-
dispatcher
:调度器,将指标对象发送MetricsStreamProcessor
(指标处理器) -
metrics
:指标类,存储指标数据 -
StorageBuilder
:存储构造器,实现类StorageBuilder
接口,提供map
与StorageData
之间互转的方法
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() {
}
}
分享并记录所学所见