All NEW OAL Runtime Engine (#3109)
* Change OAL generator tool to runtime. Step 1. change project structure. API links and maven pom. * Part of metrics class generation * Metrcis class generated. * Set up the basic structure of new OAL engine. * Finish metrics generation. * Support dispatcher generation. * Format codes. * Generate dispatcher all methods. * Implement disable in hardcode. * Clear up * Fix compile startup. * Update license and document of new OAL engine. * Fix rat. * Disable class output in default * Copy from @kezhenxu94 's test PR, https://github.com/apache/skywalking/pull/3110 * Wait for the mount command to finish
This commit is contained in:
parent
c7916d9f27
commit
5b039e9747
|
|
@ -65,6 +65,13 @@ pipeline {
|
|||
sh 'docker ps'
|
||||
sh 'docker ps | grep -e "skywalking-e2e-container-${BUILD_ID}" | awk \'{print $1}\' | xargs --no-run-if-empty docker stop'
|
||||
sh 'docker ps | grep -e "skywalking-e2e-container-${BUILD_ID}" | awk \'{print $1}\' | xargs --no-run-if-empty docker rm'
|
||||
|
||||
// Files created by docker container in the directories that are mounted from the host to
|
||||
// the container can not be deleted by `deleteDir()`, we need to mount it again and delete them
|
||||
// inside the container
|
||||
//
|
||||
// Delete `/dist` folder
|
||||
sh 'docker run -v $(pwd)/dist:/sw alpine sleep 10 && rm -rf /sw/*'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ The text of each license is the standard Apache 2.0 license.
|
|||
Apache: commons-io 2.4: https://github.com/apache/commons-io, Apache 2.0
|
||||
Apache: commons-compress 1.18: https://github.com/apache/commons-compress, Apache 2.0
|
||||
Apache: tomcat 8.5.27: https://github.com/apache/tomcat/tree/trunk, Apache 2.0
|
||||
Apache: freemaker 2.3.28: https://github.com/apache/freemarker, Apache 2.0
|
||||
netty 5.5.0: https://github.com/netty/netty/blob/4.1/LICENSE.txt, Apache 2.0
|
||||
annotations 13.0: http://www.jetbrains.org, Apache 2.0
|
||||
compiler 0.9.3: https://github.com/spullara/mustache.java, Apache 2.0
|
||||
|
|
@ -323,6 +324,7 @@ The text of each license is the standard Apache 2.0 license.
|
|||
sundrio 0.9.2: https://github.com/sundrio/sundrio Apache 2.0
|
||||
Ctripcorp: apollo 1.4.0: https://github.com/ctripcorp/apollo Apache 2.0
|
||||
etcd4j 2.17.0: https://github.com/jurmous/etcd4j Apache 2.0
|
||||
javaassist 3.25.0-GA: https://github.com/jboss-javassist/javassist Apache 2.0
|
||||
|
||||
========================================================================
|
||||
MIT licenses
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
<include>*.yml</include>
|
||||
<include>*.xml</include>
|
||||
<include>*.properties</include>
|
||||
<include>*.oal</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ public class AgentPackagePath {
|
|||
return agentJarFile.getParentFile();
|
||||
}
|
||||
} else {
|
||||
String classLocation = urlString.substring(urlString.indexOf("file:"), urlString.length() - classResourcePath.length());
|
||||
int prefixLength = "file:".length();
|
||||
String classLocation = urlString.substring(prefixLength, urlString.length() - classResourcePath.length());
|
||||
return new File(classLocation);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ Provide OAL(Observability Analysis Language) to analysis incoming data in stream
|
|||
OAL focuses on metrics in Service, Service Instance and Endpoint. Because of that, the language is easy to
|
||||
learn and use.
|
||||
|
||||
Considering performance, reading and debugging, OAL is defined as a compile language.
|
||||
The OAL scripts will be compiled to normal Java codes in package stage.
|
||||
|
||||
Since 6.3, the OAL engine is embedded in OAP server runtime, as `oal-rt`(OAL Runtime).
|
||||
OAL scripts now locate in `/config` folder, user could simply change and reboot the server to make it effective.
|
||||
But still, OAL script is compile language, OAL Runtime generates java codes dynamically.
|
||||
|
||||
You could open set `SW_OAL_ENGINE_DEBUG=Y` at system env, to see which classes generated.
|
||||
|
||||
## Grammar
|
||||
Scripts should be named as `*.oal`
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ a oap image with name `bar/oap:foo`, run the following command
|
|||
* `grpc-java` and `java` folders in **oap-server/exporter/target/generated-sources/protobuf**
|
||||
* `grpc-java` and `java` folders in **oap-server/server-configuration/grpc-configuration-sync/target/generated-sources/protobuf**
|
||||
* `antlr4` folder in **oap-server/generate-tool-grammar/target/generated-sources**
|
||||
* `oal` folder in **oap-server/generated-analysis/target/generated-sources**
|
||||
|
||||
## Setup your Eclipse IDE
|
||||
**NOTICE**: If you clone the codes from GitHub, please make sure that you had finished step 1 to 7 in section **[Build from GitHub](#build-from-github)**, if you download the source codes from the official website of SkyWalking, please make sure that you had followed the steps in section **[Build from Apache source code release](#build-from-apache-source-code-release)**.
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ and private plugin developer should read this.
|
|||
- If you want to build a new probe or plugin in any language, please read [Component library definition and extension](Component-library-settings.md) document.
|
||||
- [Storage extension development guide](storage-extention.md). Help potential contributors to build a new
|
||||
storage implementor besides the official.
|
||||
- [Customize analysis by oal script](write-oal.md). Guide you to use oal script to make your own metrics available.
|
||||
- Customize analysis by oal script. OAL scripts locate in `config/official_analysis.oal`. You could change it and reboot the OAP server. Read
|
||||
[Observability Analysis Language Introduction](../concepts-and-designs/oal.md) if you need to learn about OAL script.
|
||||
- [Source and scope extension for new metrics](source-extension.md). If you want to analysis a new metrics, which SkyWalking
|
||||
haven't provide. You need to
|
||||
add a new receiver rather than choosing [existed receiver](../setup/backend/backend-receivers.md).
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
# Write OAL script
|
||||
Read [OAL overview](../concepts-and-designs/oal.md) to understand the oal script.
|
||||
|
||||
## Find oal script in source codes
|
||||
The official official_analysis.oal is [here](../../../oap-server/generated-analysis/src/main/resources/official_analysis.oal).
|
||||
|
||||
## Generate tool
|
||||
The `oap-server/generate-tool` module includes the source codes of compiling tool. This tool is already integrated
|
||||
maven compile phase. So, unless you want to change the tool source codes, you don't need to set anything.
|
||||
|
||||
Run `./mvnw compile` or `./mvnw package`, the generated codes of the oal script are in `oap-server/generate-tool/target/generated-sources/oal/*`.
|
||||
|
||||
## Write and recompile
|
||||
You could change the `official_analysis.oal` script, then recompile codes.
|
||||
The generated codes are in **oap-server/generated-analysis/target/generated-sources/oal**.
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool;
|
||||
|
||||
import freemarker.template.TemplateException;
|
||||
import java.io.*;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
import org.apache.skywalking.oal.tool.meta.*;
|
||||
import org.apache.skywalking.oal.tool.output.FileGenerator;
|
||||
import org.apache.skywalking.oal.tool.parser.*;
|
||||
import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException, TemplateException {
|
||||
AnnotationScan scopeScan = new AnnotationScan();
|
||||
scopeScan.registerListener(new DefaultScopeDefine.Listener());
|
||||
scopeScan.scan(null);
|
||||
|
||||
String modulePath = args[0];
|
||||
|
||||
String scriptFilePath = StringUtil.join(File.separatorChar, modulePath, "src", "main", "resources", "official_analysis.oal");
|
||||
String outputPath = StringUtil.join(File.separatorChar, modulePath, "..", "generated-analysis", "target", "generated-sources", "oal",
|
||||
"org", "apache", "skywalking", "oap", "server", "core", "analysis");
|
||||
String metaFilePath = StringUtil.join(File.separatorChar, modulePath, "src", "main", "resources", "generator-scope-meta.yml");
|
||||
|
||||
MetricsHolder.init();
|
||||
|
||||
File scriptFile = new File(scriptFilePath);
|
||||
if (!scriptFile.exists()) {
|
||||
throw new IllegalArgumentException("OAL script file [" + scriptFilePath + "] doesn't exist");
|
||||
}
|
||||
|
||||
File metaFile = new File(metaFilePath);
|
||||
if (!metaFile.exists()) {
|
||||
throw new IllegalArgumentException("Generator meta file [" + metaFilePath + "] doesn't exist");
|
||||
}
|
||||
|
||||
MetaReader reader = new MetaReader();
|
||||
MetaSettings metaSettings = reader.read(new FileInputStream(metaFile));
|
||||
SourceColumnsFactory.setSettings(metaSettings);
|
||||
|
||||
ScriptParser scriptParser = ScriptParser.createFromFile(scriptFilePath);
|
||||
OALScripts oalScripts = scriptParser.parse();
|
||||
|
||||
FileGenerator generator = new FileGenerator(oalScripts, outputPath);
|
||||
generator.generate();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.output;
|
||||
|
||||
import freemarker.template.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import org.apache.skywalking.oal.tool.parser.*;
|
||||
|
||||
public class FileGenerator {
|
||||
private List<AnalysisResult> results;
|
||||
private DisableCollection collection;
|
||||
private String outputPath;
|
||||
private Configuration configuration;
|
||||
private AllDispatcherContext allDispatcherContext;
|
||||
|
||||
public FileGenerator(OALScripts oalScripts, String outputPath) {
|
||||
this.results = oalScripts.getMetricsStmts();
|
||||
this.collection = oalScripts.getDisableCollection();
|
||||
this.outputPath = outputPath;
|
||||
configuration = new Configuration(new Version("2.3.28"));
|
||||
configuration.setEncoding(Locale.ENGLISH, "UTF-8");
|
||||
configuration.setClassLoaderForTemplateLoading(FileGenerator.class.getClassLoader(), "/code-templates");
|
||||
allDispatcherContext = new AllDispatcherContext();
|
||||
buildDispatcherContext();
|
||||
}
|
||||
|
||||
public void generate() throws IOException, TemplateException {
|
||||
for (AnalysisResult result : results) {
|
||||
generate(result, "Metrics.java", writer -> generateMetricsImplementor(result, writer));
|
||||
|
||||
String scopeName = result.getSourceName();
|
||||
File file = new File(outputPath, "generated/" + scopeName.toLowerCase() + "/" + scopeName + "Dispatcher.java");
|
||||
createFile(file);
|
||||
generateDispatcher(result, new FileWriter(file));
|
||||
}
|
||||
generateDisable();
|
||||
}
|
||||
|
||||
private void generate(AnalysisResult result, String fileSuffix,
|
||||
WriteWrapper writeWrapper) throws IOException, TemplateException {
|
||||
File file = new File(outputPath, buildSubFolderName(result, fileSuffix));
|
||||
createFile(file);
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
try {
|
||||
writeWrapper.execute(fileWriter);
|
||||
} finally {
|
||||
fileWriter.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void createFile(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
}
|
||||
|
||||
private String buildSubFolderName(AnalysisResult result, String suffix) {
|
||||
return "generated/"
|
||||
+ result.getSourceName().toLowerCase() + "/"
|
||||
+ result.getMetricsName() + suffix;
|
||||
}
|
||||
|
||||
void generateMetricsImplementor(AnalysisResult result, Writer output) throws IOException, TemplateException {
|
||||
configuration.getTemplate("MetricsImplementor.ftl").process(result, output);
|
||||
}
|
||||
|
||||
void generateDispatcher(AnalysisResult result, Writer output) throws IOException, TemplateException {
|
||||
String scopeName = result.getSourceName();
|
||||
DispatcherContext context = allDispatcherContext.getAllContext().get(scopeName);
|
||||
if (context != null) {
|
||||
configuration.getTemplate("DispatcherTemplate.ftl").process(context, output);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDispatcherContext() {
|
||||
for (AnalysisResult result : results) {
|
||||
String sourceName = result.getSourceName();
|
||||
|
||||
DispatcherContext context = allDispatcherContext.getAllContext().get(sourceName);
|
||||
if (context == null) {
|
||||
context = new DispatcherContext();
|
||||
context.setSource(sourceName);
|
||||
context.setPackageName(sourceName.toLowerCase());
|
||||
allDispatcherContext.getAllContext().put(sourceName, context);
|
||||
}
|
||||
context.getMetrics().add(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDisable() throws IOException, TemplateException {
|
||||
File file = new File(outputPath, "generated/DisableSourceDefinition.java");
|
||||
createFile(file);
|
||||
configuration.getTemplate("DisableSourceDefinition.ftl").process(collection, new FileWriter(file));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.generated;
|
||||
<#if (allDisableSources?size>0)>
|
||||
import org.apache.skywalking.oap.server.core.analysis.Disable;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* This class is auto generated. Please don't change this class manually.
|
||||
*
|
||||
* @author Observability Analysis Language code generator
|
||||
*/
|
||||
<#list allDisableSources as disableSource>
|
||||
@Disable("${disableSource}")
|
||||
</#list>
|
||||
public class DisableSourceDefinition {
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.generated.${packageName};
|
||||
|
||||
import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
|
||||
<#if (metrics?size>0)>
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||
<#list metrics as metrics>
|
||||
<#if metrics.filterExpressions??>
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.expression.*;
|
||||
<#break>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
import org.apache.skywalking.oap.server.core.source.*;
|
||||
|
||||
/**
|
||||
* This class is auto generated. Please don't change this class manually.
|
||||
*
|
||||
* @author Observability Analysis Language code generator
|
||||
*/
|
||||
public class ${source}Dispatcher implements SourceDispatcher<${source}> {
|
||||
|
||||
@Override public void dispatch(${source} source) {
|
||||
<#list metrics as metrics>
|
||||
do${metrics.metricsName}(source);
|
||||
</#list>
|
||||
}
|
||||
|
||||
<#list metrics as metrics>
|
||||
private void do${metrics.metricsName}(${source} source) {
|
||||
${metrics.metricsName}Metrics metrics = new ${metrics.metricsName}Metrics();
|
||||
|
||||
<#if metrics.filterExpressions??>
|
||||
<#list metrics.filterExpressions as filterExpression>
|
||||
<#if filterExpression.expressionObject == "GreaterMatch" || filterExpression.expressionObject == "LessMatch" || filterExpression.expressionObject == "GreaterEqualMatch" || filterExpression.expressionObject == "LessEqualMatch">
|
||||
if (!new ${filterExpression.expressionObject}().match(${filterExpression.left}, ${filterExpression.right})) {
|
||||
return;
|
||||
}
|
||||
<#else>
|
||||
if (!new ${filterExpression.expressionObject}().setLeft(${filterExpression.left}).setRight(${filterExpression.right}).match()) {
|
||||
return;
|
||||
}
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
metrics.setTimeBucket(source.getTimeBucket());
|
||||
<#list metrics.fieldsFromSource as field>
|
||||
metrics.${field.fieldSetter}(source.${field.fieldGetter}());
|
||||
</#list>
|
||||
metrics.${metrics.entryMethod.methodName}(<#list metrics.entryMethod.argsExpressions as arg>${arg}<#if arg_has_next>, </#if></#list>);
|
||||
|
||||
MetricsStreamProcessor.getInstance().in(metrics);
|
||||
}
|
||||
</#list>
|
||||
}
|
||||
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.generated.${packageName};
|
||||
|
||||
import java.util.*;
|
||||
<#if (fieldsFromSource?size>0) >
|
||||
import lombok.*;
|
||||
</#if>
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
import org.apache.skywalking.oap.server.core.Const;
|
||||
<#break>
|
||||
</#if>
|
||||
</#list>
|
||||
import org.apache.skywalking.oap.server.core.analysis.Stream;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.*;
|
||||
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.storage.StorageBuilder;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.*;
|
||||
|
||||
/**
|
||||
* This class is auto generated. Please don't change this class manually.
|
||||
*
|
||||
* @author Observability Analysis Language code generator
|
||||
*/
|
||||
@Stream(name = "${tableName}", scopeId = ${sourceScopeId}, builder = ${metricsName}Metrics.Builder.class, processor = MetricsStreamProcessor.class)
|
||||
public class ${metricsName}Metrics extends ${metricsClassName} implements WithMetadata {
|
||||
|
||||
<#list fieldsFromSource as sourceField>
|
||||
@Setter @Getter @Column(columnName = "${sourceField.columnName}") <#if sourceField.isID()>@IDColumn</#if> private ${sourceField.typeName} ${sourceField.fieldName};
|
||||
</#list>
|
||||
|
||||
@Override public String id() {
|
||||
String splitJointId = String.valueOf(getTimeBucket());
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
splitJointId += Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
<#else>
|
||||
splitJointId += Const.ID_SPLIT + String.valueOf(${sourceField.fieldName});
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
return splitJointId;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result = 17;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
result = 31 * result + ${sourceField.fieldName}.hashCode();
|
||||
<#else>
|
||||
result += Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
result = 31 * result + (int)getTimeBucket();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public int remoteHashCode() {
|
||||
int result = 17;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
result = 31 * result + ${sourceField.fieldName}.hashCode();
|
||||
<#else>
|
||||
result += Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
|
||||
${metricsName}Metrics metrics = (${metricsName}Metrics)obj;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
if (!${sourceField.fieldName}.equals(metrics.${sourceField.fieldName}))
|
||||
<#else>
|
||||
if (${sourceField.fieldName} != metrics.${sourceField.fieldName})
|
||||
</#if>
|
||||
return false;
|
||||
</#if>
|
||||
</#list>
|
||||
|
||||
if (getTimeBucket() != metrics.getTimeBucket())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public RemoteData.Builder serialize() {
|
||||
RemoteData.Builder remoteBuilder = RemoteData.newBuilder();
|
||||
<#list serializeFields.stringFields as field>
|
||||
remoteBuilder.addDataStrings(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.longFields as field>
|
||||
remoteBuilder.addDataLongs(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.doubleFields as field>
|
||||
remoteBuilder.addDataDoubles(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intFields as field>
|
||||
remoteBuilder.addDataIntegers(${field.getter}());
|
||||
</#list>
|
||||
<#list serializeFields.intLongValuePairListFields as field>
|
||||
${field.getter}().forEach(element -> remoteBuilder.addDataIntLongPairList(element.serialize()));
|
||||
</#list>
|
||||
|
||||
return remoteBuilder;
|
||||
}
|
||||
|
||||
@Override public void deserialize(RemoteData remoteData) {
|
||||
<#list serializeFields.stringFields as field>
|
||||
${field.setter}(remoteData.getDataStrings(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.longFields as field>
|
||||
${field.setter}(remoteData.getDataLongs(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.doubleFields as field>
|
||||
${field.setter}(remoteData.getDataDoubles(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intFields as field>
|
||||
${field.setter}(remoteData.getDataIntegers(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intLongValuePairListFields as field>
|
||||
setDetailGroup(new IntKeyLongValueArray(30));
|
||||
remoteData.getDataIntLongPairListList().forEach(element -> {
|
||||
getDetailGroup().add(new IntKeyLongValue(element.getKey(), element.getValue()));
|
||||
});
|
||||
</#list>
|
||||
|
||||
}
|
||||
|
||||
@Override public MetricsMetaInfo getMeta() {
|
||||
return new MetricsMetaInfo("${varName}", ${sourceScopeId}<#if (fieldsFromSource?size>0) ><#list fieldsFromSource as field><#if field.isID()>, ${field.fieldName}</#if></#list></#if>);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toHour() {
|
||||
${metricsName}Metrics metrics = new ${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInHour());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInHour());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toDay() {
|
||||
${metricsName}Metrics metrics = new ${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInDay());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInDay());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toMonth() {
|
||||
${metricsName}Metrics metrics = new ${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInMonth());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInMonth());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public static class Builder implements StorageBuilder<${metricsName}Metrics> {
|
||||
|
||||
@Override public Map<String, Object> data2Map(${metricsName}Metrics storageData) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
<#list fieldsFromSource as field>
|
||||
map.put("${field.columnName}", storageData.${field.fieldGetter}());
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
map.put("${field.columnName}", storageData.${field.fieldGetter}());
|
||||
</#list>
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override public ${metricsName}Metrics map2Data(Map<String, Object> dbMap) {
|
||||
${metricsName}Metrics metrics = new ${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(((Number)dbMap.get("${field.columnName}")).${field.typeName}Value());
|
||||
<#elseif field.typeName == "java.lang.String">
|
||||
metrics.${field.fieldSetter}((String)dbMap.get("${field.columnName}"));
|
||||
<#else>
|
||||
metrics.${field.fieldSetter}(new ${field.typeName}((String)dbMap.get("${field.columnName}")));
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(((Number)dbMap.get("${field.columnName}")).${field.typeName}Value());
|
||||
<#elseif field.typeName == "java.lang.String">
|
||||
metrics.${field.fieldSetter}((String)dbMap.get("${field.columnName}"));
|
||||
<#else>
|
||||
metrics.${field.fieldSetter}(new ${field.typeName}((String)dbMap.get("${field.columnName}")));
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.output;
|
||||
|
||||
import freemarker.template.TemplateException;
|
||||
import java.io.*;
|
||||
import java.util.LinkedList;
|
||||
import org.apache.skywalking.oal.tool.meta.*;
|
||||
import org.apache.skywalking.oal.tool.parser.*;
|
||||
import org.junit.*;
|
||||
|
||||
public class FileGeneratorTest {
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
MetaReader reader = new MetaReader();
|
||||
InputStream stream = MetaReaderTest.class.getResourceAsStream("/scope-meta.yml");
|
||||
MetaSettings metaSettings = reader.read(stream);
|
||||
SourceColumnsFactory.setSettings(metaSettings);
|
||||
}
|
||||
|
||||
private AnalysisResult buildResult() {
|
||||
AnalysisResult result = new AnalysisResult();
|
||||
result.setVarName("generate_metrics");
|
||||
result.setSourceName("Service");
|
||||
result.setSourceScopeId(1);
|
||||
result.setPackageName("service.serviceavg");
|
||||
result.setTableName("service_avg");
|
||||
result.setSourceAttribute("latency");
|
||||
result.setMetricsName("ServiceAvg");
|
||||
result.setAggregationFunctionName("avg");
|
||||
result.setMetricsClassName("LongAvgMetrics");
|
||||
|
||||
FilterExpression equalExpression = new FilterExpression();
|
||||
equalExpression.setExpressionObject("EqualMatch");
|
||||
equalExpression.setLeft("source.getName()");
|
||||
equalExpression.setRight("\"/service/prod/save\"");
|
||||
result.addFilterExpressions(equalExpression);
|
||||
|
||||
FilterExpression greaterExpression = new FilterExpression();
|
||||
greaterExpression.setExpressionObject("GreaterMatch");
|
||||
greaterExpression.setLeft("source.getLatency()");
|
||||
greaterExpression.setRight("1000");
|
||||
result.addFilterExpressions(greaterExpression);
|
||||
|
||||
EntryMethod method = new EntryMethod();
|
||||
method.setMethodName("combine");
|
||||
method.setArgsExpressions(new LinkedList<>());
|
||||
method.getArgsExpressions().add("source.getLatency()");
|
||||
method.getArgsExpressions().add("1");
|
||||
result.setEntryMethod(method);
|
||||
result.addPersistentField("summation", "summation", long.class);
|
||||
result.addPersistentField("count", "count", int.class);
|
||||
result.addPersistentField("value", "value", long.class);
|
||||
result.addPersistentField("timeBucket", "time_bucket", long.class);
|
||||
result.addPersistentField("stringField", "string_field", String.class);
|
||||
result.setFieldsFromSource(SourceColumnsFactory.getColumns("Service"));
|
||||
result.generateSerializeFields();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMetricsImplementor() throws IOException, TemplateException {
|
||||
AnalysisResult result = buildResult();
|
||||
|
||||
OALScripts oalScripts = new OALScripts();
|
||||
oalScripts.getMetricsStmts().add(result);
|
||||
|
||||
FileGenerator fileGenerator = new FileGenerator(oalScripts, ".");
|
||||
StringWriter writer = new StringWriter();
|
||||
fileGenerator.generateMetricsImplementor(result, writer);
|
||||
Assert.assertEquals(readExpectedFile("MetricsImplementorExpected.java"), writer.toString());
|
||||
|
||||
// fileGenerator.generateMetricsImplementor(result, new OutputStreamWriter(System.out));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceDispatcher() throws IOException, TemplateException {
|
||||
AnalysisResult result = buildResult();
|
||||
|
||||
OALScripts oalScripts = new OALScripts();
|
||||
oalScripts.getMetricsStmts().add(result);
|
||||
|
||||
FileGenerator fileGenerator = new FileGenerator(oalScripts, ".");
|
||||
StringWriter writer = new StringWriter();
|
||||
fileGenerator.generateDispatcher(result, writer);
|
||||
Assert.assertEquals(readExpectedFile("ServiceDispatcherExpected.java"), writer.toString());
|
||||
|
||||
// fileGenerator.generateDispatcher(result, new OutputStreamWriter(System.out));
|
||||
}
|
||||
|
||||
private String readExpectedFile(String filename) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(FileGenerator.class.getResourceAsStream("/expectedFiles/" + filename)));
|
||||
|
||||
StringBuilder fileContent = new StringBuilder();
|
||||
String sCurrentLine;
|
||||
|
||||
while ((sCurrentLine = reader.readLine()) != null) {
|
||||
fileContent.append(sCurrentLine).append("\n");
|
||||
}
|
||||
|
||||
return fileContent.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>oap-server</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>6.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>generated-analysis</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>server-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- This dependency will be excluded in starter pom.xml -->
|
||||
<!-- Use default scope because `org.apache.skywalking.oal.tool.Main` in this lib, only this could make code generate tool works -->
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>generate-tool</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<sourceDirectory>target/generated-sources/oal</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>org.apache.skywalking.oal.tool.Main</mainClass>
|
||||
<arguments>
|
||||
<argument>${project.basedir}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -25,13 +25,12 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>generate-tool-grammar</artifactId>
|
||||
<artifactId>oal-grammar</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.7.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
// Observability Analysis Language lexer
|
||||
lexer grammar OALLexer;
|
||||
|
||||
@Header {package org.apache.skywalking.oal.tool.grammar;}
|
||||
@Header {package org.apache.skywalking.oal.rt.grammar;}
|
||||
|
||||
// Keywords
|
||||
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
parser grammar OALParser;
|
||||
|
||||
@Header {package org.apache.skywalking.oal.tool.grammar;}
|
||||
@Header {package org.apache.skywalking.oal.rt.grammar;}
|
||||
|
||||
options { tokenVocab=OALLexer; }
|
||||
|
||||
|
|
@ -17,7 +17,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">
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>oap-server</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
|
|
@ -25,7 +26,7 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>generate-tool</artifactId>
|
||||
<artifactId>oal-rt</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
@ -35,28 +36,24 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>generate-tool-grammar</artifactId>
|
||||
<artifactId>oal-grammar</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.28</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.rt;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Version;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtConstructor;
|
||||
import javassist.CtField;
|
||||
import javassist.CtNewConstructor;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ClassFile;
|
||||
import javassist.bytecode.ConstPool;
|
||||
import javassist.bytecode.SignatureAttribute;
|
||||
import javassist.bytecode.annotation.Annotation;
|
||||
import javassist.bytecode.annotation.ClassMemberValue;
|
||||
import javassist.bytecode.annotation.IntegerMemberValue;
|
||||
import javassist.bytecode.annotation.StringMemberValue;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
import org.apache.skywalking.oal.rt.meta.MetaReader;
|
||||
import org.apache.skywalking.oal.rt.meta.MetaSettings;
|
||||
import org.apache.skywalking.oal.rt.output.AllDispatcherContext;
|
||||
import org.apache.skywalking.oal.rt.output.DispatcherContext;
|
||||
import org.apache.skywalking.oal.rt.parser.AnalysisResult;
|
||||
import org.apache.skywalking.oal.rt.parser.MetricsHolder;
|
||||
import org.apache.skywalking.oal.rt.parser.OALScripts;
|
||||
import org.apache.skywalking.oal.rt.parser.ScriptParser;
|
||||
import org.apache.skywalking.oal.rt.parser.SourceColumn;
|
||||
import org.apache.skywalking.oal.rt.parser.SourceColumnsFactory;
|
||||
import org.apache.skywalking.oap.server.core.WorkPath;
|
||||
import org.apache.skywalking.oap.server.core.analysis.DisableRegister;
|
||||
import org.apache.skywalking.oap.server.core.analysis.DispatcherDetectorListener;
|
||||
import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Stream;
|
||||
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALCompileException;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngine;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.IDColumn;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||
import org.apache.skywalking.oap.server.library.util.ResourceUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* OAL Runtime is the class generation engine, which load the generated classes from OAL scrip definitions. This runtime
|
||||
* is loaded dynamically.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class OALRuntime implements OALEngine {
|
||||
private static final Logger logger = LoggerFactory.getLogger(OALRuntime.class);
|
||||
|
||||
private static final String CLASS_FILE_CHARSET = "UTF-8";
|
||||
private static final String METRICS_FUNCTION_PACKAGE = "org.apache.skywalking.oap.server.core.analysis.metrics.";
|
||||
private static final String DYNAMIC_METRICS_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.metrics.";
|
||||
private static final String DYNAMIC_METRICS_BUILDER_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.metrics.builder.";
|
||||
private static final String DYNAMIC_DISPATCHER_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.dispatcher.";
|
||||
private static final String WITH_METADATA_INTERFACE = "org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata";
|
||||
private static final String STORAGE_BUILDER_INTERFACE = "org.apache.skywalking.oap.server.core.storage.StorageBuilder";
|
||||
private static final String DISPATCHER_INTERFACE = "org.apache.skywalking.oap.server.core.analysis.SourceDispatcher";
|
||||
private static final String SOURCE_PACKAGE = "org.apache.skywalking.oap.server.core.source.";
|
||||
private static final String METRICS_STREAM_PROCESSOR = "org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor";
|
||||
private static final String[] METRICS_CLASS_METHODS =
|
||||
{"id", "hashCode", "remoteHashCode", "equals", "serialize", "deserialize", "getMeta", "toHour", "toDay", "toMonth"};
|
||||
private static final String[] METRICS_BUILDER_CLASS_METHODS =
|
||||
{"data2Map", "map2Data"};
|
||||
private final ClassPool classPool;
|
||||
private ClassLoader currentClassLoader;
|
||||
private Configuration configuration;
|
||||
private AllDispatcherContext allDispatcherContext;
|
||||
private StreamAnnotationListener streamAnnotationListener;
|
||||
private DispatcherDetectorListener dispatcherDetectorListener;
|
||||
private final List<Class> metricsClasses;
|
||||
private final List<Class> dispatcherClasses;
|
||||
private final boolean openEngineDebug;
|
||||
|
||||
public OALRuntime() {
|
||||
classPool = ClassPool.getDefault();
|
||||
configuration = new Configuration(new Version("2.3.28"));
|
||||
configuration.setEncoding(Locale.ENGLISH, CLASS_FILE_CHARSET);
|
||||
configuration.setClassLoaderForTemplateLoading(OALRuntime.class.getClassLoader(), "/code-templates");
|
||||
allDispatcherContext = new AllDispatcherContext();
|
||||
metricsClasses = new ArrayList<>();
|
||||
dispatcherClasses = new ArrayList<>();
|
||||
openEngineDebug = !StringUtil.isEmpty(System.getenv("SW_OAL_ENGINE_DEBUG"));
|
||||
}
|
||||
|
||||
@Override public void setStreamListener(StreamAnnotationListener listener) throws ModuleStartException {
|
||||
this.streamAnnotationListener = listener;
|
||||
}
|
||||
|
||||
@Override public void setDispatcherListener(DispatcherDetectorListener listener) throws ModuleStartException {
|
||||
dispatcherDetectorListener = listener;
|
||||
}
|
||||
|
||||
@Override public void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException {
|
||||
prepareRTTempFolder();
|
||||
|
||||
this.currentClassLoader = currentClassLoader;
|
||||
Reader read;
|
||||
try {
|
||||
read = ResourceUtils.read("scope-meta.yml");
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new ModuleStartException("Can't locate scope-meta.yml", e);
|
||||
}
|
||||
|
||||
MetaReader reader = new MetaReader();
|
||||
MetaSettings metaSettings = reader.read(read);
|
||||
SourceColumnsFactory.setSettings(metaSettings);
|
||||
|
||||
try {
|
||||
MetricsHolder.init();
|
||||
} catch (IOException e) {
|
||||
throw new ModuleStartException("load metrics functions error.", e);
|
||||
}
|
||||
|
||||
try {
|
||||
read = ResourceUtils.read("official_analysis.oal");
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new ModuleStartException("Can't locate official_analysis.oal", e);
|
||||
}
|
||||
|
||||
OALScripts oalScripts;
|
||||
try {
|
||||
ScriptParser scriptParser = ScriptParser.createFromFile(read);
|
||||
oalScripts = scriptParser.parse();
|
||||
} catch (IOException e) {
|
||||
throw new ModuleStartException("OAL script parse analysis failure.", e);
|
||||
}
|
||||
|
||||
this.generateClassAtRuntime(oalScripts);
|
||||
}
|
||||
|
||||
@Override public void notifyAllListeners() throws ModuleStartException {
|
||||
metricsClasses.forEach(streamAnnotationListener::notify);
|
||||
for (Class dispatcherClass : dispatcherClasses) {
|
||||
try {
|
||||
dispatcherDetectorListener.addIfAsSourceDispatcher(dispatcherClass);
|
||||
} catch (Exception e) {
|
||||
throw new ModuleStartException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateClassAtRuntime(OALScripts oalScripts) throws OALCompileException {
|
||||
List<AnalysisResult> metricsStmts = oalScripts.getMetricsStmts();
|
||||
metricsStmts.forEach(this::buildDispatcherContext);
|
||||
|
||||
for (AnalysisResult metricsStmt : metricsStmts) {
|
||||
metricsClasses.add(generateMetricsClass(metricsStmt));
|
||||
generateMetricsBuilderClass(metricsStmt);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, DispatcherContext> entry : allDispatcherContext.getAllContext().entrySet()) {
|
||||
dispatcherClasses.add(generateDispatcherClass(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
oalScripts.getDisableCollection().getAllDisableSources().forEach(disable -> {
|
||||
DisableRegister.INSTANCE.add(disable);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate metrics class, and inject it to classloader
|
||||
*
|
||||
* @param metricsStmt
|
||||
* @return
|
||||
* @throws OALCompileException
|
||||
*/
|
||||
private Class generateMetricsClass(AnalysisResult metricsStmt) throws OALCompileException {
|
||||
String className = metricsClassName(metricsStmt, false);
|
||||
CtClass parentMetricsClass = null;
|
||||
try {
|
||||
parentMetricsClass = classPool.get(METRICS_FUNCTION_PACKAGE + metricsStmt.getMetricsClassName());
|
||||
} catch (NotFoundException e) {
|
||||
logger.error("Can't find parent class for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
CtClass metricsClass = classPool.makeClass(metricsClassName(metricsStmt, true), parentMetricsClass);
|
||||
try {
|
||||
metricsClass.addInterface(classPool.get(WITH_METADATA_INTERFACE));
|
||||
} catch (NotFoundException e) {
|
||||
logger.error("Can't find WithMetadata interface for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
ClassFile metricsClassClassFile = metricsClass.getClassFile();
|
||||
ConstPool constPool = metricsClassClassFile.getConstPool();
|
||||
|
||||
/**
|
||||
* Create empty construct
|
||||
*/
|
||||
try {
|
||||
CtConstructor defaultConstructor = CtNewConstructor.make("public " + className + "() {}", metricsClass);
|
||||
metricsClass.addConstructor(defaultConstructor);
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't add empty constructor in " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fields with annotations.
|
||||
*
|
||||
* private ${sourceField.typeName} ${sourceField.fieldName};
|
||||
*/
|
||||
for (SourceColumn field : metricsStmt.getFieldsFromSource()) {
|
||||
try {
|
||||
CtField newField = CtField.make("private " + field.getType().getName() + " " + field.getFieldName() + ";", metricsClass);
|
||||
|
||||
metricsClass.addField(newField);
|
||||
|
||||
metricsClass.addMethod(CtNewMethod.getter(field.getFieldGetter(), newField));
|
||||
metricsClass.addMethod(CtNewMethod.setter(field.getFieldSetter(), newField));
|
||||
|
||||
AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
|
||||
/**
|
||||
* Add @Column(columnName = "${sourceField.columnName}")
|
||||
*/
|
||||
Annotation columnAnnotation = new Annotation(Column.class.getName(), constPool);
|
||||
columnAnnotation.addMemberValue("columnName", new StringMemberValue(field.getColumnName(), constPool));
|
||||
annotationsAttribute.addAnnotation(columnAnnotation);
|
||||
|
||||
if (field.isID()) {
|
||||
/**
|
||||
* Add @IDColumn
|
||||
*/
|
||||
Annotation idAnnotation = new Annotation(IDColumn.class.getName(), constPool);
|
||||
annotationsAttribute.addAnnotation(idAnnotation);
|
||||
}
|
||||
|
||||
newField.getFieldInfo().addAttribute(annotationsAttribute);
|
||||
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't add field(including set/get) " + field.getFieldName() + " in " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate methods
|
||||
*/
|
||||
for (String method : METRICS_CLASS_METHODS) {
|
||||
StringWriter methodEntity = new StringWriter();
|
||||
try {
|
||||
configuration.getTemplate("metrics/" + method + ".ftl").process(metricsStmt, methodEntity);
|
||||
metricsClass.addMethod(CtNewMethod.make(methodEntity.toString(), metricsClass));
|
||||
} catch (Exception e) {
|
||||
logger.error("Can't generate method " + method + " for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add following annotation to the metrics class
|
||||
*
|
||||
* at Stream(name = "${tableName}", scopeId = ${sourceScopeId}, builder = ${metricsName}Metrics.Builder.class, processor = MetricsStreamProcessor.class)
|
||||
*/
|
||||
AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
|
||||
Annotation streamAnnotation = new Annotation(Stream.class.getName(), constPool);
|
||||
streamAnnotation.addMemberValue("name", new StringMemberValue(metricsStmt.getTableName(), constPool));
|
||||
streamAnnotation.addMemberValue("scopeId", new IntegerMemberValue(constPool, metricsStmt.getSourceScopeId()));
|
||||
streamAnnotation.addMemberValue("builder", new ClassMemberValue(metricsBuilderClassName(metricsStmt, true), constPool));
|
||||
streamAnnotation.addMemberValue("processor", new ClassMemberValue(METRICS_STREAM_PROCESSOR, constPool));
|
||||
|
||||
annotationsAttribute.addAnnotation(streamAnnotation);
|
||||
metricsClassClassFile.addAttribute(annotationsAttribute);
|
||||
|
||||
Class targetClass;
|
||||
try {
|
||||
targetClass = metricsClass.toClass(currentClassLoader, null);
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't compile/load " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
logger.debug("Generate metrics class, " + metricsClass.getName());
|
||||
writeGeneratedFile(metricsClass, metricsClass.getSimpleName(), "metrics");
|
||||
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate metrics class builder and inject it to classloader
|
||||
*
|
||||
* @param metricsStmt
|
||||
* @throws OALCompileException
|
||||
*/
|
||||
private void generateMetricsBuilderClass(AnalysisResult metricsStmt) throws OALCompileException {
|
||||
String className = metricsBuilderClassName(metricsStmt, false);
|
||||
CtClass metricsBuilderClass = classPool.makeClass(metricsBuilderClassName(metricsStmt, true));
|
||||
try {
|
||||
metricsBuilderClass.addInterface(classPool.get(STORAGE_BUILDER_INTERFACE));
|
||||
} catch (NotFoundException e) {
|
||||
logger.error("Can't find StorageBuilder interface for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
ClassFile metricsClassClassFile = metricsBuilderClass.getClassFile();
|
||||
ConstPool constPool = metricsClassClassFile.getConstPool();
|
||||
|
||||
/**
|
||||
* Create empty construct
|
||||
*/
|
||||
try {
|
||||
CtConstructor defaultConstructor = CtNewConstructor.make("public " + className + "() {}", metricsBuilderClass);
|
||||
metricsBuilderClass.addConstructor(defaultConstructor);
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't add empty constructor in " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate methods
|
||||
*/
|
||||
for (String method : METRICS_BUILDER_CLASS_METHODS) {
|
||||
StringWriter methodEntity = new StringWriter();
|
||||
try {
|
||||
configuration.getTemplate("metrics-builder/" + method + ".ftl").process(metricsStmt, methodEntity);
|
||||
metricsBuilderClass.addMethod(CtNewMethod.make(methodEntity.toString(), metricsBuilderClass));
|
||||
} catch (Exception e) {
|
||||
logger.error("Can't generate method " + method + " for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
metricsBuilderClass.toClass(currentClassLoader, null);
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't compile/load " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
writeGeneratedFile(metricsBuilderClass, className, "metrics/builder");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SourceDispatcher class and inject it to classloader
|
||||
*
|
||||
* @throws OALCompileException
|
||||
*/
|
||||
private Class generateDispatcherClass(String scopeName,
|
||||
DispatcherContext dispatcherContext) throws OALCompileException {
|
||||
|
||||
String className = dispatcherClassName(scopeName, false);
|
||||
CtClass dispatcherClass = classPool.makeClass(dispatcherClassName(scopeName, true));
|
||||
try {
|
||||
CtClass dispatcherInterface = classPool.get(DISPATCHER_INTERFACE);
|
||||
|
||||
dispatcherClass.addInterface(dispatcherInterface);
|
||||
|
||||
/**
|
||||
* Set generic signature
|
||||
*/
|
||||
String sourceClassName = SOURCE_PACKAGE + dispatcherContext.getSource();
|
||||
SignatureAttribute.ClassSignature dispatcherSignature = new SignatureAttribute.ClassSignature(null, null,
|
||||
// Set interface and its generic params
|
||||
new SignatureAttribute.ClassType[] {
|
||||
new SignatureAttribute.ClassType(SourceDispatcher.class.getCanonicalName(),
|
||||
new SignatureAttribute.TypeArgument[] {new SignatureAttribute.TypeArgument(new SignatureAttribute.ClassType(sourceClassName))}
|
||||
)});
|
||||
|
||||
dispatcherClass.setGenericSignature(dispatcherSignature.encode());
|
||||
} catch (NotFoundException e) {
|
||||
logger.error("Can't find Dispatcher interface for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate methods
|
||||
*/
|
||||
for (AnalysisResult dispatcherContextMetric : dispatcherContext.getMetrics()) {
|
||||
StringWriter methodEntity = new StringWriter();
|
||||
try {
|
||||
configuration.getTemplate("dispatcher/doMetrics.ftl").process(dispatcherContextMetric, methodEntity);
|
||||
dispatcherClass.addMethod(CtNewMethod.make(methodEntity.toString(), dispatcherClass));
|
||||
} catch (Exception e) {
|
||||
logger.error("Can't generate method do" + dispatcherContextMetric.getMetricsName() + " for " + className + ".", e);
|
||||
logger.error("Method body as following" + System.lineSeparator() + "{}", methodEntity);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
StringWriter methodEntity = new StringWriter();
|
||||
configuration.getTemplate("dispatcher/dispatch.ftl").process(dispatcherContext, methodEntity);
|
||||
dispatcherClass.addMethod(CtNewMethod.make(methodEntity.toString(), dispatcherClass));
|
||||
} catch (Exception e) {
|
||||
logger.error("Can't generate method dispatch for " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
Class targetClass;
|
||||
try {
|
||||
targetClass = dispatcherClass.toClass(currentClassLoader, null);
|
||||
} catch (CannotCompileException e) {
|
||||
logger.error("Can't compile/load " + className + ".", e);
|
||||
throw new OALCompileException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
writeGeneratedFile(dispatcherClass, className, "dispatcher");
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
private String metricsClassName(AnalysisResult metricsStmt, boolean fullName) {
|
||||
return (fullName ? DYNAMIC_METRICS_CLASS_PACKAGE : "") + metricsStmt.getMetricsName() + "Metrics";
|
||||
}
|
||||
|
||||
private String metricsBuilderClassName(AnalysisResult metricsStmt, boolean fullName) {
|
||||
return (fullName ? DYNAMIC_METRICS_BUILDER_CLASS_PACKAGE : "") + metricsStmt.getMetricsName() + "MetricsBuilder";
|
||||
}
|
||||
|
||||
private String dispatcherClassName(String scopeName, boolean fullName) {
|
||||
return (fullName ? DYNAMIC_DISPATCHER_CLASS_PACKAGE : "") + scopeName + "Dispatcher";
|
||||
}
|
||||
|
||||
private void buildDispatcherContext(AnalysisResult metricsStmt) {
|
||||
String sourceName = metricsStmt.getSourceName();
|
||||
|
||||
DispatcherContext context = allDispatcherContext.getAllContext().get(sourceName);
|
||||
if (context == null) {
|
||||
context = new DispatcherContext();
|
||||
context.setSource(sourceName);
|
||||
context.setPackageName(sourceName.toLowerCase());
|
||||
allDispatcherContext.getAllContext().put(sourceName, context);
|
||||
}
|
||||
context.getMetrics().add(metricsStmt);
|
||||
}
|
||||
|
||||
private void prepareRTTempFolder() {
|
||||
if (openEngineDebug) {
|
||||
File workPath = WorkPath.getPath();
|
||||
File folder = new File(workPath.getParentFile(), "oal-rt/");
|
||||
if (folder.exists()) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(folder);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Can't delete " + folder.getAbsolutePath() + " temp folder.", e);
|
||||
}
|
||||
}
|
||||
folder.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeGeneratedFile(CtClass metricsClass, String className, String type) throws OALCompileException {
|
||||
if (openEngineDebug) {
|
||||
DataOutputStream printWriter = null;
|
||||
try {
|
||||
File workPath = WorkPath.getPath();
|
||||
File folder = new File(workPath.getParentFile(), "oal-rt/" + type);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
File file = new File(folder, className + ".class");
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
file.createNewFile();
|
||||
|
||||
printWriter = new DataOutputStream(new FileOutputStream(file));
|
||||
metricsClass.toBytecode(printWriter);
|
||||
printWriter.flush();
|
||||
} catch (IOException e) {
|
||||
logger.warn("Can't create " + className + ".txt, ignore.", e);
|
||||
return;
|
||||
} catch (CannotCompileException e) {
|
||||
logger.warn("Can't compile " + className + ".class(should not happen), ignore.", e);
|
||||
return;
|
||||
} finally {
|
||||
if (printWriter != null) {
|
||||
try {
|
||||
printWriter.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -16,18 +16,26 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.meta;
|
||||
package org.apache.skywalking.oal.rt.meta;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
public class MetaReader {
|
||||
public MetaSettings read(InputStream settingFileStream) {
|
||||
public MetaSettings read(Reader reader) {
|
||||
Yaml yaml = new Yaml();
|
||||
MetaSettings settings = yaml.loadAs(settingFileStream, MetaSettings.class);
|
||||
MetaSettings settings = yaml.loadAs(reader, MetaSettings.class);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public MetaSettings read(InputStream reader) {
|
||||
Yaml yaml = new Yaml();
|
||||
MetaSettings settings = yaml.loadAs(reader, MetaSettings.class);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.meta;
|
||||
package org.apache.skywalking.oal.rt.meta;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.meta;
|
||||
package org.apache.skywalking.oal.rt.meta;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oal.tool.parser.SourceColumn;
|
||||
import org.apache.skywalking.oal.rt.parser.SourceColumn;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.output;
|
||||
package org.apache.skywalking.oal.rt.output;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.output;
|
||||
package org.apache.skywalking.oal.rt.output;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oal.tool.parser.AnalysisResult;
|
||||
import org.apache.skywalking.oal.rt.parser.AnalysisResult;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
|
|
@ -44,7 +44,7 @@ public class AnalysisResult {
|
|||
|
||||
private EntryMethod entryMethod;
|
||||
|
||||
private List<FilterExpression> filterExpressions;
|
||||
private List<Expression> filterExpressions;
|
||||
|
||||
private List<ConditionExpression> filterExpressionsParserResult;
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ public class AnalysisResult {
|
|||
funcConditionExpressions.add(conditionExpression);
|
||||
}
|
||||
|
||||
public void addFilterExpressions(FilterExpression filterExpression) {
|
||||
public void addFilterExpressions(Expression filterExpression) {
|
||||
if (filterExpressions == null) {
|
||||
filterExpressions = new LinkedList<>();
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
|
||||
import org.apache.skywalking.oal.rt.util.ClassMethodUtil;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
@Setter(AccessLevel.PUBLIC)
|
||||
|
|
@ -16,12 +16,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
|
||||
import org.apache.skywalking.oal.rt.util.ClassMethodUtil;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.*;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ public class DeepAnalysis {
|
|||
List<ConditionExpression> expressions = result.getFilterExpressionsParserResult();
|
||||
if (expressions != null && expressions.size() > 0) {
|
||||
for (ConditionExpression expression : expressions) {
|
||||
FilterExpression filterExpression = new FilterExpression();
|
||||
Expression filterExpression = new Expression();
|
||||
if ("booleanMatch".equals(expression.getExpressionType())) {
|
||||
filterExpression.setExpressionObject("EqualMatch");
|
||||
filterExpression.setLeft("source." + ClassMethodUtil.toIsMethod(expression.getAttribute()) + "()");
|
||||
|
|
@ -99,39 +99,55 @@ public class DeepAnalysis {
|
|||
|
||||
// 4. Use parameter's annotation of entrance method to generate aggregation entrance.
|
||||
for (Parameter parameter : entranceMethod.getParameters()) {
|
||||
Class<?> parameterType = parameter.getType();
|
||||
Annotation[] parameterAnnotations = parameter.getAnnotations();
|
||||
if (parameterAnnotations == null || parameterAnnotations.length == 0) {
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " doesn't include the annotation.");
|
||||
}
|
||||
Annotation annotation = parameterAnnotations[0];
|
||||
if (annotation instanceof SourceFrom) {
|
||||
entryMethod.addArg("source." + ClassMethodUtil.toGetMethod(result.getSourceAttribute()) + "()");
|
||||
entryMethod.addArg(parameterType, "source." + ClassMethodUtil.toGetMethod(result.getSourceAttribute()) + "()");
|
||||
} else if (annotation instanceof ConstOne) {
|
||||
entryMethod.addArg("1");
|
||||
} else if (annotation instanceof Expression) {
|
||||
entryMethod.addArg("new " + parameter.getType().getName() + "()");
|
||||
} else if (annotation instanceof ExpressionArg0) {
|
||||
entryMethod.addArg(parameterType, "1");
|
||||
} else if (annotation instanceof org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Expression) {
|
||||
if (result.getFuncConditionExpressions().size() == 1) {
|
||||
ConditionExpression conditionExpression = result.getFuncConditionExpressions().get(0);
|
||||
if ("booleanMatch".equals(conditionExpression.getExpressionType())) {
|
||||
entryMethod.addArg("source." + ClassMethodUtil.toIsMethod(conditionExpression.getAttribute()) + "()");
|
||||
} else if ("stringMatch".equals(conditionExpression.getExpressionType())) {
|
||||
entryMethod.addArg("source." + ClassMethodUtil.toGetMethod(conditionExpression.getAttribute()) + "()");
|
||||
ConditionExpression expression = result.getFuncConditionExpressions().get(0);
|
||||
|
||||
Expression argExpression = new Expression();
|
||||
if ("booleanMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("EqualMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toIsMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else if ("stringMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("EqualMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else if ("greaterMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("GreaterMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else if ("lessMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("LessMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else if ("greaterEqualMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("GreaterEqualMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else if ("lessEqualMatch".equals(expression.getExpressionType())) {
|
||||
argExpression.setExpressionObject("LessEqualMatch");
|
||||
argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
|
||||
argExpression.setRight(expression.getValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " argument has @ExpressionArg0, but expression type is not supported");
|
||||
throw new IllegalArgumentException("filter expression [" + expression.getExpressionType() + "] not found");
|
||||
}
|
||||
|
||||
entryMethod.addArg(argExpression);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " argument has @ExpressionArg0, but can't find funcParamExpression.");
|
||||
}
|
||||
} else if (annotation instanceof ExpressionArg1) {
|
||||
if (result.getFuncConditionExpressions().size() == 1) {
|
||||
ConditionExpression conditionExpression = result.getFuncConditionExpressions().get(0);
|
||||
entryMethod.addArg(conditionExpression.getValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " argument has @ExpressionArg0, but can't find funcParamExpression.");
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " argument can't find funcParamExpression.");
|
||||
}
|
||||
} else if (annotation instanceof Arg) {
|
||||
entryMethod.addArg(result.getNextFuncArg());
|
||||
entryMethod.addArg(parameterType, result.getNextFuncArg());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Entrance method:" + entranceMethod + " doesn't the expected annotation.");
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.Getter;
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
|
|
@ -24,14 +24,29 @@ import lombok.*;
|
|||
@Getter(AccessLevel.PUBLIC)
|
||||
@Setter(AccessLevel.PUBLIC)
|
||||
public class EntryMethod {
|
||||
private static final int LITERAL_TYPE = 1;
|
||||
private static final int EXPRESSION_TYPE = 2;
|
||||
|
||||
private String methodName;
|
||||
private List<Integer> argTypes = new ArrayList<>();
|
||||
private List<Object> argsExpressions = new ArrayList<>();
|
||||
|
||||
private List<String> argsExpressions;
|
||||
|
||||
public void addArg(String expression) {
|
||||
if (argsExpressions == null) {
|
||||
argsExpressions = new LinkedList<>();
|
||||
public void addArg(Class<?> parameterType, String expression) {
|
||||
if (parameterType.equals(int.class)) {
|
||||
expression = "(int)(" + expression + ")";
|
||||
} else if (parameterType.equals(long.class)) {
|
||||
expression = "(long)(" + expression + ")";
|
||||
} else if (parameterType.equals(double.class)) {
|
||||
expression = "(double)(" + expression + ")";
|
||||
} else if (parameterType.equals(float.class)) {
|
||||
expression = "(float)(" + expression + ")";
|
||||
}
|
||||
argTypes.add(LITERAL_TYPE);
|
||||
argsExpressions.add(expression);
|
||||
}
|
||||
|
||||
public void addArg(Expression expression) {
|
||||
argTypes.add(EXPRESSION_TYPE);
|
||||
argsExpressions.add(expression);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,14 +16,24 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
@Setter(AccessLevel.PUBLIC)
|
||||
public class FilterExpression {
|
||||
public class Expression {
|
||||
private String expressionObject;
|
||||
private String left;
|
||||
private String right;
|
||||
|
||||
public void setLeft(String left) {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public void setRight(String right) {
|
||||
this.right = right;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.List;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.apache.skywalking.oal.tool.grammar.*;
|
||||
import org.apache.skywalking.oal.rt.grammar.*;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
|
||||
public class OALListener extends OALParserBaseListener {
|
||||
|
|
@ -120,19 +120,27 @@ public class OALListener extends OALParserBaseListener {
|
|||
}
|
||||
|
||||
@Override public void enterBooleanConditionValue(OALParser.BooleanConditionValueContext ctx) {
|
||||
conditionExpression.setValue(ctx.getText());
|
||||
enterConditionValue(ctx.getText());
|
||||
}
|
||||
|
||||
@Override public void enterStringConditionValue(OALParser.StringConditionValueContext ctx) {
|
||||
conditionExpression.setValue(ctx.getText());
|
||||
enterConditionValue(ctx.getText());
|
||||
}
|
||||
|
||||
@Override public void enterEnumConditionValue(OALParser.EnumConditionValueContext ctx) {
|
||||
conditionExpression.setValue(ctx.getText());
|
||||
enterConditionValue(ctx.getText());
|
||||
}
|
||||
|
||||
@Override public void enterNumberConditionValue(OALParser.NumberConditionValueContext ctx) {
|
||||
conditionExpression.setValue(ctx.getText());
|
||||
enterConditionValue(ctx.getText());
|
||||
}
|
||||
|
||||
private void enterConditionValue(String value) {
|
||||
if (value.split("\\.").length == 2 && !value.startsWith("\"")) {
|
||||
// Value is an enum.
|
||||
value = "org.apache.skywalking.oap.server.core.source." + value;
|
||||
}
|
||||
conditionExpression.setValue(value);
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
|
||||
import org.apache.skywalking.oal.rt.util.ClassMethodUtil;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
@Setter(AccessLevel.PUBLIC)
|
||||
|
|
@ -16,14 +16,19 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.io.Reader;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import org.apache.skywalking.oal.tool.grammar.*;
|
||||
import org.apache.skywalking.oal.rt.grammar.*;
|
||||
|
||||
/**
|
||||
* Script reader and parser.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class ScriptParser {
|
||||
private OALLexer lexer;
|
||||
|
||||
|
|
@ -31,9 +36,9 @@ public class ScriptParser {
|
|||
|
||||
}
|
||||
|
||||
public static ScriptParser createFromFile(String scriptFilepath) throws IOException {
|
||||
public static ScriptParser createFromFile(Reader scriptReader) throws IOException {
|
||||
ScriptParser parser = new ScriptParser();
|
||||
parser.lexer = new OALLexer(CharStreams.fromFileName(scriptFilepath));
|
||||
parser.lexer = new OALLexer(CharStreams.fromReader(scriptReader));
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.Objects;
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
|
||||
import org.apache.skywalking.oal.rt.util.ClassMethodUtil;
|
||||
|
||||
@Getter(AccessLevel.PUBLIC)
|
||||
@Setter(AccessLevel.PUBLIC)
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.util.*;
|
||||
import org.apache.skywalking.oal.tool.meta.*;
|
||||
import org.apache.skywalking.oal.rt.meta.*;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.util;
|
||||
package org.apache.skywalking.oal.rt.util;
|
||||
|
||||
public class ClassMethodUtil {
|
||||
public static String toGetMethod(String attribute) {
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
public void dispatch(org.apache.skywalking.oap.server.core.source.Source source) {
|
||||
org.apache.skywalking.oap.server.core.source.${source} _source = (org.apache.skywalking.oap.server.core.source.${source})source;
|
||||
<#list metrics as metrics>
|
||||
do${metrics.metricsName}(_source);
|
||||
</#list>
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
private void do${metricsName}(org.apache.skywalking.oap.server.core.source.${sourceName} source) {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = new org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics();
|
||||
|
||||
<#if filterExpressions??>
|
||||
<#list filterExpressions as filterExpression>
|
||||
if (!new org.apache.skywalking.oap.server.core.analysis.metrics.expression.${filterExpression.expressionObject}().match(${filterExpression.left}, ${filterExpression.right})) {
|
||||
return;
|
||||
}
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
metrics.setTimeBucket(source.getTimeBucket());
|
||||
<#list fieldsFromSource as field>
|
||||
metrics.${field.fieldSetter}(source.${field.fieldGetter}());
|
||||
</#list>
|
||||
metrics.${entryMethod.methodName}(
|
||||
<#list entryMethod.argsExpressions as arg>
|
||||
<#if entryMethod.argTypes[arg_index] == 1>
|
||||
${arg}
|
||||
<#else>
|
||||
new org.apache.skywalking.oap.server.core.analysis.metrics.expression.${arg.expressionObject}().match(${arg.left}, ${arg.right})
|
||||
</#if><#if arg_has_next>, </#if>
|
||||
</#list>);
|
||||
|
||||
org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor.getInstance().in(metrics);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
public java.util.Map data2Map(org.apache.skywalking.oap.server.core.storage.StorageData input) {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics storageData = (org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics)input;
|
||||
java.util.Map map = new java.util.HashMap();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.typeName == "long">
|
||||
map.put((Object)"${field.columnName}", new Long(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "int">
|
||||
map.put((Object)"${field.columnName}", new Integer(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "double">
|
||||
map.put((Object)"${field.columnName}", new Double(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "float">
|
||||
map.put((Object)"${field.columnName}", new Float(storageData.${field.fieldGetter}()));
|
||||
<#else>
|
||||
map.put((Object)"${field.columnName}", storageData.${field.fieldGetter}());
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.typeName == "long">
|
||||
map.put((Object)"${field.columnName}", new Long(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "int">
|
||||
map.put((Object)"${field.columnName}", new Integer(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "double">
|
||||
map.put((Object)"${field.columnName}", new Double(storageData.${field.fieldGetter}()));
|
||||
<#elseif field.typeName == "float">
|
||||
map.put((Object)"${field.columnName}", new Float(storageData.${field.fieldGetter}()));
|
||||
<#else>
|
||||
map.put((Object)"${field.columnName}", storageData.${field.fieldGetter}());
|
||||
</#if>
|
||||
</#list>
|
||||
return map;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
public org.apache.skywalking.oap.server.core.storage.StorageData map2Data(java.util.Map dbMap) {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = new org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(((Number)dbMap.get("${field.columnName}")).${field.typeName}Value());
|
||||
<#elseif field.typeName == "java.lang.String">
|
||||
metrics.${field.fieldSetter}((String)dbMap.get("${field.columnName}"));
|
||||
<#else>
|
||||
metrics.${field.fieldSetter}(new ${field.typeName}((String)dbMap.get("${field.columnName}")));
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(((Number)dbMap.get("${field.columnName}")).${field.typeName}Value());
|
||||
<#elseif field.typeName == "java.lang.String">
|
||||
metrics.${field.fieldSetter}((String)dbMap.get("${field.columnName}"));
|
||||
<#else>
|
||||
metrics.${field.fieldSetter}(new ${field.typeName}((String)dbMap.get("${field.columnName}")));
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
public void deserialize(org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData remoteData) {
|
||||
<#list serializeFields.stringFields as field>
|
||||
${field.setter}(remoteData.getDataStrings(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.longFields as field>
|
||||
${field.setter}(remoteData.getDataLongs(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.doubleFields as field>
|
||||
${field.setter}(remoteData.getDataDoubles(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intFields as field>
|
||||
${field.setter}(remoteData.getDataIntegers(${field?index}));
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intLongValuePairListFields as field>
|
||||
setDetailGroup(new org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueArray(30));
|
||||
|
||||
java.util.Iterator iterator = remoteData.getDataIntLongPairListList().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
org.apache.skywalking.oap.server.core.remote.grpc.proto.IntKeyLongValuePair element = (org.apache.skywalking.oap.server.core.remote.grpc.proto.IntKeyLongValuePair)(iterator.next());
|
||||
super.getDetailGroup().add(new org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue(element.getKey(), element.getValue()));
|
||||
}
|
||||
</#list>
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = (org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics)obj;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
if (!${sourceField.fieldName}.equals(metrics.${sourceField.fieldName}))
|
||||
<#else>
|
||||
if (${sourceField.fieldName} != metrics.${sourceField.fieldName})
|
||||
</#if>
|
||||
return false;
|
||||
</#if>
|
||||
</#list>
|
||||
|
||||
if (getTimeBucket() != metrics.getTimeBucket())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
public org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo getMeta() {
|
||||
return new org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo("${varName}", ${sourceScopeId}<#if (fieldsFromSource?size>0) ><#list fieldsFromSource as field><#if field.isID()>, ${field.fieldName}</#if></#list></#if>);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
public int hashCode() {
|
||||
int result = 17;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
result = 31 * result + ${sourceField.fieldName}.hashCode();
|
||||
<#else>
|
||||
result += Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
result = 31 * result + (int)getTimeBucket();
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
public String id() {
|
||||
String splitJointId = String.valueOf(getTimeBucket());
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
splitJointId += org.apache.skywalking.oap.server.core.Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
<#else>
|
||||
splitJointId += org.apache.skywalking.oap.server.core.Const.ID_SPLIT + String.valueOf(${sourceField.fieldName});
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
return splitJointId;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
public int remoteHashCode() {
|
||||
int result = 17;
|
||||
<#list fieldsFromSource as sourceField>
|
||||
<#if sourceField.isID()>
|
||||
<#if sourceField.getTypeName() == "java.lang.String">
|
||||
result = 31 * result + ${sourceField.fieldName}.hashCode();
|
||||
<#else>
|
||||
result += org.apache.skywalking.oap.server.core.Const.ID_SPLIT + ${sourceField.fieldName};
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
public org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData.Builder serialize() {
|
||||
org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData.Builder remoteBuilder = org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData.newBuilder();
|
||||
<#list serializeFields.stringFields as field>
|
||||
remoteBuilder.addDataStrings(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.longFields as field>
|
||||
remoteBuilder.addDataLongs(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.doubleFields as field>
|
||||
remoteBuilder.addDataDoubles(${field.getter}());
|
||||
</#list>
|
||||
|
||||
<#list serializeFields.intFields as field>
|
||||
remoteBuilder.addDataIntegers(${field.getter}());
|
||||
</#list>
|
||||
<#list serializeFields.intLongValuePairListFields as field>
|
||||
java.util.Iterator iterator = super.getDetailGroup().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
remoteBuilder.addDataIntLongPairList(((org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue)(iterator.next())).serialize());
|
||||
}
|
||||
</#list>
|
||||
|
||||
return remoteBuilder;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
public org.apache.skywalking.oap.server.core.analysis.metrics.Metrics toDay() {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = new org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInDay());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInDay());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
public org.apache.skywalking.oap.server.core.analysis.metrics.Metrics toHour() {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = new org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInHour());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInHour());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
public org.apache.skywalking.oap.server.core.analysis.metrics.Metrics toMonth() {
|
||||
org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics metrics = new org.apache.skywalking.oal.rt.metrics.${metricsName}Metrics();
|
||||
<#list fieldsFromSource as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInMonth());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
<#list persistentFields as field>
|
||||
<#if field.columnName == "time_bucket">
|
||||
metrics.setTimeBucket(toTimeBucketInMonth());
|
||||
<#elseif field.typeName == "java.lang.String" || field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
|
||||
metrics.${field.fieldSetter}(this.${field.fieldGetter}());
|
||||
<#else>
|
||||
${field.typeName} newValue = new ${field.typeName}();
|
||||
newValue.copyFrom(this.${field.fieldGetter}());
|
||||
metrics.${field.fieldSetter}(newValue);
|
||||
</#if>
|
||||
</#list>
|
||||
return metrics;
|
||||
}
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.meta;
|
||||
package org.apache.skywalking.oal.rt.meta;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oal.tool.parser.SourceColumn;
|
||||
import org.apache.skywalking.oal.rt.parser.SourceColumn;
|
||||
import org.junit.*;
|
||||
|
||||
public class MetaReaderTest {
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.meta;
|
||||
package org.apache.skywalking.oal.rt.meta;
|
||||
|
||||
import java.util.*;
|
||||
import org.apache.skywalking.oal.tool.parser.SourceColumn;
|
||||
import org.apache.skywalking.oal.rt.parser.SourceColumn;
|
||||
|
||||
public class MockSourceColumnsFactory {
|
||||
public static List<SourceColumn> getColumns(String source) {
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oal.tool.meta.*;
|
||||
import org.apache.skywalking.oal.rt.meta.*;
|
||||
import org.junit.*;
|
||||
|
||||
public class DeepAnalysisTest {
|
||||
|
|
@ -47,8 +47,8 @@ public class DeepAnalysisTest {
|
|||
|
||||
EntryMethod method = result.getEntryMethod();
|
||||
Assert.assertEquals("combine", method.getMethodName());
|
||||
Assert.assertEquals("source.getLatency()", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("1", method.getArgsExpressions().get(1));
|
||||
Assert.assertEquals("(long)(source.getLatency())", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("(long)(1)", method.getArgsExpressions().get(1));
|
||||
|
||||
List<SourceColumn> source = result.getFieldsFromSource();
|
||||
Assert.assertEquals(1, source.size());
|
||||
|
|
@ -71,8 +71,8 @@ public class DeepAnalysisTest {
|
|||
|
||||
EntryMethod method = result.getEntryMethod();
|
||||
Assert.assertEquals("combine", method.getMethodName());
|
||||
Assert.assertEquals("source.getLatency()", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("1", method.getArgsExpressions().get(1));
|
||||
Assert.assertEquals("(long)(source.getLatency())", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("(long)(1)", method.getArgsExpressions().get(1));
|
||||
|
||||
List<SourceColumn> source = result.getFieldsFromSource();
|
||||
Assert.assertEquals(3, source.size());
|
||||
|
|
@ -100,8 +100,8 @@ public class DeepAnalysisTest {
|
|||
|
||||
EntryMethod method = result.getEntryMethod();
|
||||
Assert.assertEquals("combine", method.getMethodName());
|
||||
Assert.assertEquals("source.getLatency()", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("1", method.getArgsExpressions().get(1));
|
||||
Assert.assertEquals("(long)(source.getLatency())", method.getArgsExpressions().get(0));
|
||||
Assert.assertEquals("(long)(1)", method.getArgsExpressions().get(1));
|
||||
|
||||
List<SourceColumn> source = result.getFieldsFromSource();
|
||||
Assert.assertEquals(3, source.size());
|
||||
|
|
@ -109,9 +109,9 @@ public class DeepAnalysisTest {
|
|||
List<DataColumn> persistentFields = result.getPersistentFields();
|
||||
Assert.assertEquals(4, persistentFields.size());
|
||||
|
||||
List<FilterExpression> filterExpressions = result.getFilterExpressions();
|
||||
List<Expression> filterExpressions = result.getFilterExpressions();
|
||||
Assert.assertEquals(1, filterExpressions.size());
|
||||
FilterExpression filterExpression = filterExpressions.get(0);
|
||||
Expression filterExpression = filterExpressions.get(0);
|
||||
Assert.assertEquals("EqualMatch", filterExpression.getExpressionObject());
|
||||
Assert.assertEquals("source.getName()", filterExpression.getLeft());
|
||||
Assert.assertEquals("\"/service/prod/save\"", filterExpression.getRight());
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.parser;
|
||||
package org.apache.skywalking.oal.rt.parser;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oal.tool.meta.*;
|
||||
import org.apache.skywalking.oal.rt.meta.*;
|
||||
import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
import org.junit.*;
|
||||
|
|
@ -36,7 +36,7 @@ public class ScriptParserTest {
|
|||
|
||||
AnnotationScan scopeScan = new AnnotationScan();
|
||||
scopeScan.registerListener(new DefaultScopeDefine.Listener());
|
||||
scopeScan.scan(null);
|
||||
scopeScan.scan();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
@ -80,10 +80,8 @@ public class ScriptParserTest {
|
|||
Assert.assertEquals("*", endpointPercent.getSourceAttribute());
|
||||
Assert.assertEquals("percent", endpointPercent.getAggregationFunctionName());
|
||||
EntryMethod entryMethod = endpointPercent.getEntryMethod();
|
||||
List<String> methodArgsExpressions = entryMethod.getArgsExpressions();
|
||||
Assert.assertEquals(3, methodArgsExpressions.size());
|
||||
Assert.assertEquals("source.isStatus()", methodArgsExpressions.get(1));
|
||||
Assert.assertEquals("true", methodArgsExpressions.get(2));
|
||||
List<Object> methodArgsExpressions = entryMethod.getArgsExpressions();
|
||||
Assert.assertEquals(1, methodArgsExpressions.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -37,10 +37,9 @@
|
|||
<module>server-query-plugin</module>
|
||||
<module>server-alarm-plugin</module>
|
||||
<module>server-testing</module>
|
||||
<module>generated-analysis</module>
|
||||
<module>generate-tool</module>
|
||||
<module>oal-rt</module>
|
||||
<module>server-telemetry</module>
|
||||
<module>generate-tool-grammar</module>
|
||||
<module>oal-grammar</module>
|
||||
<module>exporter</module>
|
||||
<module>server-configuration</module>
|
||||
</modules>
|
||||
|
|
@ -83,6 +82,9 @@
|
|||
<curator-test.version>2.12.0</curator-test.version>
|
||||
<etcd4j.version>2.17.0</etcd4j.version>
|
||||
<etcd.version>v3.2.3</etcd.version>
|
||||
<antlr.version>4.7.1</antlr.version>
|
||||
<freemarker.version>2.3.28</freemarker.version>
|
||||
<javaassist.version>3.25.0-GA</javaassist.version>
|
||||
<zookeeper.image.version>3.5</zookeeper.image.version>
|
||||
</properties>
|
||||
|
||||
|
|
@ -408,6 +410,22 @@
|
|||
</exclusions>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>${antlr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>${freemarker.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>${javaassist.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
|
|||
import org.apache.skywalking.oap.server.core.cache.*;
|
||||
import org.apache.skywalking.oap.server.core.cluster.*;
|
||||
import org.apache.skywalking.oap.server.core.config.*;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngine;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoader;
|
||||
import org.apache.skywalking.oap.server.core.query.*;
|
||||
import org.apache.skywalking.oap.server.core.register.service.*;
|
||||
import org.apache.skywalking.oap.server.core.remote.*;
|
||||
|
|
@ -56,6 +58,8 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
private final StorageModels storageModels;
|
||||
private final StreamDataMapping streamDataMapping;
|
||||
private final SourceReceiverImpl receiver;
|
||||
private StreamAnnotationListener streamAnnotationListener;
|
||||
private OALEngine oalEngine;
|
||||
|
||||
public CoreModuleProvider() {
|
||||
super();
|
||||
|
|
@ -79,12 +83,26 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
}
|
||||
|
||||
@Override public void prepare() throws ServiceNotProvidedException, ModuleStartException {
|
||||
streamAnnotationListener = new StreamAnnotationListener(getManager());
|
||||
|
||||
AnnotationScan scopeScan = new AnnotationScan();
|
||||
scopeScan.registerListener(new DefaultScopeDefine.Listener());
|
||||
scopeScan.registerListener(DisableRegister.INSTANCE);
|
||||
scopeScan.registerListener(new DisableRegister.SingleDisableScanListener());
|
||||
try {
|
||||
scopeScan.scan(null);
|
||||
scopeScan.scan();
|
||||
|
||||
oalEngine = OALEngineLoader.get();
|
||||
oalEngine.setStreamListener(streamAnnotationListener);
|
||||
oalEngine.setDispatcherListener(receiver.getDispatcherManager());
|
||||
oalEngine.start(getClass().getClassLoader());
|
||||
} catch (Exception e) {
|
||||
throw new ModuleStartException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
AnnotationScan oalDisable = new AnnotationScan();
|
||||
oalDisable.registerListener(DisableRegister.INSTANCE);
|
||||
oalDisable.registerListener(new DisableRegister.SingleDisableScanListener());
|
||||
try {
|
||||
oalDisable.scan();
|
||||
} catch (IOException e) {
|
||||
throw new ModuleStartException(e.getMessage(), e);
|
||||
}
|
||||
|
|
@ -144,7 +162,7 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(AlarmQueryService.class, new AlarmQueryService(getManager()));
|
||||
this.registerServiceImplementation(TopNRecordsQueryService.class, new TopNRecordsQueryService(getManager()));
|
||||
|
||||
annotationScan.registerListener(new StreamAnnotationListener(getManager()));
|
||||
annotationScan.registerListener(streamAnnotationListener);
|
||||
|
||||
this.remoteClientManager = new RemoteClientManager(getManager());
|
||||
this.registerServiceImplementation(RemoteClientManager.class, remoteClientManager);
|
||||
|
|
@ -157,9 +175,10 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
|
||||
try {
|
||||
receiver.scan();
|
||||
annotationScan.scan();
|
||||
|
||||
oalEngine.notifyAllListeners();
|
||||
|
||||
annotationScan.scan(() -> {
|
||||
});
|
||||
streamDataMapping.init();
|
||||
} catch (IOException | IllegalAccessException | InstantiationException e) {
|
||||
throw new ModuleStartException(e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Locate the base work path of OAP backend.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class WorkPath {
|
||||
private static final Logger logger = LoggerFactory.getLogger(WorkPath.class);
|
||||
|
||||
private static File PATH;
|
||||
|
||||
public static File getPath() {
|
||||
if (PATH == null) {
|
||||
PATH = findPath();
|
||||
}
|
||||
return PATH;
|
||||
}
|
||||
|
||||
private static File findPath() {
|
||||
String classResourcePath = WorkPath.class.getName().replaceAll("\\.", "/") + ".class";
|
||||
|
||||
URL resource = ClassLoader.getSystemClassLoader().getResource(classResourcePath);
|
||||
if (resource != null) {
|
||||
String urlString = resource.toString();
|
||||
|
||||
logger.debug("The beacon class location is {}.", urlString);
|
||||
|
||||
int insidePathIndex = urlString.indexOf('!');
|
||||
boolean isInJar = insidePathIndex > -1;
|
||||
|
||||
if (isInJar) {
|
||||
urlString = urlString.substring(urlString.indexOf("file:"), insidePathIndex);
|
||||
File agentJarFile = null;
|
||||
try {
|
||||
agentJarFile = new File(new URL(urlString).toURI());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new UnexpectedException("Can not locate oap core jar file by url:" + urlString, e);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new UnexpectedException("Can not locate oap core jar file by url:" + urlString, e);
|
||||
}
|
||||
if (agentJarFile.exists()) {
|
||||
return agentJarFile.getParentFile();
|
||||
}
|
||||
} else {
|
||||
int prefixLength = "file:".length();
|
||||
String classLocation = urlString.substring(prefixLength, urlString.length() - classResourcePath.length());
|
||||
return new File(classLocation);
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnexpectedException("Can not locate oap core jar file by path:" + classResourcePath);
|
||||
}
|
||||
}
|
||||
|
|
@ -43,11 +43,15 @@ public class DisableRegister implements AnnotationListener {
|
|||
Disable[] valueList = annotation.value();
|
||||
if (valueList != null) {
|
||||
for (Disable disable : valueList) {
|
||||
disableEntitySet.add(disable.value());
|
||||
add(disable.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(String name) {
|
||||
disableEntitySet.add(name);
|
||||
}
|
||||
|
||||
public boolean include(String name) {
|
||||
return disableEntitySet.contains(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oal.tool.output;
|
||||
package org.apache.skywalking.oap.server.core.analysis;
|
||||
|
||||
import freemarker.template.TemplateException;
|
||||
import java.io.*;
|
||||
|
||||
public interface WriteWrapper {
|
||||
void execute(FileWriter fileWriter) throws IOException, TemplateException;
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
public interface DispatcherDetectorListener {
|
||||
void addIfAsSourceDispatcher(Class aClass) throws IllegalAccessException, InstantiationException;
|
||||
}
|
||||
|
|
@ -21,16 +21,21 @@ package org.apache.skywalking.oap.server.core.analysis;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.skywalking.oap.server.core.UnexpectedException;
|
||||
import org.apache.skywalking.oap.server.core.source.Source;
|
||||
import org.slf4j.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng, wusheng
|
||||
*/
|
||||
public class DispatcherManager {
|
||||
public class DispatcherManager implements DispatcherDetectorListener {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DispatcherManager.class);
|
||||
|
||||
|
|
@ -75,39 +80,44 @@ public class DispatcherManager {
|
|||
for (ClassPath.ClassInfo classInfo : classes) {
|
||||
Class<?> aClass = classInfo.load();
|
||||
|
||||
if (!aClass.isInterface() && SourceDispatcher.class.isAssignableFrom(aClass)) {
|
||||
Type[] genericInterfaces = aClass.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
ParameterizedType anInterface = (ParameterizedType)genericInterface;
|
||||
if (anInterface.getRawType().getTypeName().equals(SourceDispatcher.class.getName())) {
|
||||
Type[] arguments = anInterface.getActualTypeArguments();
|
||||
addIfAsSourceDispatcher(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.length != 1) {
|
||||
throw new UnexpectedException("unexpected type argument number, class " + aClass.getName());
|
||||
}
|
||||
Type argument = arguments[0];
|
||||
@Override
|
||||
public void addIfAsSourceDispatcher(Class aClass) throws IllegalAccessException, InstantiationException {
|
||||
if (!aClass.isInterface() && SourceDispatcher.class.isAssignableFrom(aClass)) {
|
||||
Type[] genericInterfaces = aClass.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
ParameterizedType anInterface = (ParameterizedType)genericInterface;
|
||||
if (anInterface.getRawType().getTypeName().equals(SourceDispatcher.class.getName())) {
|
||||
Type[] arguments = anInterface.getActualTypeArguments();
|
||||
|
||||
Object source = ((Class)argument).newInstance();
|
||||
|
||||
if (!Source.class.isAssignableFrom(source.getClass())) {
|
||||
throw new UnexpectedException("unexpected type argument of class " + aClass.getName() + ", should be `org.apache.skywalking.oap.server.core.source.Source`. ");
|
||||
}
|
||||
|
||||
Source dispatcherSource = (Source)source;
|
||||
SourceDispatcher dispatcher = (SourceDispatcher)aClass.newInstance();
|
||||
|
||||
int scopeId = dispatcherSource.scope();
|
||||
|
||||
List<SourceDispatcher> dispatchers = this.dispatcherMap.get(scopeId);
|
||||
if (dispatchers == null) {
|
||||
dispatchers = new ArrayList<>();
|
||||
this.dispatcherMap.put(scopeId, dispatchers);
|
||||
}
|
||||
|
||||
dispatchers.add(dispatcher);
|
||||
|
||||
logger.info("Dispatcher {} is added into DefaultScopeDefine {}.", dispatcher.getClass().getName(), scopeId);
|
||||
if (arguments.length != 1) {
|
||||
throw new UnexpectedException("unexpected type argument number, class " + aClass.getName());
|
||||
}
|
||||
Type argument = arguments[0];
|
||||
|
||||
Object source = ((Class)argument).newInstance();
|
||||
|
||||
if (!Source.class.isAssignableFrom(source.getClass())) {
|
||||
throw new UnexpectedException("unexpected type argument of class " + aClass.getName() + ", should be `org.apache.skywalking.oap.server.core.source.Source`. ");
|
||||
}
|
||||
|
||||
Source dispatcherSource = (Source)source;
|
||||
SourceDispatcher dispatcher = (SourceDispatcher)aClass.newInstance();
|
||||
|
||||
int scopeId = dispatcherSource.scope();
|
||||
|
||||
List<SourceDispatcher> dispatchers = this.dispatcherMap.get(scopeId);
|
||||
if (dispatchers == null) {
|
||||
dispatchers = new ArrayList<>();
|
||||
this.dispatcherMap.put(scopeId, dispatchers);
|
||||
}
|
||||
|
||||
dispatchers.add(dispatcher);
|
||||
|
||||
logger.info("Dispatcher {} is added into DefaultScopeDefine {}.", dispatcher.getClass().getName(), scopeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ public abstract class DoubleAvgMetrics extends Metrics implements DoubleValueHol
|
|||
protected static final String VALUE = "value";
|
||||
|
||||
@Getter @Setter @Column(columnName = SUMMATION) private double summation;
|
||||
@Getter @Setter @Column(columnName = COUNT) private int count;
|
||||
@Getter @Setter @Column(columnName = COUNT) private long count;
|
||||
@Getter @Setter @Column(columnName = VALUE, isValue = true, function = Function.Avg) private double value;
|
||||
|
||||
@Entrance
|
||||
public final void combine(@SourceFrom double summation, @ConstOne int count) {
|
||||
public final void combine(@SourceFrom double summation, @ConstOne long count) {
|
||||
this.summation += summation;
|
||||
this.count += count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ public abstract class LongAvgMetrics extends Metrics implements LongValueHolder
|
|||
protected static final String VALUE = "value";
|
||||
|
||||
@Getter @Setter @Column(columnName = SUMMATION) private long summation;
|
||||
@Getter @Setter @Column(columnName = COUNT) private int count;
|
||||
@Getter @Setter @Column(columnName = COUNT) private long count;
|
||||
@Getter @Setter @Column(columnName = VALUE, isValue = true, function = Function.Avg) private long value;
|
||||
|
||||
@Entrance
|
||||
public final void combine(@SourceFrom long summation, @ConstOne int count) {
|
||||
public final void combine(@SourceFrom long summation, @ConstOne long count) {
|
||||
this.summation += summation;
|
||||
this.count += count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@
|
|||
|
||||
package org.apache.skywalking.oap.server.core.analysis.metrics;
|
||||
|
||||
import lombok.*;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.*;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.expression.EqualMatch;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Entrance;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Expression;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.MetricsFunction;
|
||||
import org.apache.skywalking.oap.server.core.query.sql.Function;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
|
||||
|
|
@ -38,11 +40,8 @@ public abstract class PercentMetrics extends Metrics implements IntValueHolder {
|
|||
@Getter @Setter @Column(columnName = MATCH) private long match;
|
||||
|
||||
@Entrance
|
||||
public final void combine(@Expression EqualMatch expression, @ExpressionArg0 Object leftValue,
|
||||
@ExpressionArg1 Object rightValue) {
|
||||
expression.setLeft(leftValue);
|
||||
expression.setRight(rightValue);
|
||||
if (expression.match()) {
|
||||
public final void combine(@Expression boolean isMatch) {
|
||||
if (isMatch) {
|
||||
match++;
|
||||
}
|
||||
total++;
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.metrics.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExpressionArg1 {
|
||||
}
|
||||
|
|
@ -19,12 +19,50 @@
|
|||
package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class EqualMatch extends BinaryMatchExpression {
|
||||
@Override public boolean match() {
|
||||
public class EqualMatch {
|
||||
public boolean match(int left, int right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(long left, long right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(float left, float right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(double left, double right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Integer left, Integer right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Long left, Long right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Float left, Float right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Double left, Double right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Boolean left, Boolean right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(boolean left, boolean right) {
|
||||
return left == right;
|
||||
}
|
||||
|
||||
public boolean match(Object left, Object right) {
|
||||
return left.equals(right);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
|||
* @author peng-yongsheng
|
||||
*/
|
||||
public class GreaterEqualMatch {
|
||||
public boolean match(int left, int right) {
|
||||
return left >= right;
|
||||
}
|
||||
|
||||
public boolean match(long left, long right) {
|
||||
return left >= right;
|
||||
}
|
||||
|
||||
public boolean match(float left, float right) {
|
||||
return left >= right;
|
||||
}
|
||||
|
||||
public boolean match(double left, double right) {
|
||||
return left >= right;
|
||||
}
|
||||
|
||||
public boolean match(Integer left, Integer right) {
|
||||
return left >= right;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
|||
* @author peng-yongsheng
|
||||
*/
|
||||
public class GreaterMatch {
|
||||
public boolean match(int left, int right) {
|
||||
return left > right;
|
||||
}
|
||||
|
||||
public boolean match(long left, long right) {
|
||||
return left > right;
|
||||
}
|
||||
|
||||
public boolean match(float left, float right) {
|
||||
return left > right;
|
||||
}
|
||||
|
||||
public boolean match(double left, double right) {
|
||||
return left > right;
|
||||
}
|
||||
|
||||
public boolean match(Integer left, Integer right) {
|
||||
return left > right;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
|||
* @author peng-yongsheng
|
||||
*/
|
||||
public class LessEqualMatch {
|
||||
public boolean match(int left, int right) {
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
public boolean match(long left, long right) {
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
public boolean match(float left, float right) {
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
public boolean match(double left, double right) {
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
public boolean match(Integer left, Integer right) {
|
||||
return left <= right;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,21 @@ package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
|||
* @author peng-yongsheng
|
||||
*/
|
||||
public class LessMatch {
|
||||
public boolean match(int left, int right) {
|
||||
return left < right;
|
||||
}
|
||||
|
||||
public boolean match(long left, long right) {
|
||||
return left < right;
|
||||
}
|
||||
|
||||
public boolean match(float left, float right) {
|
||||
return left < right;
|
||||
}
|
||||
|
||||
public boolean match(double left, double right) {
|
||||
return left < right;
|
||||
}
|
||||
|
||||
public boolean match(Integer left, Integer right) {
|
||||
return left < right;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ import java.lang.annotation.Annotation;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng
|
||||
* Scan the annotation, and notify the listener(s)
|
||||
*
|
||||
* @author peng-yongsheng, wusheng
|
||||
*/
|
||||
public class AnnotationScan {
|
||||
|
||||
|
|
@ -35,11 +37,20 @@ public class AnnotationScan {
|
|||
this.listeners = new LinkedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the callback listener
|
||||
* @param listener to be called after class found w/ annotation
|
||||
*/
|
||||
public void registerListener(AnnotationListener listener) {
|
||||
listeners.add(new AnnotationListenerCache(listener));
|
||||
}
|
||||
|
||||
public void scan(Runnable callBack) throws IOException {
|
||||
/**
|
||||
* Begin to scan classes.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void scan() throws IOException {
|
||||
ClassPath classpath = ClassPath.from(this.getClass().getClassLoader());
|
||||
ImmutableSet<ClassPath.ClassInfo> classes = classpath.getTopLevelClassesRecursive("org.apache.skywalking");
|
||||
for (ClassPath.ClassInfo classInfo : classes) {
|
||||
|
|
@ -53,10 +64,6 @@ public class AnnotationScan {
|
|||
}
|
||||
|
||||
listeners.forEach(AnnotationListenerCache::complete);
|
||||
|
||||
if (callBack != null) {
|
||||
callBack.run();
|
||||
}
|
||||
}
|
||||
|
||||
private class AnnotationListenerCache {
|
||||
|
|
|
|||
|
|
@ -16,17 +16,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.metrics.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
package org.apache.skywalking.oap.server.core.oal.rt;
|
||||
|
||||
/**
|
||||
* @author wusheng
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExpressionArg0 {
|
||||
}
|
||||
public class OALCompileException extends Exception {
|
||||
public OALCompileException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OALCompileException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,27 +16,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
|
||||
package org.apache.skywalking.oap.server.core.oal.rt;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.analysis.DispatcherDetectorListener;
|
||||
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||
|
||||
/**
|
||||
* BinaryMatchExpression accepts two calculate factors,
|
||||
* and return the True/False result.
|
||||
* OALEngine defines the main entrance of the oal script engine runtime.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public abstract class BinaryMatchExpression {
|
||||
protected Object left;
|
||||
protected Object right;
|
||||
public interface OALEngine {
|
||||
void setStreamListener(StreamAnnotationListener listener) throws ModuleStartException;
|
||||
|
||||
public BinaryMatchExpression setLeft(Object left) {
|
||||
this.left = left;
|
||||
return this;
|
||||
}
|
||||
void setDispatcherListener(DispatcherDetectorListener listener) throws ModuleStartException;
|
||||
|
||||
public BinaryMatchExpression setRight(Object right) {
|
||||
this.right = right;
|
||||
return this;
|
||||
}
|
||||
void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException;
|
||||
|
||||
public abstract boolean match();
|
||||
void notifyAllListeners() throws ModuleStartException;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.oap.server.core.oal.rt;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Load the OAL Engine runtime, because runtime module depends on core, so we have to use class::forname to locate it.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class OALEngineLoader {
|
||||
private static volatile OALEngine ENGINE = null;
|
||||
private static ReentrantLock INIT_LOCK = new ReentrantLock();
|
||||
|
||||
public static OALEngine get() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
|
||||
if (ENGINE == null) {
|
||||
INIT_LOCK.lock();
|
||||
try {
|
||||
if (ENGINE == null) {
|
||||
init();
|
||||
}
|
||||
} finally {
|
||||
INIT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
return ENGINE;
|
||||
}
|
||||
|
||||
private static void init() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
|
||||
Class<?> engineRTClass = Class.forName("org.apache.skywalking.oal.rt.OALRuntime");
|
||||
ENGINE = (OALEngine)engineRTClass.newInstance();
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ public class DefaultScopeDefine {
|
|||
public static final int HTTP_ACCESS_LOG = 25;
|
||||
|
||||
/**
|
||||
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal tool.
|
||||
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
|
||||
*/
|
||||
public static final String SERVICE_CATALOG_NAME = "SERVICE";
|
||||
public static final String SERVICE_INSTANCE_CATALOG_NAME = "SERVICE_INSTANCE";
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@
|
|||
package org.apache.skywalking.oap.server.core.source;
|
||||
|
||||
import java.io.IOException;
|
||||
import lombok.Getter;
|
||||
import org.apache.skywalking.oap.server.core.analysis.DispatcherManager;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng
|
||||
*/
|
||||
public class SourceReceiverImpl implements SourceReceiver {
|
||||
|
||||
@Getter
|
||||
private final DispatcherManager dispatcherManager;
|
||||
|
||||
public SourceReceiverImpl() {
|
||||
|
|
|
|||
|
|
@ -30,18 +30,18 @@ public class PercentMetricsTest {
|
|||
@Test
|
||||
public void testEntranceCombine() {
|
||||
PercentMetricsImpl impl = new PercentMetricsImpl();
|
||||
impl.combine(new EqualMatch(), true, true);
|
||||
impl.combine(new EqualMatch(), true, false);
|
||||
impl.combine(new EqualMatch(), true, false);
|
||||
impl.combine(new EqualMatch().match(true,true));
|
||||
impl.combine(new EqualMatch().match(true,false));
|
||||
impl.combine(new EqualMatch().match(true,false));
|
||||
|
||||
impl.calculate();
|
||||
|
||||
Assert.assertEquals(3333, impl.getValue());
|
||||
|
||||
impl = new PercentMetricsImpl();
|
||||
impl.combine(new EqualMatch(), true, true);
|
||||
impl.combine(new EqualMatch(), true, true);
|
||||
impl.combine(new EqualMatch(), true, false);
|
||||
impl.combine(new EqualMatch().match(true,true));
|
||||
impl.combine(new EqualMatch().match(true,true));
|
||||
impl.combine(new EqualMatch().match(true,false));
|
||||
|
||||
impl.calculate();
|
||||
|
||||
|
|
@ -51,14 +51,14 @@ public class PercentMetricsTest {
|
|||
@Test
|
||||
public void testSelfCombine() {
|
||||
PercentMetricsImpl impl = new PercentMetricsImpl();
|
||||
impl.combine(new EqualMatch(), true, true);
|
||||
impl.combine(new EqualMatch(), true, false);
|
||||
impl.combine(new EqualMatch(), true, false);
|
||||
impl.combine(new EqualMatch().match(true,true));
|
||||
impl.combine(new EqualMatch().match(true,false));
|
||||
impl.combine(new EqualMatch().match(true,false));
|
||||
|
||||
PercentMetricsImpl impl2 = new PercentMetricsImpl();
|
||||
impl2.combine(new EqualMatch(), true, true);
|
||||
impl2.combine(new EqualMatch(), true, true);
|
||||
impl2.combine(new EqualMatch(), true, false);
|
||||
impl2.combine(new EqualMatch().match(true,true));
|
||||
impl2.combine(new EqualMatch().match(true,true));
|
||||
impl2.combine(new EqualMatch().match(true,false));
|
||||
|
||||
impl.combine(impl2);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,19 +35,13 @@
|
|||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- generated analysis core -->
|
||||
<!-- OAL runtime core -->
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>generated-analysis</artifactId>
|
||||
<artifactId>oal-rt</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>generate-tool</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- generated analysis core -->
|
||||
<!-- OAL runtime core -->
|
||||
|
||||
<!-- cluster module -->
|
||||
<dependency>
|
||||
|
|
@ -230,6 +224,8 @@
|
|||
<exclude>component-libraries.yml</exclude>
|
||||
<exclude>datasource-settings.properties</exclude>
|
||||
<exclude>endpoint_naming_rules.properties</exclude>
|
||||
<exclude>official_analysis.oal</exclude>
|
||||
<exclude>scope-meta.yml</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
|||
|
|
@ -46,15 +46,10 @@
|
|||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>component-libraries.yml</include>
|
||||
<include>official_analysis.oal</include>
|
||||
<include>scope-meta.yml</include>
|
||||
</includes>
|
||||
<outputDirectory>/config</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/../apm-collector-instrument/target</directory>
|
||||
<includes>
|
||||
<include>collector-instrument-agent.jar</include>
|
||||
</includes>
|
||||
<outputDirectory>/agent</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
|
|
|
|||
7
pom.xml
7
pom.xml
|
|
@ -416,8 +416,9 @@
|
|||
<exclude>**/src/main/proto/protoc-gen-swagger/**</exclude>
|
||||
<exclude>**/src/main/proto/validate/validate.proto</exclude>
|
||||
|
||||
<!-- generated file from antlr -->
|
||||
<exclude>**/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.tokens</exclude>
|
||||
<!-- generated file from oal grammar and rt template -->
|
||||
<exclude>**/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.tokens</exclude>
|
||||
<exclude>**/src/main/resources/code-templates/*/*.ftl</exclude>
|
||||
|
||||
<!-- Maven Wrapper generated files -->
|
||||
<exclude>.mvn/wrapper/maven-wrapper.properties</exclude>
|
||||
|
|
@ -510,7 +511,7 @@
|
|||
org/apache/skywalking/apm/network/servicemesh/**/*.java,
|
||||
org/apache/skywalking/apm/network/language/**/*.java,
|
||||
org/apache/skywalking/oap/server/core/remote/grpc/proto/*.java,
|
||||
org/apache/skywalking/oal/tool/grammar/*.java,
|
||||
org/apache/skywalking/oal/rt/grammar/*.java,
|
||||
org/apache/skywalking/oap/server/exporter/grpc/*.java,
|
||||
org/apache/skywalking/oap/server/configuration/service/*.java
|
||||
</excludes>
|
||||
|
|
|
|||
Loading…
Reference in New Issue