Skip to content
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

fix: rename apikit traces with flow spans only #167

Merged
merged 2 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,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 @@ -3,10 +3,10 @@
import com.avioconsulting.mule.opentelemetry.api.sdk.SemanticAttributes;
import com.avioconsulting.mule.opentelemetry.api.store.SpanMeta;
import com.avioconsulting.mule.opentelemetry.api.traces.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;

import java.io.Serializable;
import java.time.Instant;
import java.util.HashMap;
Expand Down Expand Up @@ -76,7 +76,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.api.traces.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.api.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>
Loading