-
Notifications
You must be signed in to change notification settings - Fork 16
feat: enhance the support for dropping filter #288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
89c99cb
94223ce
0b8b269
b1cb908
ff97f35
7298d39
8b73714
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| package org.hypertrace.core.spannormalizer.jaeger; | ||
|
|
||
| public class SpanDropFilter { | ||
|
|
||
| public static final String TAG_KEY = "tagKey"; | ||
| public static final String OPERATOR = "operator"; | ||
| public static final String TAG_VALUE = "tagValue"; | ||
|
|
||
| public enum Operator { | ||
| EQ("EQ"), | ||
| NEQ("NEQ"), | ||
| EXISTS("EXISTS"), | ||
| CONTAINS("CONTAINS"); | ||
|
|
||
| private final String value; | ||
|
|
||
| Operator(String value) { | ||
| this.value = value; | ||
| } | ||
|
|
||
| public String getValue() { | ||
| return value; | ||
| } | ||
| } | ||
|
|
||
| private String tagKey; | ||
| private Operator operator; | ||
| private String tagValue; | ||
|
|
||
| public SpanDropFilter(String tagKey, String operator, String tagValue) { | ||
| this.tagKey = tagKey; | ||
| this.operator = Operator.valueOf(operator); | ||
| this.tagValue = tagValue; | ||
| } | ||
|
|
||
| public String getTagKey() { | ||
| return tagKey; | ||
| } | ||
|
|
||
| public Operator getOperator() { | ||
| return operator; | ||
| } | ||
|
|
||
| public String getTagValue() { | ||
| return tagValue; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "SpanDropFilter{" | ||
| + "tagKey='" | ||
| + tagKey | ||
| + '\'' | ||
| + ", operator=" | ||
| + operator | ||
| + ", tagValue='" | ||
| + tagValue | ||
| + '\'' | ||
| + '}'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,16 @@ | ||
| package org.hypertrace.core.spannormalizer.jaeger; | ||
|
|
||
| import static org.hypertrace.core.spannormalizer.jaeger.SpanDropFilter.OPERATOR; | ||
| import static org.hypertrace.core.spannormalizer.jaeger.SpanDropFilter.TAG_KEY; | ||
| import static org.hypertrace.core.spannormalizer.jaeger.SpanDropFilter.TAG_VALUE; | ||
|
|
||
| import com.google.common.util.concurrent.RateLimiter; | ||
| import com.typesafe.config.Config; | ||
| import com.typesafe.config.ConfigList; | ||
| import io.jaegertracing.api_v2.JaegerSpanInternalModel; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Objects; | ||
|
|
@@ -35,6 +41,8 @@ public class SpanFilter { | |
| */ | ||
| private static final String SPAN_DROP_CRITERION_CONFIG = "processor.spanDropCriterion"; | ||
|
|
||
| private static final String SPAN_DROP_FILTERS = "processor.spanDropFilters"; | ||
|
|
||
| public static final String ROOT_SPAN_DROP_CRITERION_CONFIG = | ||
| "processor.rootExitSpanDropCriterion"; | ||
| private static final String ROOT_SPAN_ALWAYS_DROP = "alwaysDrop"; | ||
|
|
@@ -44,6 +52,8 @@ public class SpanFilter { | |
| private static final String COLON = ":"; | ||
|
|
||
| private List<List<Pair<String, String>>> spanDropCriterion = Collections.emptyList(); | ||
| private List<List<SpanDropFilter>> spanDropFilters = Collections.emptyList(); | ||
| ; | ||
| private boolean alwaysDropRootSpan = false; | ||
| private List<List<Pair<String, String>>> rootSpanDropExclusionCriterion = Collections.emptyList(); | ||
|
|
||
|
|
@@ -55,6 +65,27 @@ public SpanFilter(Config config) { | |
| this.spanDropCriterion = parseStringList(criterion); | ||
| } | ||
|
|
||
| if (config.hasPath(SPAN_DROP_FILTERS)) { | ||
| ConfigList spanDropFiltersConfig = config.getList(SPAN_DROP_FILTERS); | ||
| LOG.info("Span drop filters: {}", spanDropFiltersConfig); | ||
| this.spanDropFilters = | ||
| spanDropFiltersConfig.stream() | ||
| .map( | ||
| orFilters -> { | ||
| List<HashMap<String, String>> andFilters = | ||
| (List<HashMap<String, String>>) orFilters.unwrapped(); | ||
| return andFilters.stream() | ||
| .map( | ||
| filter -> | ||
| new SpanDropFilter( | ||
| filter.get(TAG_KEY), | ||
| filter.get(OPERATOR), | ||
| filter.get(TAG_VALUE))) | ||
| .collect(Collectors.toList()); | ||
| }) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| if (config.hasPath(ROOT_SPAN_DROP_CRITERION_CONFIG)) { | ||
| Config rootSpanDropCriterionConfig = config.getConfig(ROOT_SPAN_DROP_CRITERION_CONFIG); | ||
| LOG.info("Root Span drop criterion: {}", rootSpanDropCriterionConfig); | ||
|
|
@@ -88,14 +119,23 @@ private List<List<Pair<String, String>>> parseStringList(List<String> stringList | |
| * the span should be dropped, false otherwise. | ||
| */ | ||
| public boolean shouldDropSpan( | ||
| JaegerSpanInternalModel.Span span, Map<String, JaegerSpanInternalModel.KeyValue> tags) { | ||
| JaegerSpanInternalModel.Span span, | ||
| Map<String, JaegerSpanInternalModel.KeyValue> tags, | ||
| Map<String, JaegerSpanInternalModel.KeyValue> processTags) { | ||
| if (anyCriteriaMatch(tags, spanDropCriterion)) { | ||
| if (DROPPED_SPANS_RATE_LIMITER.tryAcquire()) { | ||
| LOG.info("Dropping span: [{}] with drop criterion: [{}]", span, spanDropCriterion); | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| if (anySpanDropFiltersMatch(spanDropFilters, tags, processTags)) { | ||
| if (LOG.isDebugEnabled() && DROPPED_SPANS_RATE_LIMITER.tryAcquire()) { | ||
| LOG.debug("Dropping span: [{}] with drop filters: [{}]", span, spanDropFilters.toString()); | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| if (isRootExitSpan(span, tags)) { | ||
| boolean anyCriteriaMatch = anyCriteriaMatch(tags, rootSpanDropExclusionCriterion); | ||
| boolean shouldDropSpan = | ||
|
|
@@ -147,4 +187,37 @@ private boolean isRootExitSpan( | |
|
|
||
| return SPAN_KIND_CLIENT.equals(spanKindKeyValue.getVStr()); | ||
| } | ||
|
|
||
| private boolean anySpanDropFiltersMatch( | ||
| List<List<SpanDropFilter>> spanDropFilters, | ||
| Map<String, JaegerSpanInternalModel.KeyValue> tags, | ||
| Map<String, JaegerSpanInternalModel.KeyValue> processTags) { | ||
| return spanDropFilters.stream() | ||
| .anyMatch( | ||
| andFilters -> | ||
| andFilters.stream() | ||
| .allMatch( | ||
| filter -> | ||
| matchSpanDropFilter(filter, tags) | ||
| || matchSpanDropFilter(filter, processTags))); | ||
| } | ||
|
|
||
| private boolean matchSpanDropFilter( | ||
| SpanDropFilter filter, Map<String, JaegerSpanInternalModel.KeyValue> tags) { | ||
| switch (filter.getOperator()) { | ||
| case EQ: | ||
| return tags.containsKey(filter.getTagKey()) | ||
| && StringUtils.equals(tags.get(filter.getTagKey()).getVStr(), filter.getTagValue()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kotharironak We may have to look into the process tags too. See below
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the process tags are meant for resources, do we want to drop span based on resource criteria? So, far we are dropping based on span attribute filters, and with that, we are able to filter existing scenarios, right? Are there some scenario?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ravisingal @avinashkolluru I have added the support for processTags too. So, now the filter will check in the union of two tags ( Total Tags = |
||
| case NEQ: | ||
| return tags.containsKey(filter.getTagKey()) | ||
| && !StringUtils.equals(tags.get(filter.getTagKey()).getVStr(), filter.getTagValue()); | ||
| case CONTAINS: | ||
| return tags.containsKey(filter.getTagKey()) | ||
| && StringUtils.contains(tags.get(filter.getTagKey()).getVStr(), filter.getTagValue()); | ||
| case EXISTS: | ||
| return tags.containsKey(filter.getTagKey()); | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.