Skip to content

Commit 76d003e

Browse files
authored
MAL Labeled metrics support additional attributes. (#13625)
1 parent 71c469c commit 76d003e

File tree

15 files changed

+532
-70
lines changed

15 files changed

+532
-70
lines changed

docs/en/changes/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Fail fast if SampleFamily is empty after MAL filter expression.
1313
* Fix range matrix and scalar binary operation in PromQL.
1414
* Add `LatestLabeledFunction` for meter.
15+
* MAL Labeled metrics support additional attributes.
1516

1617
#### UI
1718
* Fix the missing icon in new native trace view.

docs/en/concepts-and-designs/metrics-additional-attributes.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ kubernetes_service_apdex = from(K8SService.protocol.http.latency).filter(detectP
5252
In the MAL script, you can use the [decorate](mal.md#decorate-function) function to decorate the source, and must follow the following rules:
5353
- The decorate function must after service() function.
5454
- Not supported for histogram metrics.
55-
- Not supported for labeled metrics.
5655

5756
SkyWalking does not provide a default script for MAL, you can refer to the following example to set the `attr0` to the service `Layer`:
5857
```text

oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,6 @@ public SampleFamily decorate(Closure<Void> c) {
704704
if (ctx.isHistogram()) {
705705
throw new IllegalStateException("decorate() not supported for histogram metrics");
706706
}
707-
if (!ctx.getLabels().isEmpty()) {
708-
throw new IllegalStateException("decorate() not supported for labeled metrics");
709-
}
710707
});
711708
if (this == EMPTY) {
712709
return EMPTY;

oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgLabeledFunction.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package org.apache.skywalking.oap.server.core.analysis.meter.function.avg;
2020

21+
import org.apache.skywalking.oap.server.core.Const;
2122
import org.apache.skywalking.oap.server.core.UnexpectedException;
2223
import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
2324
import org.apache.skywalking.oap.server.core.analysis.meter.Meter;
@@ -40,6 +41,7 @@
4041
import lombok.Getter;
4142
import lombok.Setter;
4243
import lombok.ToString;
44+
import org.apache.skywalking.oap.server.library.util.StringUtil;
4345

4446
@MeterFunction(functionName = "avgLabeled")
4547
@ToString
@@ -118,6 +120,13 @@ public Metrics toHour() {
118120
metrics.setServiceId(getServiceId());
119121
metrics.getSummation().copyFrom(getSummation());
120122
metrics.getCount().copyFrom(getCount());
123+
124+
metrics.setAttr0(getAttr0());
125+
metrics.setAttr1(getAttr1());
126+
metrics.setAttr2(getAttr2());
127+
metrics.setAttr3(getAttr3());
128+
metrics.setAttr4(getAttr4());
129+
metrics.setAttr5(getAttr5());
121130
return metrics;
122131
}
123132

@@ -129,6 +138,13 @@ public Metrics toDay() {
129138
metrics.setServiceId(getServiceId());
130139
metrics.getSummation().copyFrom(getSummation());
131140
metrics.getCount().copyFrom(getCount());
141+
142+
metrics.setAttr0(getAttr0());
143+
metrics.setAttr1(getAttr1());
144+
metrics.setAttr2(getAttr2());
145+
metrics.setAttr3(getAttr3());
146+
metrics.setAttr4(getAttr4());
147+
metrics.setAttr5(getAttr5());
132148
return metrics;
133149
}
134150

@@ -145,6 +161,30 @@ public void deserialize(final RemoteData remoteData) {
145161

146162
this.entityId = remoteData.getDataStrings(0);
147163
this.serviceId = remoteData.getDataStrings(1);
164+
165+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(2))) {
166+
setAttr0(remoteData.getDataStrings(2));
167+
}
168+
169+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(3))) {
170+
setAttr1(remoteData.getDataStrings(3));
171+
}
172+
173+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(4))) {
174+
setAttr2(remoteData.getDataStrings(4));
175+
}
176+
177+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(5))) {
178+
setAttr3(remoteData.getDataStrings(5));
179+
}
180+
181+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(6))) {
182+
setAttr4(remoteData.getDataStrings(6));
183+
}
184+
185+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(7))) {
186+
setAttr5(remoteData.getDataStrings(7));
187+
}
148188
}
149189

150190
@Override
@@ -157,6 +197,13 @@ public RemoteData.Builder serialize() {
157197
remoteBuilder.addDataStrings(entityId);
158198
remoteBuilder.addDataStrings(serviceId);
159199

200+
remoteBuilder.addDataStrings(getAttr0() == null ? Const.EMPTY_STRING : getAttr0());
201+
remoteBuilder.addDataStrings(getAttr1() == null ? Const.EMPTY_STRING : getAttr1());
202+
remoteBuilder.addDataStrings(getAttr2() == null ? Const.EMPTY_STRING : getAttr2());
203+
remoteBuilder.addDataStrings(getAttr3() == null ? Const.EMPTY_STRING : getAttr3());
204+
remoteBuilder.addDataStrings(getAttr4() == null ? Const.EMPTY_STRING : getAttr4());
205+
remoteBuilder.addDataStrings(getAttr5() == null ? Const.EMPTY_STRING : getAttr5());
206+
160207
return remoteBuilder;
161208
}
162209

@@ -169,6 +216,7 @@ protected StorageID id0() {
169216

170217
@Override
171218
public void accept(final MeterEntity entity, final DataTable value) {
219+
decorate(entity);
172220
this.entityId = entity.id();
173221
this.serviceId = entity.serviceId();
174222
this.summation.append(value);
@@ -197,6 +245,13 @@ public AcceptableValue<DataTable> createNew() {
197245
metrics.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
198246
metrics.setServiceId((String) converter.get(InstanceTraffic.SERVICE_ID));
199247
metrics.setEntityId((String) converter.get(ENTITY_ID));
248+
249+
metrics.setAttr0((String) converter.get(ATTR0));
250+
metrics.setAttr1((String) converter.get(ATTR1));
251+
metrics.setAttr2((String) converter.get(ATTR2));
252+
metrics.setAttr3((String) converter.get(ATTR3));
253+
metrics.setAttr4((String) converter.get(ATTR4));
254+
metrics.setAttr5((String) converter.get(ATTR5));
200255
return metrics;
201256
}
202257

@@ -208,6 +263,13 @@ public void entity2Storage(final AvgLabeledFunction storageData, final Convert2S
208263
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
209264
converter.accept(InstanceTraffic.SERVICE_ID, storageData.getServiceId());
210265
converter.accept(ENTITY_ID, storageData.getEntityId());
266+
267+
converter.accept(ATTR0, storageData.getAttr0());
268+
converter.accept(ATTR1, storageData.getAttr1());
269+
converter.accept(ATTR2, storageData.getAttr2());
270+
converter.accept(ATTR3, storageData.getAttr3());
271+
converter.accept(ATTR4, storageData.getAttr4());
272+
converter.accept(ATTR5, storageData.getAttr5());
211273
}
212274
}
213275

oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/latest/LatestLabeledFunction.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import lombok.Getter;
2323
import lombok.Setter;
2424
import lombok.ToString;
25+
import org.apache.skywalking.oap.server.core.Const;
2526
import org.apache.skywalking.oap.server.core.UnexpectedException;
2627
import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
2728
import org.apache.skywalking.oap.server.core.analysis.meter.Meter;
@@ -39,6 +40,7 @@
3940
import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity;
4041
import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage;
4142
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
43+
import org.apache.skywalking.oap.server.library.util.StringUtil;
4244

4345
@MeterFunction(functionName = "latestLabeled")
4446
@ToString
@@ -69,6 +71,7 @@ public abstract class LatestLabeledFunction extends Meter implements AcceptableV
6971

7072
@Override
7173
public void accept(final MeterEntity entity, final DataTable value) {
74+
decorate(entity);
7275
setEntityId(entity.id());
7376
setServiceId(entity.serviceId());
7477
this.value = value;
@@ -93,6 +96,13 @@ public Metrics toHour() {
9396
metrics.setTimeBucket(toTimeBucketInHour());
9497
metrics.setServiceId(getServiceId());
9598
metrics.getValue().copyFrom(getValue());
99+
100+
metrics.setAttr0(getAttr0());
101+
metrics.setAttr1(getAttr1());
102+
metrics.setAttr2(getAttr2());
103+
metrics.setAttr3(getAttr3());
104+
metrics.setAttr4(getAttr4());
105+
metrics.setAttr5(getAttr5());
96106
return metrics;
97107
}
98108

@@ -103,6 +113,13 @@ public Metrics toDay() {
103113
metrics.setTimeBucket(toTimeBucketInDay());
104114
metrics.setServiceId(getServiceId());
105115
metrics.getValue().copyFrom(getValue());
116+
117+
metrics.setAttr0(getAttr0());
118+
metrics.setAttr1(getAttr1());
119+
metrics.setAttr2(getAttr2());
120+
metrics.setAttr3(getAttr3());
121+
metrics.setAttr4(getAttr4());
122+
metrics.setAttr5(getAttr5());
106123
return metrics;
107124
}
108125

@@ -120,6 +137,30 @@ public void deserialize(final RemoteData remoteData) {
120137

121138
setEntityId(remoteData.getDataStrings(0));
122139
setServiceId(remoteData.getDataStrings(1));
140+
141+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(2))) {
142+
setAttr0(remoteData.getDataStrings(2));
143+
}
144+
145+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(3))) {
146+
setAttr1(remoteData.getDataStrings(3));
147+
}
148+
149+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(4))) {
150+
setAttr2(remoteData.getDataStrings(4));
151+
}
152+
153+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(5))) {
154+
setAttr3(remoteData.getDataStrings(5));
155+
}
156+
157+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(6))) {
158+
setAttr4(remoteData.getDataStrings(6));
159+
}
160+
161+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(7))) {
162+
setAttr5(remoteData.getDataStrings(7));
163+
}
123164
}
124165

125166
@Override
@@ -131,6 +172,13 @@ public RemoteData.Builder serialize() {
131172
remoteBuilder.addDataStrings(entityId);
132173
remoteBuilder.addDataStrings(serviceId);
133174

175+
remoteBuilder.addDataStrings(getAttr0() == null ? Const.EMPTY_STRING : getAttr0());
176+
remoteBuilder.addDataStrings(getAttr1() == null ? Const.EMPTY_STRING : getAttr1());
177+
remoteBuilder.addDataStrings(getAttr2() == null ? Const.EMPTY_STRING : getAttr2());
178+
remoteBuilder.addDataStrings(getAttr3() == null ? Const.EMPTY_STRING : getAttr3());
179+
remoteBuilder.addDataStrings(getAttr4() == null ? Const.EMPTY_STRING : getAttr4());
180+
remoteBuilder.addDataStrings(getAttr5() == null ? Const.EMPTY_STRING : getAttr5());
181+
134182
return remoteBuilder;
135183
}
136184

@@ -157,6 +205,13 @@ public AcceptableValue<DataTable> createNew() {
157205
metrics.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
158206
metrics.setServiceId((String) converter.get(InstanceTraffic.SERVICE_ID));
159207
metrics.setEntityId((String) converter.get(ENTITY_ID));
208+
209+
metrics.setAttr0((String) converter.get(ATTR0));
210+
metrics.setAttr1((String) converter.get(ATTR1));
211+
metrics.setAttr2((String) converter.get(ATTR2));
212+
metrics.setAttr3((String) converter.get(ATTR3));
213+
metrics.setAttr4((String) converter.get(ATTR4));
214+
metrics.setAttr5((String) converter.get(ATTR5));
160215
return metrics;
161216
}
162217

@@ -166,6 +221,13 @@ public void entity2Storage(final LatestLabeledFunction storageData, final Conver
166221
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
167222
converter.accept(InstanceTraffic.SERVICE_ID, storageData.getServiceId());
168223
converter.accept(ENTITY_ID, storageData.getEntityId());
224+
225+
converter.accept(ATTR0, storageData.getAttr0());
226+
converter.accept(ATTR1, storageData.getAttr1());
227+
converter.accept(ATTR2, storageData.getAttr2());
228+
converter.accept(ATTR3, storageData.getAttr3());
229+
converter.accept(ATTR4, storageData.getAttr4());
230+
converter.accept(ATTR5, storageData.getAttr5());
169231
}
170232
}
171233

oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/max/MaxLabeledFunction.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import lombok.Getter;
2222
import lombok.Setter;
2323
import lombok.ToString;
24+
import org.apache.skywalking.oap.server.core.Const;
2425
import org.apache.skywalking.oap.server.core.UnexpectedException;
2526
import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
2627
import org.apache.skywalking.oap.server.core.analysis.meter.Meter;
@@ -40,6 +41,7 @@
4041
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
4142

4243
import java.util.Objects;
44+
import org.apache.skywalking.oap.server.library.util.StringUtil;
4345

4446
@MeterFunction(functionName = "maxLabeled")
4547
@ToString
@@ -70,6 +72,7 @@ public abstract class MaxLabeledFunction extends Meter implements AcceptableValu
7072

7173
@Override
7274
public void accept(final MeterEntity entity, final DataTable value) {
75+
decorate(entity);
7376
setEntityId(entity.id());
7477
setServiceId(entity.serviceId());
7578
this.value.setMaxValue(value);
@@ -94,6 +97,13 @@ public Metrics toHour() {
9497
metrics.setTimeBucket(toTimeBucketInHour());
9598
metrics.setServiceId(getServiceId());
9699
metrics.getValue().copyFrom(getValue());
100+
101+
metrics.setAttr0(getAttr0());
102+
metrics.setAttr1(getAttr1());
103+
metrics.setAttr2(getAttr2());
104+
metrics.setAttr3(getAttr3());
105+
metrics.setAttr4(getAttr4());
106+
metrics.setAttr5(getAttr5());
97107
return metrics;
98108
}
99109

@@ -104,6 +114,13 @@ public Metrics toDay() {
104114
metrics.setTimeBucket(toTimeBucketInDay());
105115
metrics.setServiceId(getServiceId());
106116
metrics.getValue().copyFrom(getValue());
117+
118+
metrics.setAttr0(getAttr0());
119+
metrics.setAttr1(getAttr1());
120+
metrics.setAttr2(getAttr2());
121+
metrics.setAttr3(getAttr3());
122+
metrics.setAttr4(getAttr4());
123+
metrics.setAttr5(getAttr5());
107124
return metrics;
108125
}
109126

@@ -121,6 +138,30 @@ public void deserialize(final RemoteData remoteData) {
121138

122139
setEntityId(remoteData.getDataStrings(0));
123140
setServiceId(remoteData.getDataStrings(1));
141+
142+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(2))) {
143+
setAttr0(remoteData.getDataStrings(2));
144+
}
145+
146+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(3))) {
147+
setAttr1(remoteData.getDataStrings(3));
148+
}
149+
150+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(4))) {
151+
setAttr2(remoteData.getDataStrings(4));
152+
}
153+
154+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(5))) {
155+
setAttr3(remoteData.getDataStrings(5));
156+
}
157+
158+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(6))) {
159+
setAttr4(remoteData.getDataStrings(6));
160+
}
161+
162+
if (StringUtil.isNotEmpty(remoteData.getDataStrings(7))) {
163+
setAttr5(remoteData.getDataStrings(7));
164+
}
124165
}
125166

126167
@Override
@@ -132,6 +173,12 @@ public RemoteData.Builder serialize() {
132173
remoteBuilder.addDataStrings(entityId);
133174
remoteBuilder.addDataStrings(serviceId);
134175

176+
remoteBuilder.addDataStrings(getAttr0() == null ? Const.EMPTY_STRING : getAttr0());
177+
remoteBuilder.addDataStrings(getAttr1() == null ? Const.EMPTY_STRING : getAttr1());
178+
remoteBuilder.addDataStrings(getAttr2() == null ? Const.EMPTY_STRING : getAttr2());
179+
remoteBuilder.addDataStrings(getAttr3() == null ? Const.EMPTY_STRING : getAttr3());
180+
remoteBuilder.addDataStrings(getAttr4() == null ? Const.EMPTY_STRING : getAttr4());
181+
remoteBuilder.addDataStrings(getAttr5() == null ? Const.EMPTY_STRING : getAttr5());
135182
return remoteBuilder;
136183
}
137184

@@ -158,6 +205,13 @@ public AcceptableValue<DataTable> createNew() {
158205
metrics.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
159206
metrics.setServiceId((String) converter.get(InstanceTraffic.SERVICE_ID));
160207
metrics.setEntityId((String) converter.get(ENTITY_ID));
208+
209+
metrics.setAttr0((String) converter.get(ATTR0));
210+
metrics.setAttr1((String) converter.get(ATTR1));
211+
metrics.setAttr2((String) converter.get(ATTR2));
212+
metrics.setAttr3((String) converter.get(ATTR3));
213+
metrics.setAttr4((String) converter.get(ATTR4));
214+
metrics.setAttr5((String) converter.get(ATTR5));
161215
return metrics;
162216
}
163217

@@ -167,6 +221,13 @@ public void entity2Storage(final MaxLabeledFunction storageData, final Convert2S
167221
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
168222
converter.accept(InstanceTraffic.SERVICE_ID, storageData.getServiceId());
169223
converter.accept(ENTITY_ID, storageData.getEntityId());
224+
225+
converter.accept(ATTR0, storageData.getAttr0());
226+
converter.accept(ATTR1, storageData.getAttr1());
227+
converter.accept(ATTR2, storageData.getAttr2());
228+
converter.accept(ATTR3, storageData.getAttr3());
229+
converter.accept(ATTR4, storageData.getAttr4());
230+
converter.accept(ATTR5, storageData.getAttr5());
170231
}
171232
}
172233

0 commit comments

Comments
 (0)