-
Notifications
You must be signed in to change notification settings - Fork 463
Add trace filter support, custom headers and improve opentelemetry #2435
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
base: master
Are you sure you want to change the base?
Conversation
WalkthroughThis pull request enhances OpenTelemetry support in Apache Synapse with trace filtering capabilities, Axis2 MessageContext integration throughout the telemetry pipeline, custom span properties, and error tracking. Changes span data models, event handlers, span management, and configuration infrastructure to enable fine-grained filtering of telemetry data and enrich span attributes with custom properties. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (7)
modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java (1)
148-150: LGTM! Consider adding a disable constant for completeness.The constants follow existing naming conventions. For consistency with
TRACE_DISABLEandSTATISTICS_DISABLE, you may want to addTRACE_FILTER_DISABLE = "disable"for future use, though this is optional.modules/core/src/main/java/org/apache/synapse/aspects/AspectConfiguration.java (1)
125-135: Consider adding guard checks for consistency.The existing
enableStatistics()anddisableStatistics()methods include guards (if (!statisticsEnable)/if (statisticsEnable)) to avoid redundant assignments. The new trace filter methods don't follow this pattern. While functionally correct, adding guards would maintain consistency.public void enableTraceFilter() { - this.traceFilterEnable = true; + if (!traceFilterEnable) { + this.traceFilterEnable = true; + } } public void disableTraceFilter() { - this.traceFilterEnable = false; + if (traceFilterEnable) { + this.traceFilterEnable = false; + } }modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/SpanTagger.java (1)
162-241: Axis2 overload has asymmetric feature set compared to Synapse version.This method omits context property/variable map collection and endpoint attributes present in the Synapse
MessageContextoverload, but adds error code/message handling (lines 224-232). If this asymmetry is intentional (due to Axis2 context limitations), consider adding the error code/message handling to the Synapse version as well for consistency.Consider adding error code/message handling to the Synapse
MessageContextversion:if (spanWrapper.getCloseEventStatisticDataUnit() != null) { if (spanWrapper.getCloseEventStatisticDataUnit().getCustomProperties() != null) { spanWrapper.getCloseEventStatisticDataUnit().getCustomProperties().forEach( (key, value) -> span.setAttribute(key, String.valueOf(value)) ); } + if (spanWrapper.getCloseEventStatisticDataUnit().getErrorCode() != null) { + span.setAttribute(TelemetryConstants.ERROR_CODE_ATTRIBUTE_KEY, + spanWrapper.getCloseEventStatisticDataUnit().getErrorCode()); + } + if (spanWrapper.getCloseEventStatisticDataUnit().getErrorMessage() != null) { + span.setAttribute(TelemetryConstants.ERROR_MESSAGE_ATTRIBUTE_KEY, + spanWrapper.getCloseEventStatisticDataUnit().getErrorMessage()); + } }modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/scoping/TracingScopeManager.java (1)
62-82: Consider null-safety for tracingScopeId.The Axis2 overload correctly mirrors the Synapse version. However, if
FLOW_STATISTICS_IDis not set on the MessageContext,extractTracingScopeIdreturnsnull, which could lead to storing/retrieving scopes with a null key.Consider adding a null check:
public TracingScope getTracingScope(org.apache.axis2.context.MessageContext msgCtx) { synchronized (tracingScopes) { String tracingScopeId = extractTracingScopeId(msgCtx); + if (tracingScopeId == null) { + return null; // or throw an exception/log a warning + } if (tracingScopes.containsKey(tracingScopeId)) {This would also be beneficial for the existing Synapse
MessageContextoverload.modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/TelemetryConstants.java (1)
91-93: Consider usingOTELprefix instead ofOLTP.The constants use
OLTPprefix (e.g.,oltp.custom.span.header.tags), but OpenTelemetry is typically abbreviated asOTEL. UnlessOLTPis an established convention in this codebase, consider renaming for consistency with OpenTelemetry naming conventions:- public static final String OLTP_CUSTOM_SPAN_TAGS = "oltp.custom.span.header.tags"; + public static final String OTEL_CUSTOM_SPAN_TAGS = "otel.custom.span.header.tags"; - public static final String OLTP_FILTERED_MEDIATOR_NAMES = "oltp.filtered.mediator.names"; + public static final String OTEL_FILTERED_MEDIATOR_NAMES = "otel.filtered.mediator.names";modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/event/CloseEventHandler.java (1)
51-58: Consider adding missing Axis2 overloads for completeness.The interface adds Axis2 overloads for
handleCloseEntryEvent,handleCloseFlowForcefully, andhandleCloseEntryWithErrorEvent, but not forhandleTryEndFlowandhandleScatterGatherFinishEvent. If Axis2 context support is needed for those operations in the future, this inconsistency may cause issues.Verify whether
handleTryEndFlowandhandleScatterGatherFinishEventneed Axis2 overloads for complete Dataservices OpenTelemetry support.Also applies to: 81-88
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java (1)
252-279: Significant code duplication in custom span tags logic.The custom span tags extraction logic is duplicated between the Synapse
startSpan(lines 255-279) and Axis2startSpan(lines 355-378). Consider extracting to a shared helper method.Extract to a private helper method:
private void extractAndSetCustomSpanTags(Map headersMap, StatisticDataUnit statisticDataUnit, Object msgContext, boolean isSynapseContext) { Object prevCustomSpanTagsObj = isSynapseContext ? ((MessageContext) msgContext).getProperty(TelemetryConstants.OLTP_CUSTOM_SPAN_TAGS) : ((org.apache.axis2.context.MessageContext) msgContext).getProperty(TelemetryConstants.OLTP_CUSTOM_SPAN_TAGS); // ... rest of shared logic }Also applies to: 355-378
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
modules/core/src/main/java/org/apache/synapse/SynapseConstants.java(1 hunks)modules/core/src/main/java/org/apache/synapse/aspects/AspectConfiguration.java(2 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/collectors/OpenEventCollector.java(5 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/collectors/RuntimeStatisticCollector.java(5 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/BasicStatisticDataUnit.java(3 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/StatisticDataUnit.java(3 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/StatisticsLog.java(3 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/TelemetryConstants.java(1 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/event/CloseEventHandler.java(2 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/event/OpenEventHandler.java(1 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java(11 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/SpanTagger.java(1 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/scoping/TracingScopeManager.java(2 hunks)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/stores/SpanStore.java(3 hunks)modules/core/src/main/java/org/apache/synapse/config/xml/AbstractMediatorFactory.java(1 hunks)modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java(1 hunks)modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2SynapseEnvironment.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/SpanTagger.java (2)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/OpenTelemetryManagerHolder.java (1)
OpenTelemetryManagerHolder(31-87)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/TelemetryConstants.java (1)
TelemetryConstants(21-94)
modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2SynapseEnvironment.java (1)
modules/core/src/main/java/org/apache/synapse/SynapseConstants.java (1)
SynapseConstants(30-745)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/stores/SpanStore.java (2)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/TracingUtils.java (1)
TracingUtils(28-65)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/SpanTagger.java (1)
SpanTagger(33-242)
modules/core/src/main/java/org/apache/synapse/config/xml/AbstractMediatorFactory.java (1)
modules/core/src/main/java/org/apache/synapse/config/xml/XMLConfigConstants.java (1)
XMLConfigConstants(30-151)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java (3)
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/TelemetryConstants.java (1)
TelemetryConstants(21-94)modules/core/src/main/java/org/apache/synapse/config/SynapsePropertiesLoader.java (1)
SynapsePropertiesLoader(32-119)modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/TracingUtils.java (1)
TracingUtils(28-65)
🔇 Additional comments (18)
modules/core/src/main/java/org/apache/synapse/config/xml/AbstractMediatorFactory.java (1)
186-196: LGTM! Trace filter attribute handling follows existing patterns.The implementation correctly mirrors the existing patterns for
traceandstatisticsattribute handling, maintaining consistency in the codebase.modules/core/src/main/java/org/apache/synapse/SynapseConstants.java (1)
743-744: LGTM!The new constant follows existing naming conventions and is appropriately placed with related constants.
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/StatisticsLog.java (1)
173-174: LGTM!The
customPropertiesfield follows the existing pattern for other map fields likecontextPropertyMapandtransportPropertyMap, with proper initialization in the constructor and a getter method.Also applies to: 206-206, 434-437
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/collectors/OpenEventCollector.java (3)
105-110: LGTM! Filtering logic is correctly applied.The trace filtering logic properly skips OpenTelemetry handling when the mediator is in the filtered list or when trace filtering is explicitly enabled on the component.
139-144: Consistent filtering applied across event methods.The filtering logic is consistently applied across
reportChildEntryEvent,reportFlowContinuableEvent,reportFlowSplittingEvent, andreportFlowAggregateEvent, maintaining uniform behavior for trace filtering.Also applies to: 175-180, 212-217, 248-253
266-281: Verify:reportFlowAsynchronousEventlacks trace filtering.Unlike other event reporting methods in this class,
reportFlowAsynchronousEventdoes not include anisFilteredcheck before calling the OpenTelemetry handler. Confirm whether this omission is intentional for asynchronous events or represents an inconsistency that should be addressed.modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/BasicStatisticDataUnit.java (1)
71-75: LGTM! The newcustomPropertiesfield follows existing patterns.The addition of
customPropertieswith getter/setter is consistent with other fields in this data carrier class (e.g.,elasticMetadata,messageContext). The field appropriately allows null values and follows the same mutable reference pattern used throughout the class.Also applies to: 139-146
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/helpers/SpanTagger.java (1)
140-152: LGTM! Custom properties propagation for Synapse MessageContext.The addition correctly exports custom properties from both open and close event data units as span attributes, ensuring complete property propagation.
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/collectors/RuntimeStatisticCollector.java (3)
145-159: LGTM! Mediator span filter initialization is well-implemented.The initialization correctly:
- Guards against null/empty configuration values
- Uses stream API for clean parsing
- Normalizes to lowercase for case-insensitive matching
- Logs the filter list at debug level
181-193: LGTM! Axis2 MessageContext overload provides necessary compatibility.The method correctly mirrors the Synapse
MessageContextversion for setting trace IDs in Axis2 contexts.
286-297: LGTM! Filter check is correctly implemented.The method safely handles:
- Null
componentNamevia early check- Component names without colons (
split(":")[0]returns original string)- Case-insensitive matching via lowercase normalization
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/scoping/TracingScopeManager.java (1)
94-102: LGTM! Axis2 context ID extraction is consistent with existing pattern.The overloaded method correctly extracts the tracing scope ID from the Axis2 MessageContext using the same property key.
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/event/OpenEventHandler.java (1)
37-43: Interface extension requires implementations to be updated.The new Axis2 MessageContext overload is appropriate for enabling Axis2-based tracing. Verify that all classes implementing
OpenEventHandlerhave been updated to implement this new method signature.modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/TelemetryConstants.java (1)
85-86: LGTM!The error attribute constants follow OpenTelemetry semantic conventions for error tracking (
error.code,error.message).modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/event/CloseEventHandler.java (1)
35-42: LGTM!The new Axis2 MessageContext overloads maintain consistency with existing method signatures and Javadoc style.
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/StatisticDataUnit.java (2)
82-86: LGTM!The new fields (
componentTypeString,errorCode,errorMessage,isOuterLayerSpan) are well-structured and follow the existing patterns in the class. Default initialization forisOuterLayerSpan = falseis appropriate.Also applies to: 134-144
319-350: LGTM!The new accessor methods follow JavaBean conventions and are consistent with the existing codebase style.
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java (1)
568-585: Both finishSpan overloads have identical logic in the outer-level span handling block.The Synapse and Axis2 versions (lines 554–567 and 568–585, respectively) both execute the same code path in their else blocks:
spanStore.finishSpan()followed bytracingScopeManager.cleanupTracingScope(). There is no difference in how outer-level spans are finished between the two overloads. Neither method contains calls toisEventCollectionFinishedorcleanupContinuationStateSequences— these methods do not exist in this class.Likely an incorrect or invalid review comment.
| String[] customTags = customTagsString.split(","); | ||
| Map<String, Object> customTagsMap = new HashMap<>(); | ||
| for (String tag : customTags) { | ||
| if (headersMap.containsKey(tag.trim())) { | ||
| customTagsMap.put(tag, headersMap.get(tag)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent key handling in custom tags map.
In the Synapse version (line 271), the key is stored with the original (potentially untrimmed) value, but the header lookup uses tag.trim(). In the Axis2 version (line 370), the same pattern exists. This may cause issues if the configured tag has leading/trailing whitespace.
for (String tag : customTags) {
- if (headersMap.containsKey(tag.trim())) {
- customTagsMap.put(tag, headersMap.get(tag));
+ String trimmedTag = tag.trim();
+ if (headersMap.containsKey(trimmedTag)) {
+ customTagsMap.put(trimmedTag, headersMap.get(trimmedTag));
}
}Also applies to: 365-371
🤖 Prompt for AI Agents
In
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java
around lines 267-272 (and similarly around 365-371), the code trims the tag when
looking up headers but uses the untrimmed original tag as the map key, which can
cause mismatched keys when configured tags have surrounding whitespace; update
the logic to trim the tag once into a local variable (e.g., String key =
tag.trim()), use that trimmed key for the headersMap lookup and also as the key
when putting into customTagsMap so both lookup and storage are consistent.
| } | ||
| } | ||
|
|
||
| statisticDataUnit.setTransportHeaderMap(headersMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Remove redundant setTransportHeaderMap call.
statisticDataUnit.setTransportHeaderMap(headersMap) is already called at line 352. This duplicate call at line 381 is unnecessary.
- statisticDataUnit.setTransportHeaderMap(headersMap);
-
String spanId = TracingUtils.extractId(statisticDataUnit);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| statisticDataUnit.setTransportHeaderMap(headersMap); |
🤖 Prompt for AI Agents
In
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java
around line 381, there is a redundant call to
statisticDataUnit.setTransportHeaderMap(headersMap) (it was already set at line
352); remove the duplicate call at line 381 so the transport header map is only
assigned once, leaving the earlier assignment intact.
| @Override | ||
| public void handleCloseFlowForcefully(BasicStatisticDataUnit basicStatisticDataUnit, | ||
| org.apache.axis2.context.MessageContext msgCtx) { | ||
| TracingScope tracingScope = tracingScopeManager.getTracingScope(msgCtx); | ||
| SpanStore spanStore = tracingScope.getSpanStore(); | ||
| String spanWrapperId = TracingUtils.extractId(basicStatisticDataUnit); | ||
| SpanWrapper spanWrapper = spanStore.getSpanWrapper(spanWrapperId); | ||
|
|
||
| // finish the current span | ||
| handleCloseEvent(basicStatisticDataUnit, msgCtx, true); | ||
|
|
||
| // finish outer level spans since the control is not returned to the original flow to close them gracefully. | ||
| while (spanWrapper.getParentSpanWrapper() != null) { | ||
| spanWrapper = spanWrapper.getParentSpanWrapper(); | ||
| spanStore.finishSpan(spanWrapper, msgCtx, true); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent error flag behavior between Synapse and Axis2 overloads.
The Axis2 handleCloseFlowForcefully always calls handleCloseEvent with isError=true (line 483) and finishes parent spans with isError=true (line 488), whereas the Synapse version uses isError=false (line 465). This behavioral difference may cause inconsistent span status reporting.
// finish the current span
- handleCloseEvent(basicStatisticDataUnit, msgCtx, true);
+ handleCloseEvent(basicStatisticDataUnit, msgCtx, false);
// finish outer level spans since the control is not returned to the original flow to close them gracefully.
while (spanWrapper.getParentSpanWrapper() != null) {
spanWrapper = spanWrapper.getParentSpanWrapper();
- spanStore.finishSpan(spanWrapper, msgCtx, true);
+ spanStore.finishSpan(spanWrapper, msgCtx);
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java
around lines 474 to 490: the Axis2 overload incorrectly marks the close flow as
an error by passing isError=true to handleCloseEvent and to spanStore.finishSpan
for parent spans, creating inconsistent span status versus the Synapse overload
which uses isError=false; change the calls to use isError=false (or otherwise
mirror the Synapse overload behavior) so
handleCloseEvent(basicStatisticDataUnit, msgCtx, false) is called and
spanStore.finishSpan(spanWrapper, msgCtx, false) is used in the parent loop,
ensuring consistent non-error closure semantics.
| String spanWrapperId = TracingUtils.extractId(basicStatisticDataUnit); | ||
| SpanWrapper spanWrapper = spanStore.getSpanWrapper(spanWrapperId); | ||
|
|
||
| // finish the current span | ||
| handleCloseEvent(basicStatisticDataUnit, msgCtx, true); | ||
|
|
||
| // finish outer level spans since the control is not returned to the original flow to close them gracefully. | ||
| while (spanWrapper.getParentSpanWrapper() != null) { | ||
| spanWrapper = spanWrapper.getParentSpanWrapper(); | ||
| spanStore.finishSpan(spanWrapper, msgCtx, true); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential NullPointerException in parent span traversal.
If spanStore.getSpanWrapper(spanWrapperId) returns null, the while loop at line 486 will throw a NullPointerException. The Synapse version at line 468 has the same risk.
Add a null check before traversing:
SpanWrapper spanWrapper = spanStore.getSpanWrapper(spanWrapperId);
// finish the current span
handleCloseEvent(basicStatisticDataUnit, msgCtx, true);
// finish outer level spans since the control is not returned to the original flow to close them gracefully.
- while (spanWrapper.getParentSpanWrapper() != null) {
+ while (spanWrapper != null && spanWrapper.getParentSpanWrapper() != null) {
spanWrapper = spanWrapper.getParentSpanWrapper();
spanStore.finishSpan(spanWrapper, msgCtx, true);
}🤖 Prompt for AI Agents
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/handling/span/SpanHandler.java
around lines 479-489: spanStore.getSpanWrapper(spanWrapperId) may return null
and the subsequent while (spanWrapper.getParentSpanWrapper() != null) will NPE;
add a null check after retrieving spanWrapper and only call handleCloseEvent and
traverse parentSpanWrapper/finishSpan if spanWrapper != null (log a warning or
return early if null) to avoid the NullPointerException.
| public SpanWrapper addSpanWrapper(String spanId, | ||
| Span activeSpan, | ||
| StatisticDataUnit statisticDataUnit, | ||
| SpanWrapper parentSpanWrapper, | ||
| org.apache.axis2.context.MessageContext msgCtx) { | ||
| SpanWrapper spanWrapper = new SpanWrapper(spanId, activeSpan, statisticDataUnit, parentSpanWrapper); | ||
| spanWrappers.put(spanId, spanWrapper); | ||
| spanWrapper.addKnownSynCtxHashCodeToAllParents(TracingUtils.getSystemIdentityHashCode(msgCtx)); | ||
| if (parentSpanWrapper != null) { | ||
| parentSpanWrapper.addChildComponentUniqueId(statisticDataUnit.getComponentId()); | ||
| } | ||
| componentUniqueIdWiseSpanWrappers.put(statisticDataUnit.getComponentId(), spanWrapper); | ||
| activeSpanWrappers.add(spanWrapper); | ||
| return spanWrapper; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing anonymous sequence handling in Axis2 overload.
The Axis2 addSpanWrapper overload is missing the anonymous sequence handling present in the Synapse MessageContext version (lines 103-108). This could lead to incorrect span parent relationships when anonymous sequences are involved in Axis2 contexts.
Apply this diff to add the missing logic:
public SpanWrapper addSpanWrapper(String spanId,
Span activeSpan,
StatisticDataUnit statisticDataUnit,
SpanWrapper parentSpanWrapper,
org.apache.axis2.context.MessageContext msgCtx) {
SpanWrapper spanWrapper = new SpanWrapper(spanId, activeSpan, statisticDataUnit, parentSpanWrapper);
spanWrappers.put(spanId, spanWrapper);
spanWrapper.addKnownSynCtxHashCodeToAllParents(TracingUtils.getSystemIdentityHashCode(msgCtx));
if (parentSpanWrapper != null) {
parentSpanWrapper.addChildComponentUniqueId(statisticDataUnit.getComponentId());
+ if (TracingUtils.isAnonymousSequence(spanWrapper.getStatisticDataUnit())) {
+ /*
+ Add this anonymous sequence to the parent.
+ Note that, anonymous sequences are not pushed to the continuation stack
+ */
+ parentSpanWrapper.addAnonymousSequence(spanId, spanWrapper);
+ }
}
componentUniqueIdWiseSpanWrappers.put(statisticDataUnit.getComponentId(), spanWrapper);
activeSpanWrappers.add(spanWrapper);
return spanWrapper;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public SpanWrapper addSpanWrapper(String spanId, | |
| Span activeSpan, | |
| StatisticDataUnit statisticDataUnit, | |
| SpanWrapper parentSpanWrapper, | |
| org.apache.axis2.context.MessageContext msgCtx) { | |
| SpanWrapper spanWrapper = new SpanWrapper(spanId, activeSpan, statisticDataUnit, parentSpanWrapper); | |
| spanWrappers.put(spanId, spanWrapper); | |
| spanWrapper.addKnownSynCtxHashCodeToAllParents(TracingUtils.getSystemIdentityHashCode(msgCtx)); | |
| if (parentSpanWrapper != null) { | |
| parentSpanWrapper.addChildComponentUniqueId(statisticDataUnit.getComponentId()); | |
| } | |
| componentUniqueIdWiseSpanWrappers.put(statisticDataUnit.getComponentId(), spanWrapper); | |
| activeSpanWrappers.add(spanWrapper); | |
| return spanWrapper; | |
| } | |
| public SpanWrapper addSpanWrapper(String spanId, | |
| Span activeSpan, | |
| StatisticDataUnit statisticDataUnit, | |
| SpanWrapper parentSpanWrapper, | |
| org.apache.axis2.context.MessageContext msgCtx) { | |
| SpanWrapper spanWrapper = new SpanWrapper(spanId, activeSpan, statisticDataUnit, parentSpanWrapper); | |
| spanWrappers.put(spanId, spanWrapper); | |
| spanWrapper.addKnownSynCtxHashCodeToAllParents(TracingUtils.getSystemIdentityHashCode(msgCtx)); | |
| if (parentSpanWrapper != null) { | |
| parentSpanWrapper.addChildComponentUniqueId(statisticDataUnit.getComponentId()); | |
| if (TracingUtils.isAnonymousSequence(spanWrapper.getStatisticDataUnit())) { | |
| /* | |
| Add this anonymous sequence to the parent. | |
| Note that, anonymous sequences are not pushed to the continuation stack | |
| */ | |
| parentSpanWrapper.addAnonymousSequence(spanId, spanWrapper); | |
| } | |
| } | |
| componentUniqueIdWiseSpanWrappers.put(statisticDataUnit.getComponentId(), spanWrapper); | |
| activeSpanWrappers.add(spanWrapper); | |
| return spanWrapper; | |
| } |
🤖 Prompt for AI Agents
In
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/stores/SpanStore.java
around lines 126-140, the Axis2 overload of addSpanWrapper is missing the
anonymous-sequence handling that exists in the Synapse MessageContext overload
(lines ~103-108); update this method to mirror that logic: after creating and
putting the new SpanWrapper, detect if the current statisticDataUnit/msgCtx
represents an anonymous sequence (use the same check/constants used in the
MessageContext overload), and if so resolve the actual parent span wrapper for
the anonymous sequence (lookup by the anonymous sequence component id in
componentUniqueIdWiseSpanWrappers or via the same TracingUtils helper) and
attach the new span as a child of that resolved parent (call the same
addChildComponentUniqueId / parent linking method used in the other overload).
Ensure you still populate componentUniqueIdWiseSpanWrappers and
activeSpanWrappers exactly as before, but with the additional anonymous-sequence
parent resolution and parent linking inserted in the same place relative to
those operations as in the MessageContext version.
| /** | ||
| * Denotes the end of a span. | ||
| * Adds tags to the span and removes reference to the appropriate span wrapper in activeSpanWrappers. | ||
| * | ||
| * @param spanWrapper Span wrapper object, which has been already created | ||
| * @param msgCtx Synapse message context | ||
| * @param isError finishing the span with an error | ||
| */ | ||
| public void finishSpan(SpanWrapper spanWrapper, org.apache.axis2.context.MessageContext msgCtx, boolean isError) { | ||
| if (spanWrapper != null && spanWrapper.getSpan() != null) { | ||
| if (spanWrapper.getStatisticDataUnit() != null) { | ||
| SpanTagger.setSpanTags(spanWrapper, msgCtx); | ||
| } | ||
| if (isError) { | ||
| spanWrapper.getSpan().setStatus(StatusCode.ERROR); | ||
| } | ||
| spanWrapper.getSpan().end(); | ||
| activeSpanWrappers.remove(spanWrapper); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Javadoc comment: incorrect parameter description.
The Javadoc states @param msgCtx Synapse message context but the parameter is actually an Axis2 MessageContext.
/**
* Denotes the end of a span.
* Adds tags to the span and removes reference to the appropriate span wrapper in activeSpanWrappers.
*
* @param spanWrapper Span wrapper object, which has been already created
- * @param msgCtx Synapse message context
+ * @param msgCtx Axis2 message context
* @param isError finishing the span with an error
*/🤖 Prompt for AI Agents
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/stores/SpanStore.java
around lines 183 to 202: the Javadoc for finishSpan incorrectly describes the
msgCtx parameter as a "Synapse message context"; update the @param tag to
correctly state that msgCtx is an Axis2 MessageContext (e.g., "Axis2
MessageContext" or "org.apache.axis2.context.MessageContext") and ensure wording
matches the method signature and imports.
| Object skipMainSequenceObj = synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE); | ||
| if (skipMainSequenceObj != null && (Boolean) skipMainSequenceObj) { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential ClassCastException with unsafe cast.
The direct cast to Boolean will throw a ClassCastException if the property is set as a non-Boolean type (e.g., String "true"). Consider using Boolean.TRUE.equals() for safer comparison.
- Object skipMainSequenceObj = synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE);
- if (skipMainSequenceObj != null && (Boolean) skipMainSequenceObj) {
+ Object skipMainSequenceObj = synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE);
+ if (Boolean.TRUE.equals(skipMainSequenceObj)) {
return true;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Object skipMainSequenceObj = synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE); | |
| if (skipMainSequenceObj != null && (Boolean) skipMainSequenceObj) { | |
| return true; | |
| } | |
| Object skipMainSequenceObj = synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE); | |
| if (Boolean.TRUE.equals(skipMainSequenceObj)) { | |
| return true; | |
| } |
🤖 Prompt for AI Agents
In
modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2SynapseEnvironment.java
around lines 361 to 364, the code unsafely casts
synCtx.getProperty(SynapseConstants.SKIP_MAIN_SEQUENCE) to Boolean which can
throw ClassCastException if the property is a non-Boolean (e.g., String);
replace the direct cast with a safe check such as
Boolean.TRUE.equals(skipMainSequenceObj) or explicitly handle String values
(e.g., parse "true"/"false") so the condition only returns true when the
property semantically represents true without throwing.
fixes: wso2/product-micro-integrator#4496
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.