Skip to content

Commit

Permalink
fix: Rename apikit traces with flow spans only (#166)
Browse files Browse the repository at this point in the history
When renaming the trace using apikit flow names, only the flow-span
should process renaming.
  • Loading branch information
manikmagar authored Mar 22, 2024
1 parent 08d91bd commit 22175d6
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public TraceComponent getStartTraceComponent(EnrichedServerNotification notifica

TraceComponent traceComponent = TraceComponent.named(notification.getResourceIdentifier());

Map<String, String> tags = new HashMap<>();
Map<String, String> tags = getProcessorCommonTags(notification.getComponent());
tags.put(MULE_APP_FLOW_NAME.getKey(), notification.getResourceIdentifier());
tags.put(MULE_SERVER_ID.getKey(), notification.getServerId());
tags.put(MULE_CORRELATION_ID.getKey(), notification.getEvent().getCorrelationId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public static String spanName(String method, String route) {
public static String apiKitRoutePath(Map<String, String> tags, String rootSpanName) {
Objects.requireNonNull(rootSpanName, "Root span name must not be null");
String flowName = tags.get(MULE_APP_FLOW_NAME.getKey());
Objects.requireNonNull(flowName, "Flow name must not be null");
String pathName = (flowName.split(":")[1]).replace(":", "")
.replaceAll("\\\\", "/")
.replaceAll("\\(", "{").replaceAll("\\)", "}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.avioconsulting.mule.opentelemetry.internal.opentelemetry.sdk.SemanticAttributes;
import com.avioconsulting.mule.opentelemetry.internal.processor.TraceComponent;
import com.avioconsulting.mule.opentelemetry.internal.util.ComponentsUtil;
import com.avioconsulting.mule.opentelemetry.internal.util.PropertiesUtil;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
Expand Down Expand Up @@ -73,7 +74,8 @@ public SpanMeta addProcessorSpan(String containerName, TraceComponent traceCompo
private void resetSpanNameIfNeeded(TraceComponent traceComponent) {
if (!PropertiesUtil.isUseAPIKitSpanNames())
return;
if (apikitConfigName != null && traceComponent.getName().endsWith(":" + apikitConfigName)) {
if (apikitConfigName != null && ComponentsUtil.isFlowTrace(traceComponent)
&& traceComponent.getName().endsWith(":" + apikitConfigName)) {
if (rootSpanName.endsWith("/*")) { // Wildcard listener for HTTP APIKit Router
String spanName = apiKitRoutePath(traceComponent.getTags(), getRootSpanName());
getSpan().updateName(spanName);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.avioconsulting.mule.opentelemetry.internal.util;

import com.avioconsulting.mule.opentelemetry.internal.processor.TraceComponent;
import org.mule.runtime.api.component.Component;
import org.mule.runtime.api.component.ComponentIdentifier;
import org.mule.runtime.api.component.location.ComponentLocation;
import org.mule.runtime.api.component.location.ConfigurationComponentLocator;

import java.util.Optional;

import static com.avioconsulting.mule.opentelemetry.internal.opentelemetry.sdk.SemanticAttributes.MULE_APP_PROCESSOR_NAME;

public class ComponentsUtil {

public static Optional<ComponentLocation> findLocation(String location,
Expand All @@ -29,4 +32,9 @@ public static Optional<Component> findComponent(ComponentIdentifier identifier,
.find(identifier).stream()
.filter(c -> c.getLocation().getLocation().equals(location)).findFirst();
}

public static boolean isFlowTrace(TraceComponent traceComponent) {
return traceComponent != null && traceComponent.getTags() != null
&& "flow".equalsIgnoreCase(traceComponent.getTags().get(MULE_APP_PROCESSOR_NAME.getKey()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ protected void doTearDownAfterMuleContextDispose() throws Exception {
public void getAPIKitOrders() throws Exception {
sendRequest(CORRELATION_ID, "/api/orders/1234", 200);
await().untilAsserted(() -> assertThat(DelegatedLoggingSpanTestExporter.spanQueue)
.hasSize(3)
.hasSize(8)
.anySatisfy(span -> {
assertThat(span)
.as("Span for http:listener source flow")
Expand All @@ -52,13 +52,27 @@ public void getAPIKitOrders() throws Exception {
.extracting("spanName", "spanKind", "spanStatus")
.containsOnly("router:router order-exp-config", "INTERNAL", "UNSET");
}));
await().untilAsserted(() -> assertThat(DelegatedLoggingSpanTestExporter.spanQueue)
.anySatisfy(span -> {
assertThat(span)
.as("Span for http:request target flow")
.extracting("spanName", "spanKind", "spanStatus")
.containsOnly("/test", "CLIENT", "UNSET");
}));
await().untilAsserted(() -> assertThat(DelegatedLoggingSpanTestExporter.spanQueue)
.anySatisfy(span -> {
assertThat(span)
.as("Span for http:listener target flow")
.extracting("spanName", "spanKind", "spanStatus")
.containsOnly("GET /test", "SERVER", "UNSET");
}));
}

@Test
public void getAPIKitOrders_404Error() throws Exception {
sendRequest(CORRELATION_ID, "/api/something/1234", 404);
await().untilAsserted(() -> assertThat(DelegatedLoggingSpanTestExporter.spanQueue)
.hasSize(2)
.hasSize(4)
.anySatisfy(span -> {
assertThat(span)
.as("Span for http:listener source flow")
Expand All @@ -78,7 +92,7 @@ public void postAPIKitOrders() throws Exception {
ContentType.APPLICATION_JSON);
sendRequest("post", CORRELATION_ID, "/api/orders", 201, stringEntity);
await().untilAsserted(() -> assertThat(DelegatedLoggingSpanTestExporter.spanQueue)
.hasSize(3)
.hasSize(4)
.anySatisfy(span -> {
assertThat(span)
.as("Span for http:listener source flow")
Expand Down
67 changes: 65 additions & 2 deletions src/test/resources/apikit-order-exp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,62 @@
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:apikit="http://www.mulesoft.org/schema/mule/mule-apikit"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:opentelemetry="http://www.mulesoft.org/schema/mule/opentelemetry"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/mule-apikit http://www.mulesoft.org/schema/mule/mule-apikit/current/mule-apikit.xsd">
http://www.mulesoft.org/schema/mule/mule-apikit http://www.mulesoft.org/schema/mule/mule-apikit/current/mule-apikit.xsd
http://www.mulesoft.org/schema/mule/opentelemetry http://www.mulesoft.org/schema/mule/opentelemetry/current/mule-opentelemetry.xsd">
<apikit:config name="order-exp-config" api="order-exp.raml" outboundHeadersMapName="outboundHeaders" httpStatusVarName="httpStatus" />
<import file="global-common.xml"/>
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="79881531-bfaa-49fd-8227-b67e35d64cf8" >
<http:listener-connection host="0.0.0.0" port="${http.port}" />
</http:listener-config>

<opentelemetry:config name="OpenTelemetry_Config" doc:name="OpenTelemetry Config" doc:id="91477cb5-36f7-48ad-90b7-c339af87b408" serviceName="api-app-1" maxQueueSize="2048"
maxBatchExportSize="512" batchExportDelayInterval="5000"
exportTimeout="30000" spanAllProcessors="true">
<opentelemetry:resource-attributes >
<opentelemetry:attribute key="mule.env" value="Dev" />
</opentelemetry:resource-attributes>
<opentelemetry:exporter >
<!-- <opentelemetry:logging-exporter logPrefix="test-log" />-->
<opentelemetry:generic-exporter >
<opentelemetry:config-properties >
<opentelemetry:config-property key="otel.traces.exporter" value="delegatedLogging" />
</opentelemetry:config-properties>
</opentelemetry:generic-exporter>
</opentelemetry:exporter>
</opentelemetry:config>
<http:request-config name="SELF_HTTP_Request_configuration" doc:name="HTTP Request configuration" doc:id="c18eed36-eb42-4c29-abc9-9e7a2c6049e1" >
<http:request-connection host="0.0.0.0" port="${http.port}" />
</http:request-config>
<error-handler name="global-apikit-error-handler">
<on-error-propagate type="APIKIT:BAD_REQUEST">
<set-payload value="#[output application/json --- {message: 'Bad request'}]"/>
<set-variable value="400" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_FOUND">
<set-payload value="#[output application/json --- {message: 'Resource not found'}]"/>
<set-variable value="404" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:METHOD_NOT_ALLOWED">
<set-payload value="#[output application/json --- {message: 'Method not allowed'}]"/>
<set-variable value="405" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_ACCEPTABLE">
<set-payload value="#[output application/json --- {message: 'Not acceptable'}]"/>
<set-variable value="406" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:UNSUPPORTED_MEDIA_TYPE">
<set-payload value="#[output application/json --- {message: 'Unsupported media type'}]"/>
<set-variable value="415" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_IMPLEMENTED">
<set-payload value="#[output application/json --- {message: 'Not Implemented'}]"/>
<set-variable value="501" variableName="httpStatus" />
</on-error-propagate>
</error-handler>
<flow name="order-exp-main">
<http:listener config-ref="HTTP_Listener_config" path="/api/*">
<http:response statusCode="#[vars.httpStatus default 200]">
Expand All @@ -22,8 +71,22 @@
<apikit:router config-ref="order-exp-config" />
<error-handler ref="global-apikit-error-handler"/>
</flow>
<flow name="apikit-test-flow" doc:id="ddcac188-d00c-4614-ba69-5deef8575938" >
<http:listener config-ref="HTTP_Listener_config" path="/test">
<http:response statusCode="#[vars.httpStatus default 200]">
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:response>
<http:error-response statusCode="#[vars.httpStatus default 500]">
<http:body>#[payload]</http:body>
<http:headers>#[vars.outboundHeaders default {}]</http:headers>
</http:error-response>
</http:listener>
<logger level="INFO" doc:name="Logger" doc:id="97393612-d33a-466f-b9b5-600a21098532" />
</flow>

<flow name="get:\orders\(orderId):order-exp-config">
<set-variable value="#[attributes.uriParams.'orderId']" variableName="orderId" />
<http:request method="GET" doc:name="Request" config-ref="SELF_HTTP_Request_configuration" path="/test"/>
<logger level="INFO" message="get:\orders\(orderId):order-exp-config" />
</flow>
<flow name="post:\orders:application\json:order-exp-config">
Expand Down
26 changes: 0 additions & 26 deletions src/test/resources/global-common.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,4 @@ http://www.mulesoft.org/schema/mule/opentelemetry http://www.mulesoft.org/schema
<http:request-config name="SELF_HTTP_Request_configuration" doc:name="HTTP Request configuration" doc:id="c18eed36-eb42-4c29-abc9-9e7a2c6049e1" >
<http:request-connection host="0.0.0.0" port="${http.port}" />
</http:request-config>
<error-handler name="global-apikit-error-handler">
<on-error-propagate type="APIKIT:BAD_REQUEST">
<set-payload value="#[output application/json --- {message: 'Bad request'}]"/>
<set-variable value="400" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_FOUND">
<set-payload value="#[output application/json --- {message: 'Resource not found'}]"/>
<set-variable value="404" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:METHOD_NOT_ALLOWED">
<set-payload value="#[output application/json --- {message: 'Method not allowed'}]"/>
<set-variable value="405" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_ACCEPTABLE">
<set-payload value="#[output application/json --- {message: 'Not acceptable'}]"/>
<set-variable value="406" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:UNSUPPORTED_MEDIA_TYPE">
<set-payload value="#[output application/json --- {message: 'Unsupported media type'}]"/>
<set-variable value="415" variableName="httpStatus" />
</on-error-propagate>
<on-error-propagate type="APIKIT:NOT_IMPLEMENTED">
<set-payload value="#[output application/json --- {message: 'Not Implemented'}]"/>
<set-variable value="501" variableName="httpStatus" />
</on-error-propagate>
</error-handler>
</mule>

0 comments on commit 22175d6

Please sign in to comment.