未验证 提交 4f1dab70 编写于 作者: E Evan 提交者: GitHub

Support segment status based on entry/first span only (#5416)

上级 35264e61
......@@ -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 | - | - |
......
......@@ -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();
}
......@@ -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<String> 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<String> 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
);
}
}
......
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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);
}
/*
* 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;
}
}
/*
* 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
......@@ -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}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册