Skip to content

Commit c9a959e

Browse files
authored
Adapt the new metadata standardization in Istio 1.24 (#12768)
1 parent 5c5274b commit c9a959e

File tree

16 files changed

+262
-59
lines changed

16 files changed

+262
-59
lines changed

.github/workflows/skywalking.yaml

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -555,26 +555,31 @@ jobs:
555555
- name: Kafka Log
556556
config: test/e2e-v2/cases/kafka/log/e2e.yaml
557557

558-
- name: Istio Metrics Service 1.15.0
558+
- name: Istio Metrics Service 1.20.0
559559
config: test/e2e-v2/cases/istio/metrics/e2e.yaml
560560
env: |
561-
ISTIO_VERSION=1.15.0
562-
KUBERNETES_VERSION=25
563-
- name: Istio Metrics Service 1.16.0
561+
ISTIO_VERSION=1.20.0
562+
KUBERNETES_VERSION=28
563+
- name: Istio Metrics Service 1.21.0
564564
config: test/e2e-v2/cases/istio/metrics/e2e.yaml
565565
env: |
566-
ISTIO_VERSION=1.16.0
567-
KUBERNETES_VERSION=25
568-
- name: Istio Metrics Service 1.17.0
566+
ISTIO_VERSION=1.21.0
567+
KUBERNETES_VERSION=28
568+
- name: Istio Metrics Service 1.22.0
569569
config: test/e2e-v2/cases/istio/metrics/e2e.yaml
570570
env: |
571-
ISTIO_VERSION=1.17.0
572-
KUBERNETES_VERSION=25
573-
- name: Istio Metrics Service 1.18.0
571+
ISTIO_VERSION=1.22.0
572+
KUBERNETES_VERSION=28
573+
- name: Istio Metrics Service 1.23.0
574574
config: test/e2e-v2/cases/istio/metrics/e2e.yaml
575575
env: |
576-
ISTIO_VERSION=1.18.0
577-
KUBERNETES_VERSION=25
576+
ISTIO_VERSION=1.23.0
577+
KUBERNETES_VERSION=28
578+
- name: Istio Metrics Service 1.24.0
579+
config: test/e2e-v2/cases/istio/metrics/e2e.yaml
580+
env: |
581+
ISTIO_VERSION=1.24.0
582+
KUBERNETES_VERSION=28
578583
579584
- name: Rover with Istio Process 1.15.0
580585
config: test/e2e-v2/cases/rover/process/istio/e2e.yaml
@@ -769,14 +774,16 @@ jobs:
769774
matrix:
770775
analyzer: [k8s-mesh, mx-mesh]
771776
versions:
772-
- istio: 1.15.0
773-
kubernetes: 25
774-
- istio: 1.16.0
775-
kubernetes: 25
776-
- istio: 1.17.0
777-
kubernetes: 25
778-
- istio: 1.18.0
779-
kubernetes: 25
777+
- istio: 1.20.0
778+
kubernetes: 28
779+
- istio: 1.21.0
780+
kubernetes: 28
781+
- istio: 1.22.0
782+
kubernetes: 28
783+
- istio: 1.23.0
784+
kubernetes: 28
785+
- istio: 1.24.0
786+
kubernetes: 28
780787

781788
steps:
782789
- uses: actions/checkout@v3

docker/oap/log4j2.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
</Console>
2929
</Appenders>
3030
<Loggers>
31-
<Root level="INFO">
31+
<Root level="DEBUG">
3232
<AppenderRef ref="Console"/>
3333
</Root>
3434
</Loggers>

docs/en/changes/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* Add max query size settings to BanyanDB.
2020
* Fix "BanyanDBTraceQueryDAO.queryBasicTraces" doesn't support querying by "trace_id".
2121
* Polish mesh data dispatcher: don't generate Instance/Endpoint metrics if they are empty.
22+
* Adapt the new metadata standardization in Istio 1.24.
2223

2324
#### UI
2425

oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/FieldsHelper.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.HashMap;
3939
import java.util.List;
4040
import java.util.Map;
41+
import java.util.TreeMap;
4142
import java.util.concurrent.ConcurrentHashMap;
4243
import java.util.function.BiConsumer;
4344
import java.util.regex.Matcher;
@@ -166,7 +167,7 @@ public void init(final InputStream inputStream) {
166167
public void inflate(final Struct metadata, final Object target) {
167168
final Value empty = Value.newBuilder().setStringValue("-").build();
168169
final Value root = Value.newBuilder().setStructValue(metadata).build();
169-
for (final Map.Entry<String, FieldFormat> entry : fieldNameMapping.entrySet()) {
170+
for (final var entry : fieldNameMapping.entrySet()) {
170171
final FieldFormat fieldFormat = entry.getValue();
171172
final Object[] values = new String[fieldFormat.properties.size()];
172173
for (int i = 0; i < fieldFormat.properties.size(); i++) {
@@ -175,7 +176,9 @@ public void inflate(final Struct metadata, final Object target) {
175176
for (final Field field : property) {
176177
Value value = root;
177178
for (final String segment : field.dsvSegments) {
178-
value = value.getStructValue().getFieldsOrDefault(segment, empty);
179+
final var fieldMaps = new TreeMap<String, Value>(String.CASE_INSENSITIVE_ORDER);
180+
fieldMaps.putAll(value.getStructValue().getFieldsMap());
181+
value = fieldMaps.getOrDefault(segment, empty);
179182
}
180183
if (Strings.isNullOrEmpty(value.getStringValue()) || "-".equals(value.getStringValue())) {
181184
continue;

oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/MetaExchangeALSHTTPAnalyzer.java

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,30 @@
1818

1919
package org.apache.skywalking.oap.server.receiver.envoy.als.mx;
2020

21-
import com.google.protobuf.Any;
22-
import com.google.protobuf.TextFormat;
23-
import io.envoyproxy.envoy.data.accesslog.v3.HTTPAccessLogEntry;
24-
import io.envoyproxy.envoy.service.accesslog.v3.StreamAccessLogsMessage;
25-
import lombok.extern.slf4j.Slf4j;
21+
import static org.apache.skywalking.oap.server.core.Const.TLS_MODE.NON_TLS;
22+
23+
import java.util.Base64;
24+
import java.util.Map;
25+
import java.util.concurrent.atomic.AtomicBoolean;
26+
2627
import org.apache.skywalking.apm.network.servicemesh.v3.HTTPServiceMeshMetric;
28+
import org.apache.skywalking.apm.network.servicemesh.v3.HTTPServiceMeshMetrics.Builder;
2729
import org.apache.skywalking.oap.server.library.module.ModuleManager;
2830
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
2931
import org.apache.skywalking.oap.server.library.util.FieldsHelper;
3032
import org.apache.skywalking.oap.server.receiver.envoy.EnvoyMetricReceiverConfig;
3133
import org.apache.skywalking.oap.server.receiver.envoy.als.AbstractALSAnalyzer;
34+
import org.apache.skywalking.oap.server.receiver.envoy.als.AccessLogAnalyzer.Result.ResultBuilder;
3235
import org.apache.skywalking.oap.server.receiver.envoy.als.Role;
3336
import org.apache.skywalking.oap.server.receiver.envoy.als.ServiceMetaInfo;
3437

35-
import java.util.Base64;
36-
import java.util.concurrent.atomic.AtomicBoolean;
38+
import com.google.protobuf.Any;
39+
import com.google.protobuf.Struct;
40+
import com.google.protobuf.TextFormat;
3741

38-
import static org.apache.skywalking.oap.server.core.Const.TLS_MODE.NON_TLS;
42+
import io.envoyproxy.envoy.data.accesslog.v3.HTTPAccessLogEntry;
43+
import io.envoyproxy.envoy.service.accesslog.v3.StreamAccessLogsMessage;
44+
import lombok.extern.slf4j.Slf4j;
3945

4046
@Slf4j
4147
public class MetaExchangeALSHTTPAnalyzer extends AbstractALSAnalyzer {
@@ -44,6 +50,10 @@ public class MetaExchangeALSHTTPAnalyzer extends AbstractALSAnalyzer {
4450

4551
public static final String DOWNSTREAM_KEY = "wasm.downstream_peer";
4652

53+
public static final String UPSTREAM_PEER = "upstream_peer";
54+
55+
public static final String DOWNSTREAM_PEER = "downstream_peer";
56+
4757
protected String fieldMappingFile = "metadata-service-mapping.yaml";
4858

4959
protected EnvoyMetricReceiverConfig config;
@@ -86,13 +96,34 @@ public Result analysis(
8696
final var properties = entry.getCommonProperties();
8797
final var stateMap = properties.getFilterStateObjectsMap();
8898
final var result = previousResult.toBuilder();
99+
if (log.isDebugEnabled()) {
100+
log.debug("Filter state object map: {}", stateMap);
101+
}
89102
if (stateMap.isEmpty()) {
90103
return result.service(currSvc).build();
91104
}
92105

93106
final var previousMetrics = previousResult.getMetrics();
94107
final var httpMetrics = previousMetrics.getHttpMetricsBuilder();
95108
final var downstreamExists = new AtomicBoolean();
109+
parseFilterObject(previousResult, entry, role, currSvc, stateMap, result, httpMetrics, downstreamExists);
110+
parseFilterObjectPrior124(previousResult, entry, role, currSvc, stateMap, result, httpMetrics, downstreamExists);
111+
if (role.equals(Role.PROXY) && !downstreamExists.get()) {
112+
final var metric = newAdapter(entry, config.serviceMetaInfoFactory().unknown(), currSvc).adaptToDownstreamMetrics();
113+
if (log.isDebugEnabled()) {
114+
log.debug("Transformed a {} inbound mesh metric {}", role, TextFormat.shortDebugString(metric));
115+
}
116+
httpMetrics.addMetrics(metric);
117+
result.hasDownstreamMetrics(true);
118+
}
119+
return result.metrics(previousMetrics.setHttpMetrics(httpMetrics)).service(currSvc).build();
120+
}
121+
122+
// TODO: remove this when 1.24.0 is our minimum supported version.
123+
@Deprecated(forRemoval = true)
124+
private void parseFilterObjectPrior124(final Result previousResult, final HTTPAccessLogEntry entry, final Role role,
125+
final ServiceMetaInfo currSvc, final Map<String, Any> stateMap, final ResultBuilder result,
126+
final Builder httpMetrics, final AtomicBoolean downstreamExists) {
96127
stateMap.forEach((key, value) -> {
97128
if (!key.equals(UPSTREAM_KEY) && !key.equals(DOWNSTREAM_KEY)) {
98129
return;
@@ -131,21 +162,63 @@ public Result analysis(
131162
break;
132163
}
133164
});
134-
if (role.equals(Role.PROXY) && !downstreamExists.get()) {
135-
final var metric = newAdapter(entry, config.serviceMetaInfoFactory().unknown(), currSvc).adaptToDownstreamMetrics();
165+
}
166+
167+
private void parseFilterObject(final Result previousResult, final HTTPAccessLogEntry entry, final Role role,
168+
final ServiceMetaInfo currSvc, final Map<String, Any> stateMap, final ResultBuilder result,
169+
final Builder httpMetrics, final AtomicBoolean downstreamExists) {
170+
stateMap.forEach((key, value) -> {
171+
if (!key.equals(UPSTREAM_PEER) && !key.equals(DOWNSTREAM_PEER)) {
172+
return;
173+
}
136174
if (log.isDebugEnabled()) {
137-
log.debug("Transformed a {} inbound mesh metric {}", role, TextFormat.shortDebugString(metric));
175+
log.debug("Filter state object key: {}, value: {}", key, value);
138176
}
139-
httpMetrics.addMetrics(metric);
140-
result.hasDownstreamMetrics(true);
141-
}
142-
return result.metrics(previousMetrics.setHttpMetrics(httpMetrics)).service(currSvc).build();
177+
final ServiceMetaInfo svc;
178+
try {
179+
log.debug("Filter state object value map: {}", value.unpack(Struct.class).getFieldsMap());
180+
svc = adaptToServiceMetaInfo(value.unpack(Struct.class));
181+
} catch (Exception e) {
182+
log.error("Fail to parse metadata {} to FlatNode", Base64.getEncoder().encode(value.toByteArray()));
183+
return;
184+
}
185+
final HTTPServiceMeshMetric.Builder metrics;
186+
switch (key) {
187+
case UPSTREAM_PEER:
188+
if (previousResult.hasUpstreamMetrics()) {
189+
break;
190+
}
191+
metrics = newAdapter(entry, currSvc, svc).adaptToUpstreamMetrics().setTlsMode(NON_TLS);
192+
if (log.isDebugEnabled()) {
193+
log.debug("Transformed a {} outbound mesh metrics {}", role, TextFormat.shortDebugString(metrics));
194+
}
195+
httpMetrics.addMetrics(metrics);
196+
result.hasUpstreamMetrics(true);
197+
break;
198+
case DOWNSTREAM_PEER:
199+
if (previousResult.hasDownstreamMetrics()) {
200+
break;
201+
}
202+
metrics = newAdapter(entry, svc, currSvc).adaptToDownstreamMetrics();
203+
if (log.isDebugEnabled()) {
204+
log.debug("Transformed a {} inbound mesh metrics {}", role, TextFormat.shortDebugString(metrics));
205+
}
206+
httpMetrics.addMetrics(metrics);
207+
downstreamExists.set(true);
208+
result.hasDownstreamMetrics(true);
209+
break;
210+
}
211+
});
143212
}
144213

145214
protected ServiceMetaInfo adaptToServiceMetaInfo(final Any value) throws Exception {
146215
return new ServiceMetaInfoAdapter(value);
147216
}
148217

218+
protected ServiceMetaInfo adaptToServiceMetaInfo(final Struct struct) throws Exception {
219+
return config.serviceMetaInfoFactory().fromStruct(struct);
220+
}
221+
149222
protected ServiceMetaInfo adaptToServiceMetaInfo(final StreamAccessLogsMessage.Identifier identifier) throws Exception {
150223
return config.serviceMetaInfoFactory().fromStruct(identifier.getNode().getMetadata());
151224
}

oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/ServiceMetaInfoAdapter.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.TreeMap;
3233

3334
import lombok.RequiredArgsConstructor;
3435
import lombok.extern.slf4j.Slf4j;
@@ -65,6 +66,9 @@ public ServiceMetaInfoAdapter(final ByteString bv) throws Exception {
6566
}
6667

6768
final Struct metadata = requireNonNull(extractStructFromNodeFlatBuffer(flatNode));
69+
if (log.isDebugEnabled()) {
70+
log.debug("Node metadata: {}", metadata);
71+
}
6872
FieldsHelper.forClass(this.getClass().getSuperclass()).inflate(metadata, this);
6973
appendTags(metadata);
7074
}
@@ -111,17 +115,27 @@ public static Struct extractStructFromNodeFlatBuffer(final FlatNode node) {
111115
public ServiceMetaInfoAdapter(final Struct metadata) {
112116
FieldsHelper.forClass(this.getClass().getSuperclass()).inflate(requireNonNull(metadata), this);
113117
appendTags(requireNonNull(metadata));
118+
if (log.isDebugEnabled()) {
119+
log.info("Metadata is converted to: {}", this);
120+
}
114121
}
115122

116123
private void appendTags(Struct metadata) {
117-
final Map<String, Value> fieldsMap = metadata.getFieldsMap();
124+
final Map<String, Value> fieldsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
125+
fieldsMap.putAll(metadata.getFieldsMap());
126+
if (log.isDebugEnabled()) {
127+
log.debug("Metadata field map: {}", fieldsMap);
128+
}
118129
final List<KeyValue> tags = new ArrayList<>();
119130
if (fieldsMap.containsKey("NAME")) {
120131
tags.add(new KeyValue("pod", fieldsMap.get("NAME").getStringValue()));
121132
}
122133
if (fieldsMap.containsKey("NAMESPACE")) {
123134
tags.add(new KeyValue("namespace", fieldsMap.get("NAMESPACE").getStringValue()));
124135
}
136+
if (log.isDebugEnabled()) {
137+
log.debug("Converted tags: {}", tags);
138+
}
125139
if (!tags.isEmpty()) {
126140
this.setTags(tags);
127141
}

0 commit comments

Comments
 (0)