Support segment status based on entry/first span only (#5416)
This commit is contained in:
parent
35264e6171
commit
4f1dab7003
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Reference in New Issue