未验证 提交 071708a4 编写于 作者: wu-sheng's avatar wu-sheng 提交者: GitHub

Support default value in labeled-value and heatmap query. (#4711)

* Support default value in labeled-value and heatmap query.

* Update a little document.
上级 2b41aea6
...@@ -38,7 +38,7 @@ including ...@@ -38,7 +38,7 @@ including
1. Java, [.NET Core](https://github.com/SkyAPM/SkyAPM-dotnet), [NodeJS](https://github.com/SkyAPM/SkyAPM-nodejs) and [PHP](https://github.com/SkyAPM/SkyAPM-php-sdk) auto-instrument agents. 1. Java, [.NET Core](https://github.com/SkyAPM/SkyAPM-dotnet), [NodeJS](https://github.com/SkyAPM/SkyAPM-nodejs) and [PHP](https://github.com/SkyAPM/SkyAPM-php-sdk) auto-instrument agents.
1. [Go agent](https://github.com/tetratelabs/go2sky). 1. [Go agent](https://github.com/tetratelabs/go2sky).
1. [LUA agent](https://github.com/apache/skywalking-nginx-lua), especially for Nginx, OpenResty. 1. [LUA agent](https://github.com/apache/skywalking-nginx-lua), especially for Nginx, OpenResty.
1. Service Mesh Observability, including Envoy gRPC Access Log Service (ALS) format in Istio controlled service mesh, Istio telemetry. 1. Service Mesh Observability. Support Mixer telemetry. Recommend to use Envoy Access Log Service (ALS) for better performance, first introduced at [KubeCon 2019](https://www.youtube.com/watch?v=tERm39ju9ew).
1. Metrics system, including Prometheus, Spring Sleuth(Micrometer). 1. Metrics system, including Prometheus, Spring Sleuth(Micrometer).
1. Zipkin v1/v2 and Jaeger gRPC format with limited topology and metrics analysis.(Experimental). 1. Zipkin v1/v2 and Jaeger gRPC format with limited topology and metrics analysis.(Experimental).
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
Envoy [ALS(access log service)](https://www.envoyproxy.io/docs/envoy/latest/api-v2/service/accesslog/v2/als.proto) provides Envoy [ALS(access log service)](https://www.envoyproxy.io/docs/envoy/latest/api-v2/service/accesslog/v2/als.proto) provides
fully logs about RPC routed, including HTTP and TCP. fully logs about RPC routed, including HTTP and TCP.
**If solution initialized and first implemented by [Sheng Wu](https://github.com/wu-sheng), [Hongtao Gao](https://github.com/hanahmily), [Lizan Zhou](https://github.com/lizan) and [Dhi Aurrahman](https://github.com/dio) at 17 May. 2019, and presented on [KubeCon China 2019](https://kccncosschn19eng.sched.com/event/NroB/observability-in-service-mesh-powered-by-envoy-and-apache-skywalking-sheng-wu-lizan-zhou-tetrate).** If solution initialized and first implemented by [Sheng Wu](https://github.com/wu-sheng), [Hongtao Gao](https://github.com/hanahmily), [Lizan Zhou](https://github.com/lizan),
and [Dhi Aurrahman](https://github.com/dio) at 17 May. 2019,
and presented on [KubeCon China 2019](https://kccncosschn19eng.sched.com/event/NroB/observability-in-service-mesh-powered-by-envoy-and-apache-skywalking-sheng-wu-lizan-zhou-tetrate).
Here is the recorded [Video](https://www.youtube.com/watch?v=tERm39ju9ew).
SkyWalking is the first open source project introducing this ALS based solution to the world. This provides a new way with very low payload to service mesh, but the same observability. SkyWalking is the first open source project introducing this ALS based solution to the world. This provides a new way with very low payload to service mesh, but the same observability.
...@@ -17,4 +20,4 @@ envoy-metric: ...@@ -17,4 +20,4 @@ envoy-metric:
``` ```
Note multiple value,please use `,` symbol split Note multiple value,please use `,` symbol split
Notice, only use this when envoy under Istio controlled, also in k8s env. Notice, only use this when envoy under Istio controlled, also in k8s env. The OAP requires the read right to k8s API server for all pods IPs.
...@@ -13,6 +13,8 @@ Follow the [deploying backend in kubernetes](../backend/backend-k8s.md) to insta ...@@ -13,6 +13,8 @@ Follow the [deploying backend in kubernetes](../backend/backend-k8s.md) to insta
## Setup Istio to send metrics to oap ## Setup Istio to send metrics to oap
Our scripts are wrote based on Istio 1.3.3.
1. Install Istio metric template 1. Install Istio metric template
`kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.3.3/mixer/template/metric/template.yaml` `kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.3.3/mixer/template/metric/template.yaml`
...@@ -22,3 +24,5 @@ Follow the [deploying backend in kubernetes](../backend/backend-k8s.md) to insta ...@@ -22,3 +24,5 @@ Follow the [deploying backend in kubernetes](../backend/backend-k8s.md) to insta
`kubectl apply -f skywalkingadapter.yml` `kubectl apply -f skywalkingadapter.yml`
Find the `skywalkingadapter.yml` at [here](yaml/skywalkingadapter.yml). Find the `skywalkingadapter.yml` at [here](yaml/skywalkingadapter.yml).
NOTICE, due to Istio Mixer is default OFF, we recommend you to consider our [ALS solution](../envoy/als_setting.md)
\ No newline at end of file
...@@ -71,6 +71,10 @@ public class DataTable implements StorageDataComplexObject<DataTable> { ...@@ -71,6 +71,10 @@ public class DataTable implements StorageDataComplexObject<DataTable> {
return !data.isEmpty(); return !data.isEmpty();
} }
public boolean hasKey(String key) {
return data.containsKey(key);
}
public int size() { public int size() {
return data.size(); return data.size();
} }
......
...@@ -41,7 +41,7 @@ public abstract class HistogramMetrics extends Metrics { ...@@ -41,7 +41,7 @@ public abstract class HistogramMetrics extends Metrics {
@Getter @Getter
@Setter @Setter
@Column(columnName = DATASET, dataType = Column.ValueDataType.HISTOGRAM, storageOnly = true) @Column(columnName = DATASET, dataType = Column.ValueDataType.HISTOGRAM, storageOnly = true, defaultValue = 0)
private DataTable dataset = new DataTable(30); private DataTable dataset = new DataTable(30);
/** /**
......
...@@ -45,7 +45,7 @@ public class HeatMap { ...@@ -45,7 +45,7 @@ public class HeatMap {
* @param id of the row * @param id of the row
* @param rawdata literal string, represent a {@link DataTable} * @param rawdata literal string, represent a {@link DataTable}
*/ */
public void buildColumn(String id, String rawdata) { public void buildColumn(String id, String rawdata, int defaultValue) {
DataTable dataset = new DataTable(rawdata); DataTable dataset = new DataTable(rawdata);
final List<String> sortedKeys = dataset.sortedKeys( final List<String> sortedKeys = dataset.sortedKeys(
...@@ -70,12 +70,16 @@ public class HeatMap { ...@@ -70,12 +70,16 @@ public class HeatMap {
HeatMap.HeatMapColumn column = new HeatMap.HeatMapColumn(); HeatMap.HeatMapColumn column = new HeatMap.HeatMapColumn();
column.setId(id); column.setId(id);
sortedKeys.forEach(key -> { sortedKeys.forEach(key -> {
column.addValue(dataset.get(key)); if (dataset.hasKey(key)) {
column.addValue(dataset.get(key));
} else {
column.addValue((long) defaultValue);
}
}); });
values.add(column); values.add(column);
} }
public void fixMissingColumns(List<String> ids) { public void fixMissingColumns(List<String> ids, int defaultValue) {
for (int i = 0; i < ids.size(); i++) { for (int i = 0; i < ids.size(); i++) {
final String expectedId = ids.get(i); final String expectedId = ids.get(i);
boolean found = false; boolean found = false;
...@@ -85,17 +89,17 @@ public class HeatMap { ...@@ -85,17 +89,17 @@ public class HeatMap {
} }
} }
if (!found) { if (!found) {
final HeatMapColumn emptyColumn = buildMissingColumn(expectedId); final HeatMapColumn emptyColumn = buildMissingColumn(expectedId, defaultValue);
values.add(i, emptyColumn); values.add(i, emptyColumn);
} }
} }
} }
private HeatMapColumn buildMissingColumn(String id) { private HeatMapColumn buildMissingColumn(String id, int defaultValue) {
HeatMapColumn column = new HeatMapColumn(); HeatMapColumn column = new HeatMapColumn();
column.setId(id); column.setId(id);
buckets.forEach(bucket -> { buckets.forEach(bucket -> {
column.addValue(0L); column.addValue((long) defaultValue);
}); });
return column; return column;
} }
......
...@@ -148,14 +148,18 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO { ...@@ -148,14 +148,18 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
labeledValues.put(label, labelValue); labeledValues.put(label, labelValue);
}); });
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
for (String id : ids) { for (String id : ids) {
if (idMap.containsKey(id)) { if (idMap.containsKey(id)) {
Map<String, Object> source = idMap.get(id); Map<String, Object> source = idMap.get(id);
DataTable multipleValues = new DataTable((String) source.getOrDefault(valueColumnName, "")); DataTable multipleValues = new DataTable((String) source.getOrDefault(valueColumnName, ""));
labels.forEach(label -> { labels.forEach(label -> {
final Long data = multipleValues.get(label);
final IntValues values = labeledValues.get(label).getValues(); final IntValues values = labeledValues.get(label).getValues();
Long data = multipleValues.get(label);
if (data == null) {
data = (long) defaultValue;
}
KVInt kv = new KVInt(); KVInt kv = new KVInt();
kv.setId(id); kv.setId(id);
kv.setValue(data); kv.setValue(data);
...@@ -168,7 +172,7 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO { ...@@ -168,7 +172,7 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
return Util.sortValues( return Util.sortValues(
new ArrayList<>(labeledValues.values()), new ArrayList<>(labeledValues.values()),
ids, ids,
ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()) defaultValue
); );
} }
...@@ -187,15 +191,16 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO { ...@@ -187,15 +191,16 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
HeatMap heatMap = new HeatMap(); HeatMap heatMap = new HeatMap();
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
for (String id : ids) { for (String id : ids) {
Map<String, Object> source = idMap.get(id); Map<String, Object> source = idMap.get(id);
if (source != null) { if (source != null) {
String value = (String) source.get(HistogramMetrics.DATASET); String value = (String) source.get(HistogramMetrics.DATASET);
heatMap.buildColumn(id, value); heatMap.buildColumn(id, value, defaultValue);
} }
} }
heatMap.fixMissingColumns(ids); heatMap.fixMissingColumns(ids, defaultValue);
return heatMap; return heatMap;
} }
......
...@@ -183,6 +183,7 @@ public class MetricsQuery implements IMetricsQueryDAO { ...@@ -183,6 +183,7 @@ public class MetricsQuery implements IMetricsQueryDAO {
labeledValues.put(label, labelValue); labeledValues.put(label, labelValue);
}); });
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
if (!CollectionUtils.isEmpty(series)) { if (!CollectionUtils.isEmpty(series)) {
series.get(0).getValues().forEach(values -> { series.get(0).getValues().forEach(values -> {
final String id = (String) values.get(1); final String id = (String) values.get(1);
...@@ -190,7 +191,10 @@ public class MetricsQuery implements IMetricsQueryDAO { ...@@ -190,7 +191,10 @@ public class MetricsQuery implements IMetricsQueryDAO {
multipleValues.toObject((String) values.get(2)); multipleValues.toObject((String) values.get(2));
labels.forEach(label -> { labels.forEach(label -> {
final Long data = multipleValues.get(label); Long data = multipleValues.get(label);
if (data == null) {
data = (long) defaultValue;
}
final IntValues intValues = labeledValues.get(label).getValues(); final IntValues intValues = labeledValues.get(label).getValues();
KVInt kv = new KVInt(); KVInt kv = new KVInt();
kv.setId(id); kv.setId(id);
...@@ -203,7 +207,7 @@ public class MetricsQuery implements IMetricsQueryDAO { ...@@ -203,7 +207,7 @@ public class MetricsQuery implements IMetricsQueryDAO {
return Util.sortValues( return Util.sortValues(
new ArrayList<>(labeledValues.values()), new ArrayList<>(labeledValues.values()),
ids, ids,
ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()) defaultValue
); );
} }
...@@ -229,14 +233,16 @@ public class MetricsQuery implements IMetricsQueryDAO { ...@@ -229,14 +233,16 @@ public class MetricsQuery implements IMetricsQueryDAO {
log.debug("SQL: {} result set: {}", query.getCommand(), series); log.debug("SQL: {} result set: {}", query.getCommand(), series);
} }
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
HeatMap heatMap = new HeatMap(); HeatMap heatMap = new HeatMap();
if (series != null) { if (series != null) {
for (List<Object> values : series.getValues()) { for (List<Object> values : series.getValues()) {
heatMap.buildColumn(values.get(1).toString(), values.get(2).toString()); heatMap.buildColumn(values.get(1).toString(), values.get(2).toString(), defaultValue);
} }
} }
heatMap.fixMissingColumns(ids); heatMap.fixMissingColumns(ids, defaultValue);
return heatMap; return heatMap;
} }
......
...@@ -170,6 +170,8 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO ...@@ -170,6 +170,8 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
labeledValues.put(label, labelValue); labeledValues.put(label, labelValue);
}); });
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
try (Connection connection = h2Client.getConnection()) { try (Connection connection = h2Client.getConnection()) {
try (ResultSet resultSet = h2Client.executeQuery( try (ResultSet resultSet = h2Client.executeQuery(
connection, sql.toString(), parameters.toArray(new Object[0]))) { connection, sql.toString(), parameters.toArray(new Object[0]))) {
...@@ -180,7 +182,10 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO ...@@ -180,7 +182,10 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
multipleValues.toObject(resultSet.getString(valueColumnName)); multipleValues.toObject(resultSet.getString(valueColumnName));
labels.forEach(label -> { labels.forEach(label -> {
final Long data = multipleValues.get(label); Long data = multipleValues.get(label);
if (data == null) {
data = (long) defaultValue;
}
final IntValues values = labeledValues.get(label).getValues(); final IntValues values = labeledValues.get(label).getValues();
KVInt kv = new KVInt(); KVInt kv = new KVInt();
kv.setId(id); kv.setId(id);
...@@ -196,7 +201,7 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO ...@@ -196,7 +201,7 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
return Util.sortValues( return Util.sortValues(
new ArrayList<>(labeledValues.values()), new ArrayList<>(labeledValues.values()),
ids, ids,
ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()) defaultValue
); );
} }
...@@ -223,17 +228,20 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO ...@@ -223,17 +228,20 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
} }
sql.append(")"); sql.append(")");
final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
try (Connection connection = h2Client.getConnection()) { try (Connection connection = h2Client.getConnection()) {
HeatMap heatMap = new HeatMap(); HeatMap heatMap = new HeatMap();
try (ResultSet resultSet = h2Client.executeQuery( try (ResultSet resultSet = h2Client.executeQuery(
connection, sql.toString(), parameters.toArray(new Object[0]))) { connection, sql.toString(), parameters.toArray(new Object[0]))) {
while (resultSet.next()) { while (resultSet.next()) {
heatMap.buildColumn(resultSet.getString("id"), resultSet.getString("dataset")); heatMap.buildColumn(
resultSet.getString("id"), resultSet.getString("dataset"), defaultValue);
} }
} }
heatMap.fixMissingColumns(ids); heatMap.fixMissingColumns(ids, defaultValue);
return heatMap; return heatMap;
} catch (SQLException e) { } catch (SQLException e) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册