You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/05/12 22:53:31 UTC
[skywalking] branch master updated: Allow multiple definitions as
fallback in metadata-service-mapping.yaml file (#6933)
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 85a993f Allow multiple definitions as fallback in metadata-service-mapping.yaml file (#6933)
85a993f is described below
commit 85a993faf5f09a88ba3a640c4e3b4284a5e64b47
Author: Zhenxu Ke <ke...@apache.org>
AuthorDate: Thu May 13 06:53:05 2021 +0800
Allow multiple definitions as fallback in metadata-service-mapping.yaml file (#6933)
---
CHANGES.md | 1 +
.../main/resources/metadata-service-mapping.yaml | 2 +-
.../server/core/query/MetadataQueryService.java | 3 +-
.../server/receiver/envoy/als/mx/FieldsHelper.java | 84 ++++++++++++++--------
.../receiver/envoy/als/mx/FieldsHelperTest.java | 10 +++
5 files changed, 69 insertions(+), 31 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 6091d64..e209ae1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -40,6 +40,7 @@ Release Notes.
* Support analyzing Envoy TCP access logs and persist error TCP logs.
* Fix: Envoy error logs are not persisted when no metrics are generated
* Fix: Memory leakage of low version etcd client. [fix-issue](https://github.com/jurmous/etcd4j/pull/185)
+* Allow multiple definitions as fallback in metadata-service-mapping.yaml file.
#### UI
* Add logo for kong plugin.
diff --git a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml b/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
index 941ece6..7737432 100644
--- a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
+++ b/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
@@ -13,5 +13,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-serviceName: ${LABELS."service.istio.io/canonical-name"}
+serviceName: ${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name",LABELS.app}
serviceInstanceName: ${NAME}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
index a5f1e8b..7f6d674 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
@@ -50,11 +50,10 @@ public class MetadataQueryService implements org.apache.skywalking.oap.server.li
public List<Service> getAllServices(final String group) throws IOException {
return getMetadataQueryDAO().getAllServices(group).stream()
- .map(service -> {
+ .peek(service -> {
if (service.getGroup() == null) {
service.setGroup(Const.EMPTY_STRING);
}
- return service;
}).collect(Collectors.toList());
}
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
index 04ad511..a615284 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
@@ -30,7 +30,9 @@ import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
+import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
@@ -39,9 +41,6 @@ import org.apache.skywalking.oap.server.receiver.envoy.als.ServiceMetaInfo;
import org.yaml.snakeyaml.Yaml;
@Slf4j
-/**
- * FieldsHelper
- */
public enum FieldsHelper {
SINGLETON;
@@ -79,30 +78,33 @@ public enum FieldsHelper {
final String serviceMetaInfoFieldName = entry.getKey();
final String flatBuffersFieldName = entry.getValue();
- final Pattern p = Pattern.compile("(\\$\\{(?<property>.+?)})");
+ final Pattern p = Pattern.compile("(\\$\\{(?<properties>.+?)})");
final Matcher m = p.matcher(flatBuffersFieldName);
- final List<List<String>> flatBuffersFieldNames = new ArrayList<>(m.groupCount());
+ final List<Property> flatBuffersFieldNames = new ArrayList<>(m.groupCount());
final StringBuffer serviceNamePattern = new StringBuffer();
while (m.find()) {
- final String property = m.group("property");
- List<String> tokens = Splitter.on('.').omitEmptyStrings().splitToList(property);
-
- StringBuilder tokenBuffer = new StringBuilder();
- List<String> compactedTokens = new ArrayList<>(tokens.size());
- for (String token : tokens) {
- if (tokenBuffer.length() == 0 && token.startsWith("\"")) {
- tokenBuffer.append(token);
- } else if (tokenBuffer.length() > 0) {
- tokenBuffer.append(".").append(token);
- if (token.endsWith("\"")) {
- compactedTokens.add(tokenBuffer.toString().replaceAll("\"", ""));
- tokenBuffer.setLength(0);
+ final String properties = m.group("properties");
+ final List<Field> fields = Splitter.on(',').omitEmptyStrings().splitToList(properties).stream().map(candidate -> {
+ List<String> tokens = Splitter.on('.').omitEmptyStrings().splitToList(candidate);
+
+ StringBuilder tokenBuffer = new StringBuilder();
+ List<String> candidateFields = new ArrayList<>(tokens.size());
+ for (String token : tokens) {
+ if (tokenBuffer.length() == 0 && token.startsWith("\"")) {
+ tokenBuffer.append(token);
+ } else if (tokenBuffer.length() > 0) {
+ tokenBuffer.append(".").append(token);
+ if (token.endsWith("\"")) {
+ candidateFields.add(tokenBuffer.toString().replaceAll("\"", ""));
+ tokenBuffer.setLength(0);
+ }
+ } else {
+ candidateFields.add(token);
}
- } else {
- compactedTokens.add(token);
}
- }
- flatBuffersFieldNames.add(compactedTokens);
+ return new Field(candidateFields);
+ }).collect(Collectors.toList());
+ flatBuffersFieldNames.add(new Property(fields));
m.appendReplacement(serviceNamePattern, "%s");
}
@@ -136,12 +138,18 @@ public enum FieldsHelper {
final ServiceNameFormat serviceNameFormat = entry.getValue();
final Object[] values = new String[serviceNameFormat.properties.size()];
for (int i = 0; i < serviceNameFormat.properties.size(); i++) {
- final List<String> properties = serviceNameFormat.properties.get(i);
- Value value = root;
- for (final String property : properties) {
- value = value.getStructValue().getFieldsOrDefault(property, empty);
+ values[i] = "-"; // Give it a default value
+ final Property property = serviceNameFormat.properties.get(i);
+ for (final Field field : property) {
+ Value value = root;
+ for (final String segment : field.dsvSegments) {
+ value = value.getStructValue().getFieldsOrDefault(segment, empty);
+ }
+ if (Strings.isNullOrEmpty(value.getStringValue()) || "-".equals(value.getStringValue())) {
+ continue;
+ }
+ values[i] = value.getStringValue();
}
- values[i] = value.getStringValue();
}
final String value = Strings.lenientFormat(serviceNameFormat.format, values);
if (!Strings.isNullOrEmpty(value)) {
@@ -154,6 +162,26 @@ public enum FieldsHelper {
private static class ServiceNameFormat {
private final String format;
- private final List<List<String>> properties;
+ private final List<Property> properties;
+ }
+
+ /**
+ * A property in the metadata map, it may have multiple candidates, of which the first is non empty will be used.
+ * For example, to look up the service name, you may set candidates like ${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name","app"}.
+ */
+ @RequiredArgsConstructor
+ private static class Property implements Iterable<Field> {
+ @Delegate
+ private final List<Field> candidateFields;
+ }
+
+ /**
+ * A field in the property, it may be nested such as LABELS.app, LABELS.revision, etc.
+ * {@link #dsvSegments} are the `.` separated segment list, such as ["LABELS", "app"], ["LABELS", "revision"].
+ */
+ @RequiredArgsConstructor
+ private static class Field implements Iterable<String> {
+ @Delegate
+ private final List<String> dsvSegments;
}
}
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelperTest.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelperTest.java
index 8a38c18..448b343 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelperTest.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelperTest.java
@@ -69,6 +69,16 @@ public class FieldsHelperTest {
"serviceName: fixed-${LABELS.\"service.istio.io/canonical-name\"}\nserviceInstanceName: yeah_${NAME}",
"fixed-productpage",
"yeah_productpage-v1-65576bb7bf-4mzsp"
+ },
+ {
+ "serviceName: fixed-${LABELS.\"service.istio.io/not-exist\",LABELS.\"service.istio.io/canonical-name\"}\nserviceInstanceName: yeah_${NAME}",
+ "fixed-productpage",
+ "yeah_productpage-v1-65576bb7bf-4mzsp"
+ },
+ {
+ "serviceName: fixed-${LABELS.\"service.istio.io/not-exist\",LABELS.\"service.istio.io/not-exist-2\"}\nserviceInstanceName: yeah_${NAME}",
+ "fixed--",
+ "yeah_productpage-v1-65576bb7bf-4mzsp"
}
});
}