diff --git a/docs/en/setup/backend/configuration-vocabulary.md b/docs/en/setup/backend/configuration-vocabulary.md index 5ae1f3c20374902d1a755562b5b90c7d4963bc6a..b56366b41a1ef94addcbe355221c59b096df47e5 100644 --- a/docs/en/setup/backend/configuration-vocabulary.md +++ b/docs/en/setup/backend/configuration-vocabulary.md @@ -137,6 +137,7 @@ core|default|role|Option values, `Mixed/Receiver/Aggregator`. **Receiver** mode | - | -| sampleRate|Sampling rate for receiving trace. The precision is 1/10000. 10000 means 100% sample in default.|SW_TRACE_SAMPLE_RATE|10000| | - | - |slowDBAccessThreshold|The slow database access thresholds. Unit ms.|SW_SLOW_DB_THRESHOLD|default:200,mongodb:100| | - | - |forceSampleErrorSegment|When sampling mechanism activated, this config would make the error status segment sampled, ignoring the sampling rate.|SW_FORCE_SAMPLE_ERROR_SEGMENT|true| +| - | - |segmentStatusAnalysisStrategy|Determine the final segment status from the status of spans. Available values are `FROM_SPAN_STATUS` , `FROM_ENTRY_SPAN` and `FROM_FIRST_SPAN`. `FROM_SPAN_STATUS` represents the segment status would be error if any span is in error status. `FROM_ENTRY_SPAN` means the segment status would be determined by the status of entry spans only. `FROM_FIRST_SPAN` means the segment status would be determined by the status of the first span only.|SW_SEGMENT_STATUS_ANALYSIS_STRATEGY|FROM_SPAN_STATUS| | receiver-sharing-server|default| Sharing server provides new gRPC and restful servers for data collection. Ana make the servers in the core module working for internal communication only.| - | - | | - | - | restHost| Binding IP of restful service. Services include GraphQL query and HTTP data report| - | - | | - | - | restPort | Binding port of restful service | - | - | diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/AnalyzerModuleConfig.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/AnalyzerModuleConfig.java index 4a658d02436a89eba2f5e224500a9c437b1f1ddd..7fe30f2330f1bc2db868253196bae68fbe9b71b9 100644 --- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/AnalyzerModuleConfig.java +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/AnalyzerModuleConfig.java @@ -25,8 +25,11 @@ import lombok.Setter; import org.apache.skywalking.oap.server.analyzer.provider.trace.DBLatencyThresholdsAndWatcher; import org.apache.skywalking.oap.server.analyzer.provider.trace.TraceSampleRateWatcher; import org.apache.skywalking.oap.server.analyzer.provider.trace.UninstrumentedGatewaysConfig; +import org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy; import org.apache.skywalking.oap.server.library.module.ModuleConfig; +import static org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy.FROM_SPAN_STATUS; + public class AnalyzerModuleConfig extends ModuleConfig { /** * The sample rate precision is 1/10000. 10000 means 100% sample in default. @@ -80,9 +83,19 @@ public class AnalyzerModuleConfig extends ModuleConfig { private final String configPath = "meter-receive-config"; /** - * Sample the trace segment if the segment has span(s) tagged as error status, and ignore the sampleRate configuration. + * Sample the trace segment if the segment has span(s) tagged as error status, and ignore the sampleRate + * configuration. */ @Setter @Getter private boolean forceSampleErrorSegment = true; + + /** + * Determine the final segment status from the status of spans. + * + * @see SegmentStatusStrategy + */ + @Setter + @Getter + private String segmentStatusAnalysisStrategy = FROM_SPAN_STATUS.name(); } diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SegmentAnalysisListener.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SegmentAnalysisListener.java index d46b42709b9053bdb7514c5e34b59a4b6d9d23f7..f5d4214352930fdaad566c7ebb19f5b2a95207ee 100644 --- a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SegmentAnalysisListener.java +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/SegmentAnalysisListener.java @@ -26,6 +26,8 @@ import org.apache.skywalking.apm.network.language.agent.v3.SegmentObject; import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; import org.apache.skywalking.apm.util.StringUtil; import org.apache.skywalking.oap.server.analyzer.provider.AnalyzerModuleConfig; +import org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy; +import org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusAnalyzer; import org.apache.skywalking.oap.server.core.Const; import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.analysis.IDManager; @@ -50,6 +52,7 @@ public class SegmentAnalysisListener implements FirstAnalysisListener, EntryAnal private final boolean forceSampleErrorSegment; private final NamingControl namingControl; private final List searchableTagKeys; + private final SegmentStatusAnalyzer segmentStatusAnalyzer; private final Segment segment = new Segment(); private SAMPLE_STATUS sampleStatus = SAMPLE_STATUS.UNKNOWN; @@ -134,10 +137,7 @@ public class SegmentAnalysisListener implements FirstAnalysisListener, EntryAnal if (span.getEndTime() > endTimestamp) { endTimestamp = span.getEndTime(); } - if (!isError && span.getIsError()) { - isError = true; - } - + isError = isError || segmentStatusAnalyzer.isError(span); appendSearchableTags(span); }); final long accurateDuration = endTimestamp - startTimestamp; @@ -188,6 +188,7 @@ public class SegmentAnalysisListener implements FirstAnalysisListener, EntryAnal private final boolean forceSampleErrorSegment; private final NamingControl namingControl; private final List searchTagKeys; + private final SegmentStatusAnalyzer segmentStatusAnalyzer; public Factory(ModuleManager moduleManager, AnalyzerModuleConfig config) { this.sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class); @@ -200,6 +201,8 @@ public class SegmentAnalysisListener implements FirstAnalysisListener, EntryAnal this.namingControl = moduleManager.find(CoreModule.NAME) .provider() .getService(NamingControl.class); + this.segmentStatusAnalyzer = SegmentStatusStrategy.findByName(config.getSegmentStatusAnalysisStrategy()) + .getExceptionAnalyzer(); } @Override @@ -209,7 +212,8 @@ public class SegmentAnalysisListener implements FirstAnalysisListener, EntryAnal sampler, forceSampleErrorSegment, namingControl, - searchTagKeys + searchTagKeys, + segmentStatusAnalyzer ); } } diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromEntrySpan.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromEntrySpan.java new file mode 100644 index 0000000000000000000000000000000000000000..b7ac4d2b8e126b5ebb37856850756c7075711128 --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromEntrySpan.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; +import org.apache.skywalking.apm.network.language.agent.v3.SpanType; + +/** + * FromEntrySpan means the status of the segment is the same as the status of the entry span. If the entry span does not + * exist, the final state of the segment is successful. + */ +public class FromEntrySpan implements SegmentStatusAnalyzer { + + @Override + public boolean isError(final SpanObject spanObject) { + return spanObject.getSpanType().equals(SpanType.Entry) && spanObject.getIsError(); + } +} diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromFirstSpan.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromFirstSpan.java new file mode 100644 index 0000000000000000000000000000000000000000..dc099b4bd8839be91fbc27344b8cd869d0e461a1 --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromFirstSpan.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; + +/** + * FromFirstSpan means the status of the segment is the same as the status of the first span. Mostly, the first span is + * an entry span. However, a tracing caused by a scheduled task, the first one should be a local span. + */ +public class FromFirstSpan implements SegmentStatusAnalyzer { + + @Override + public boolean isError(final SpanObject spanObject) { + return spanObject.getSpanId() == 0 && spanObject.getIsError(); + } +} diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromSpanStatus.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromSpanStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..683738af52e6cb02882e4c8c6911882264e8f93d --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/FromSpanStatus.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; + +/** + * If the status of any span is an error, the status of the segment would be an error. + */ +public class FromSpanStatus implements SegmentStatusAnalyzer { + + @Override + public boolean isError(final SpanObject spanObject) { + return spanObject.getIsError(); + } +} diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzer.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzer.java new file mode 100644 index 0000000000000000000000000000000000000000..b205e831e98e61936cef4b088db1bef5fd345127 --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzer.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; + +/** + * The SegmentStatusAnalyzer implementations provide different strategies for determining the segment status from the + * status of spans. + */ +public interface SegmentStatusAnalyzer { + /** + * @return false, if the status of the given status represents the fatal status of the whole segment based on the strategy + */ + boolean isError(SpanObject spanObject); +} diff --git a/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusStrategy.java b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..aed77e4f5d1a48479e147f4c19e2aa277df48d19 --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/main/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusStrategy.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Define the available strategies for analysis segment status analysis. + */ +@AllArgsConstructor +public enum SegmentStatusStrategy { + /** + * `FROM_SPAN_STATUS` represents the segment status would be error if any span is in error status. + */ + FROM_SPAN_STATUS(new FromSpanStatus()), + /** + * `FROM_ENTRY_SPAN` means the segment status would be determined by the status of entry spans only. + * + * @see FromEntrySpan + */ + FROM_ENTRY_SPAN(new FromEntrySpan()), + /** + * `FROM_FIRST_SPAN` means the segment status would be determined by the status of the first span only. + */ + FROM_FIRST_SPAN(new FromFirstSpan()); + + @Getter + private final SegmentStatusAnalyzer exceptionAnalyzer; + + public static SegmentStatusStrategy findByName(String name) { + for (final SegmentStatusStrategy strategy : SegmentStatusStrategy.values()) { + if (strategy.name().equalsIgnoreCase(name)) { + return strategy; + } + } + return FROM_SPAN_STATUS; + } +} diff --git a/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzerTest.java b/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b4b4537686b37022d04b753d5cb3f5c12fd15a7a --- /dev/null +++ b/oap-server/analyzer/agent-analyzer/src/test/java/org/apache/skywalking/oap/server/analyzer/provider/trace/parser/listener/strategy/SegmentStatusAnalyzerTest.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy; + +import org.apache.skywalking.apm.network.language.agent.v3.SpanObject; +import org.apache.skywalking.apm.network.language.agent.v3.SpanType; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy.FROM_ENTRY_SPAN; +import static org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy.FROM_FIRST_SPAN; +import static org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.strategy.SegmentStatusStrategy.FROM_SPAN_STATUS; + +public class SegmentStatusAnalyzerTest { + + private SpanObject entryErrorSpan; + private SpanObject entryNormalSpan; + private SpanObject localFirstSpan; + private SpanObject localErrorSpan; + + @Before + public void prepare() { + entryErrorSpan = SpanObject.newBuilder().setIsError(true).setSpanType(SpanType.Entry).setSpanId(0).build(); + entryNormalSpan = SpanObject.newBuilder().setIsError(false).setSpanType(SpanType.Entry).setSpanId(0).build(); + localErrorSpan = SpanObject.newBuilder().setIsError(true).setSpanType(SpanType.Local).setSpanId(1).build(); + localFirstSpan = SpanObject.newBuilder().setIsError(true).setSpanType(SpanType.Local).setSpanId(0).build(); + } + + @Test + public void fromSpanStatus() { + SegmentStatusAnalyzer exceptionAnalyzer = FROM_SPAN_STATUS.getExceptionAnalyzer(); + Assert.assertTrue(exceptionAnalyzer.isError(entryErrorSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(entryNormalSpan)); + Assert.assertTrue(exceptionAnalyzer.isError(localErrorSpan)); + Assert.assertTrue(exceptionAnalyzer.isError(localFirstSpan)); + } + + @Test + public void fromEntrySpan() { + SegmentStatusAnalyzer exceptionAnalyzer = FROM_ENTRY_SPAN.getExceptionAnalyzer(); + Assert.assertTrue(exceptionAnalyzer.isError(entryErrorSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(entryNormalSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(localErrorSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(localFirstSpan)); + } + + @Test + public void fromFirstSpan() { + SegmentStatusAnalyzer exceptionAnalyzer = FROM_FIRST_SPAN.getExceptionAnalyzer(); + Assert.assertTrue(exceptionAnalyzer.isError(entryErrorSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(entryNormalSpan)); + Assert.assertFalse(exceptionAnalyzer.isError(localErrorSpan)); + Assert.assertTrue(exceptionAnalyzer.isError(localFirstSpan)); + } +} \ No newline at end of file diff --git a/oap-server/server-bootstrap/src/main/resources/application.yml b/oap-server/server-bootstrap/src/main/resources/application.yml index 2dbf1121070165d68a9daf35b6dc1d203d86fce2..e48e487a72beec2e011474284c22124cb9824cc7 100755 --- a/oap-server/server-bootstrap/src/main/resources/application.yml +++ b/oap-server/server-bootstrap/src/main/resources/application.yml @@ -180,6 +180,7 @@ agent-analyzer: sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default. slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms. forceSampleErrorSegment: ${SW_FORCE_SAMPLE_ERROR_SEGMENT:true} # When sampling mechanism active, this config can open(true) force save some error segment. true is default. + segmentStatusAnalysisStrategy: ${SW_SEGMENT_STATUS_ANALYSIS_STRATEGY:FROM_SPAN_STATUS} # Determine the final segment status from the status of spans. Available values are `FROM_SPAN_STATUS` , `FROM_ENTRY_SPAN` and `FROM_FIRST_SPAN`. `FROM_SPAN_STATUS` represents the segment status would be error if any span is in error status. `FROM_ENTRY_SPAN` means the segment status would be determined by the status of entry spans only. `FROM_FIRST_SPAN` means the segment status would be determined by the status of the first span only. receiver-sharing-server: selector: ${SW_RECEIVER_SHARING_SERVER:default}