Skip to content

Commit 8fbc1eb

Browse files
authored
Add Baseline module for support alarm module query predict metrics value (#12991)
1 parent 0d7c787 commit 8fbc1eb

File tree

17 files changed

+901
-0
lines changed

17 files changed

+901
-0
lines changed

docs/en/changes/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
* MQE: Support `&&(and)`, `||(or)` bool operators.
6565
* OAP self observability: Add JVM heap and direct memory used metrics.
6666
* OAP self observability: Add watermark circuit break/recover metrics.
67+
* Add Baseline module for support alarm module query baseline data.
6768

6869
#### UI
6970

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
~
18+
-->
19+
20+
<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">
21+
<parent>
22+
<artifactId>oap-server</artifactId>
23+
<groupId>org.apache.skywalking</groupId>
24+
<version>${revision}</version>
25+
</parent>
26+
<modelVersion>4.0.0</modelVersion>
27+
28+
<artifactId>metrics-baseline</artifactId>
29+
30+
<dependencies>
31+
<dependency>
32+
<groupId>org.apache.skywalking</groupId>
33+
<artifactId>server-core</artifactId>
34+
<version>${project.version}</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>io.grpc</groupId>
38+
<artifactId>grpc-testing</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.powermock</groupId>
43+
<artifactId>powermock-reflect</artifactId>
44+
<scope>test</scope>
45+
</dependency>
46+
</dependencies>
47+
48+
<build>
49+
<plugins>
50+
<plugin>
51+
<groupId>org.xolstice.maven.plugins</groupId>
52+
<artifactId>protobuf-maven-plugin</artifactId>
53+
<version>${protobuf-maven-plugin.version}</version>
54+
<configuration>
55+
<!--
56+
The version of protoc must match protobuf-java. If you don't depend on
57+
protobuf-java directly, you will be transitively depending on the
58+
protobuf-java version that grpc depends on.
59+
-->
60+
<protocArtifact>com.google.protobuf:protoc:${com.google.protobuf.protoc.version}:exe:${os.detected.classifier}
61+
</protocArtifact>
62+
<pluginId>grpc-java</pluginId>
63+
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${protoc-gen-grpc-java.plugin.version}:exe:${os.detected.classifier}
64+
</pluginArtifact>
65+
</configuration>
66+
<executions>
67+
<execution>
68+
<goals>
69+
<goal>compile</goal>
70+
<goal>compile-custom</goal>
71+
</goals>
72+
</execution>
73+
</executions>
74+
</plugin>
75+
</plugins>
76+
</build>
77+
</project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.oap.server.baseline;
20+
21+
import org.apache.skywalking.oap.server.baseline.service.BaselineQueryService;
22+
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
23+
24+
public class BaselineModule extends ModuleDefine {
25+
public static final String NAME = "baseline";
26+
27+
public BaselineModule() {
28+
super(NAME);
29+
}
30+
31+
@Override
32+
public Class[] services() {
33+
return new Class[]{BaselineQueryService.class};
34+
}
35+
36+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.oap.server.baseline;
20+
21+
import lombok.Getter;
22+
import lombok.Setter;
23+
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
24+
25+
public class BaselineModuleConfig extends ModuleConfig {
26+
@Setter
27+
@Getter
28+
private String serviceHost = "";
29+
@Setter
30+
@Getter
31+
private int servicePort = 0;
32+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.oap.server.baseline;
20+
21+
import org.apache.skywalking.oap.server.baseline.service.BaselineQueryService;
22+
import org.apache.skywalking.oap.server.baseline.service.BaselineQueryServiceImpl;
23+
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
24+
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
25+
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
26+
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
27+
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
28+
29+
public class BaselineModuleProvider extends ModuleProvider {
30+
private BaselineModuleConfig config;
31+
32+
@Override
33+
public String name() {
34+
return "default";
35+
}
36+
37+
@Override
38+
public Class<? extends ModuleDefine> module() {
39+
return BaselineModule.class;
40+
}
41+
42+
@Override
43+
public ConfigCreator<? extends ModuleConfig> newConfigCreator() {
44+
return new ConfigCreator<BaselineModuleConfig>() {
45+
@Override
46+
public Class type() {
47+
return BaselineModuleConfig.class;
48+
}
49+
50+
@Override
51+
public void onInitialized(BaselineModuleConfig moduleConfig) {
52+
config = moduleConfig;
53+
}
54+
};
55+
}
56+
57+
@Override
58+
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
59+
this.registerServiceImplementation(BaselineQueryService.class, new BaselineQueryServiceImpl(config.getServiceHost(),
60+
config.getServicePort()));
61+
}
62+
63+
@Override
64+
public void start() throws ServiceNotProvidedException, ModuleStartException {
65+
66+
}
67+
68+
@Override
69+
public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
70+
71+
}
72+
73+
@Override
74+
public String[] requiredModules() {
75+
return new String[0];
76+
}
77+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.oap.server.baseline.service;
20+
21+
import org.apache.skywalking.oap.server.library.module.Service;
22+
23+
import java.util.List;
24+
25+
public interface BaselineQueryService extends Service {
26+
/**
27+
* query predict metrics
28+
*/
29+
List<PredictServiceMetrics> queryPredictMetrics(List<ServiceMetrics> serviceMetrics, long startTimeBucket, long endTimeBucket);
30+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.oap.server.baseline.service;
20+
21+
import io.grpc.ManagedChannel;
22+
import lombok.extern.slf4j.Slf4j;
23+
import org.apache.skywalking.apm.baseline.v3.AlarmBaselineMetricPrediction;
24+
import org.apache.skywalking.apm.baseline.v3.AlarmBaselineRequest;
25+
import org.apache.skywalking.apm.baseline.v3.AlarmBaselineResponse;
26+
import org.apache.skywalking.apm.baseline.v3.AlarmBaselineServiceGrpc;
27+
import org.apache.skywalking.apm.baseline.v3.AlarmBaselineServiceMetricName;
28+
import org.apache.skywalking.apm.baseline.v3.KeyStringValuePair;
29+
import org.apache.skywalking.apm.baseline.v3.TimeBucketStep;
30+
import org.apache.skywalking.oap.server.library.client.grpc.GRPCClient;
31+
import org.apache.skywalking.oap.server.library.util.StringUtil;
32+
33+
import java.util.Collections;
34+
import java.util.List;
35+
import java.util.stream.Collectors;
36+
37+
@Slf4j
38+
public class BaselineQueryServiceImpl implements BaselineQueryService {
39+
private AlarmBaselineServiceGrpc.AlarmBaselineServiceBlockingStub stub;
40+
41+
public BaselineQueryServiceImpl(String addr, int port) {
42+
if (StringUtil.isEmpty(addr) || port <= 0) {
43+
return;
44+
}
45+
GRPCClient client = new GRPCClient(addr, port);
46+
client.connect();
47+
ManagedChannel channel = client.getChannel();
48+
stub = AlarmBaselineServiceGrpc.newBlockingStub(channel);
49+
}
50+
51+
public List<PredictServiceMetrics> queryPredictMetrics(List<ServiceMetrics> serviceMetrics, long startTimeBucket, long endTimeBucket) {
52+
if (stub == null) {
53+
return Collections.emptyList();
54+
}
55+
56+
try {
57+
return queryPredictMetrics0(serviceMetrics, startTimeBucket, endTimeBucket);
58+
} catch (Exception e) {
59+
log.warn("Query baseline failure", e);
60+
}
61+
return Collections.emptyList();
62+
}
63+
64+
private List<PredictServiceMetrics> queryPredictMetrics0(List<ServiceMetrics> serviceMetrics, long startTimeBucket, long endTimeBucket) {
65+
// building request
66+
final AlarmBaselineRequest.Builder request = AlarmBaselineRequest.newBuilder();
67+
serviceMetrics.forEach(s -> {
68+
final AlarmBaselineServiceMetricName.Builder serviceMetricsBuilder = AlarmBaselineServiceMetricName.newBuilder();
69+
serviceMetricsBuilder.setServiceName(s.getServiceName());
70+
serviceMetricsBuilder.addAllMetricNames(s.getMetricsNames());
71+
request.addServiceMetricNames(serviceMetricsBuilder);
72+
});
73+
request.setStartTimeBucket(startTimeBucket);
74+
request.setEndTimeBucket(endTimeBucket);
75+
// Only support hour level for now
76+
request.setStep(TimeBucketStep.HOUR);
77+
78+
// send request and convert response
79+
final AlarmBaselineResponse response = stub.queryPredictedMetrics(request.build());
80+
return response.getServiceMetricsList().stream().map(s -> {
81+
final PredictServiceMetrics.PredictServiceMetricsBuilder builder = PredictServiceMetrics.builder();
82+
builder.serviceName(s.getServiceName());
83+
builder.metricsValues(s.getPredictionsList().stream().collect(
84+
Collectors.toMap(AlarmBaselineMetricPrediction::getName, p -> p.getValuesList().stream().map(v -> {
85+
final PredictServiceMetrics.PredictMetricsValue.PredictMetricsValueBuilder valueBuilder =
86+
PredictServiceMetrics.PredictMetricsValue.builder();
87+
valueBuilder.timeBucket(v.getTimeBucket());
88+
// parsing single value
89+
if (v.hasSingleValue()) {
90+
valueBuilder.singleValue(PredictServiceMetrics.PredictSingleValue.builder()
91+
.value(v.getSingleValue().getValue().getValue())
92+
.upperValue(v.getSingleValue().getValue().getUpperValue())
93+
.lowerValue(v.getSingleValue().getValue().getLowerValue())
94+
.build());
95+
}
96+
// parsing labeled values
97+
if (v.hasLabeledValue()) {
98+
valueBuilder.labeledValue(v.getLabeledValue().getValuesList().stream().map(l -> {
99+
final PredictServiceMetrics.PredictLabelValue.PredictLabelValueBuilder labelBuilder =
100+
PredictServiceMetrics.PredictLabelValue.builder();
101+
labelBuilder.labels(l.getLabelsList().stream().collect(
102+
Collectors.toMap(KeyStringValuePair::getKey, KeyStringValuePair::getValue)));
103+
labelBuilder.value(PredictServiceMetrics.PredictSingleValue.builder()
104+
.value(l.getValue().getValue())
105+
.upperValue(l.getValue().getUpperValue())
106+
.lowerValue(l.getValue().getLowerValue())
107+
.build());
108+
return labelBuilder.build();
109+
}).collect(Collectors.toList()));
110+
}
111+
return valueBuilder.build();
112+
}).collect(Collectors.toList()))));
113+
return builder.build();
114+
}).collect(Collectors.toList());
115+
}
116+
}

0 commit comments

Comments
 (0)