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

feat: telemetry disable flags #200

Merged
merged 1 commit into from
Aug 27, 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 @@ -31,6 +31,10 @@ public boolean isTurnOffTracing() {
return openTelemetryConfiguration.isTurnOffTracing();
}

public boolean isTurnOffMetrics() {
return openTelemetryConfiguration.isTurnOffMetrics();
}

public OpenTelemetryConfiguration getOpenTelemetryConfiguration() {
return openTelemetryConfiguration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface OpenTelemetryConfiguration {

boolean isTurnOffTracing();

boolean isTurnOffMetrics();

TraceLevelConfiguration getTraceLevelConfiguration();

ExporterConfiguration getExporterConfiguration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.avioconsulting.mule.opentelemetry.api.config.SpanProcessorConfiguration;
import com.avioconsulting.mule.opentelemetry.api.config.TraceLevelConfiguration;
import com.avioconsulting.mule.opentelemetry.api.notifications.MetricBaseNotificationData;
import com.avioconsulting.mule.opentelemetry.api.providers.NoopOpenTelemetryMetricsConfigProvider;
import com.avioconsulting.mule.opentelemetry.api.providers.OpenTelemetryMetricsConfigProvider;
import com.avioconsulting.mule.opentelemetry.api.providers.OpenTelemetryMetricsConfigSupplier;
import com.avioconsulting.mule.opentelemetry.internal.OpenTelemetryOperations;
Expand Down Expand Up @@ -46,6 +47,7 @@
public class OpenTelemetryExtensionConfiguration
implements Startable, Stoppable, OpenTelemetryConfiguration, OpenTelemetryMetricsConfigSupplier {

public static final String PROP_MULE_OTEL_METRICS_DISABLED = "mule.otel.metrics.disabled";
public static final String PROP_MULE_OTEL_TRACING_DISABLED = "mule.otel.tracing.disabled";
private final Logger logger = LoggerFactory.getLogger(OpenTelemetryExtensionConfiguration.class);
private static final DataType METRIC_NOTIFICATION_DATA_TYPE = DataType.fromType(MetricBaseNotificationData.class);
Expand Down Expand Up @@ -96,8 +98,14 @@ public HttpService getHttpService() {
private SpanProcessorConfiguration spanProcessorConfiguration;

@Parameter
@Optional
@Optional(defaultValue = "false")
@Placement(order = 501, tab = "Metrics")
@Summary("Turn off Metrics for this application.")
private boolean turnOffMetrics;

@Parameter
@Optional
@Placement(order = 502, tab = "Metrics")
@DisplayName("Metrics Provider")
@Summary("OpenTelemetry Metrics Provider")
private OpenTelemetryMetricsConfigProvider metricsConfigProvider;
Expand All @@ -108,6 +116,17 @@ public boolean isTurnOffTracing() {
.parseBoolean(System.getProperty(PROP_MULE_OTEL_TRACING_DISABLED)) : turnOffTracing;
}

@Override
public boolean isTurnOffMetrics() {
boolean disabled = System.getProperties().containsKey(PROP_MULE_OTEL_METRICS_DISABLED) ? Boolean
.parseBoolean(System.getProperty(PROP_MULE_OTEL_METRICS_DISABLED)) : turnOffMetrics;
if (!disabled) {
disabled = this.metricsConfigProvider == null
|| this.metricsConfigProvider instanceof NoopOpenTelemetryMetricsConfigProvider;
}
return disabled;
}

// Visible for testing purpose
OpenTelemetryExtensionConfiguration setTurnOffTracing(boolean turnOffTracing) {
this.turnOffTracing = turnOffTracing;
Expand Down Expand Up @@ -173,32 +192,30 @@ public String getConfigName() {

@Override
public void start() throws MuleException {
if (disableTelemetry()) {
logger.warn("Tracing and Metrics is disabled. OpenTelemetry will be turned off for config '{}'.",
getConfigName());
// Is there a better way to let runtime trigger the configuration shutdown
// without stopping the application?
// Raising an exception here will make runtime invoke the stop method
// but it will kill the application as well, so can't do that here.
// For now, let's skip the initialization of tracing related components and
// processors.
return;
}
logger.info("Initiating otel config - '{}'", getConfigName());
appIdentifier = AppIdentifier.fromEnvironment(expressionManager);
OpenTelemetryConnection openTelemetryConnection = OpenTelemetryConnection
.getInstance(new OpenTelemetryConfigWrapper(this));
muleNotificationProcessor.init(openTelemetryConnection,
getTraceLevelConfiguration());

notificationListenerRegistry.registerListener(
new MuleMessageProcessorNotificationListener(muleNotificationProcessor));
notificationListenerRegistry.registerListener(
new MulePipelineMessageNotificationListener(muleNotificationProcessor));
notificationListenerRegistry.registerListener(new AsyncMessageNotificationListener(muleNotificationProcessor));
notificationListenerRegistry.registerListener(new MetricEventNotificationListener(muleNotificationProcessor),
extensionNotification -> METRIC_NOTIFICATION_DATA_TYPE
.isCompatibleWith(extensionNotification.getData().getDataType()));
if (!isTurnOffTracing()) {
logger.info("Tracing has been turned off. No listener will be registered.");
notificationListenerRegistry.registerListener(
new MuleMessageProcessorNotificationListener(muleNotificationProcessor));
notificationListenerRegistry.registerListener(
new MulePipelineMessageNotificationListener(muleNotificationProcessor));
notificationListenerRegistry
.registerListener(new AsyncMessageNotificationListener(muleNotificationProcessor));
}

if (!isTurnOffMetrics()) {
logger.info("Metrics has been turned off. No listener will be registered.");
notificationListenerRegistry.registerListener(
new MetricEventNotificationListener(muleNotificationProcessor),
extensionNotification -> METRIC_NOTIFICATION_DATA_TYPE
.isCompatibleWith(extensionNotification.getData().getDataType()));
}
}

@Override
Expand All @@ -211,15 +228,8 @@ public OpenTelemetryMetricsConfigProvider getMetricsConfigProvider() {
return metricsConfigProvider;
}

private boolean disableTelemetry() {
return isTurnOffTracing() && metricsConfigProvider == null;
}

@Override
public void stop() throws MuleException {
if (isTurnOffTracing()) {
logger.info("{} is set to true. Configuration '{}' has been stopped.", PROP_MULE_OTEL_TRACING_DISABLED,
getConfigName());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class OpenTelemetryConnection implements TraceContextHandler {
private final OpenTelemetry openTelemetry;
private final Tracer tracer;
private boolean turnOffTracing = false;
private boolean turnOffMetrics = false;

private OpenTelemetryConnection(OpenTelemetryConfigWrapper openTelemetryConfigWrapper) {
Properties properties = getModuleProperties();
Expand All @@ -87,6 +88,7 @@ private OpenTelemetryConnection(OpenTelemetryConfigWrapper openTelemetryConfigWr
// See here for autoconfigure options
// https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure
AutoConfiguredOpenTelemetrySdkBuilder builder = AutoConfiguredOpenTelemetrySdk.builder();

if (openTelemetryConfigWrapper != null) {
// TODO: Process other config elements for OTEL SDK
final Map<String, String> configMap = new HashMap<>();
Expand All @@ -102,19 +104,24 @@ private OpenTelemetryConnection(OpenTelemetryConfigWrapper openTelemetryConfigWr
builder.addPropertiesSupplier(() -> Collections.unmodifiableMap(configMap));
logger.debug("Creating OpenTelemetryConnection with properties: [" + configMap + "]");
turnOffTracing = openTelemetryConfigWrapper.isTurnOffTracing();
turnOffMetrics = openTelemetryConfigWrapper.isTurnOffMetrics();
appIdentifier = openTelemetryConfigWrapper.getOpenTelemetryConfiguration().getAppIdentifier();
metricsProvider = openTelemetryConfigWrapper.getOpenTelemetryConfiguration().getMetricsConfigProvider();
expressionManager = openTelemetryConfigWrapper.getOpenTelemetryConfiguration().getExpressionManager();
}
builder.setServiceClassLoader(AutoConfiguredOpenTelemetrySdkBuilder.class.getClassLoader());
builder.setResultAsGlobal();
if (metricsProvider != null)
if (!turnOffMetrics)
metricsProvider.initialise(appIdentifier);
openTelemetry = builder.build().getOpenTelemetrySdk();
installOpenTelemetryLogger();
if (metricsProvider != null) {
if (!turnOffMetrics) {
logger.info("Initializing Metrics Providers");
metricsProvider.start();
metricsProviders.initialize(metricsProvider, openTelemetry);
} else {
logger.info("Disabling loaded Metrics Providers");
metricsProviders.clear();
}
tracer = openTelemetry.getTracer(instrumentationName, instrumentationVersion);
transactionStore = InMemoryTransactionStore.getInstance();
Expand Down Expand Up @@ -144,6 +151,10 @@ public boolean isTurnOffTracing() {
return turnOffTracing;
}

public boolean isTurnOffMetrics() {
return turnOffMetrics;
}

public OpenTelemetryMetricsProviderCollection getMetricsProviders() {
return metricsProviders;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ public boolean intercept(ComponentLocation location) {
.noneMatch(mc -> mc.getNamespace().equalsIgnoreCase(identifier.getNamespace())
& (mc.getName().equalsIgnoreCase(identifier.getName())
|| "*".equalsIgnoreCase(mc.getName())));
intercept = isFirstProcessor(location)
|| interceptConfigured;
intercept = !muleNotificationProcessor.getOpenTelemetryConnection().isTurnOffTracing()
&& (isFirstProcessor(location)
|| interceptConfigured);

if (intercept) {
// This factory executes during application initialization.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void addInterceptSpannedComponents(String location) {
* {@link String} value of target processor
*/
public void addMeteredComponentLocation(String location) {
if (openTelemetryConnection != null) {
if (openTelemetryConnection != null && !openTelemetryConnection.isTurnOffMetrics()) {
openTelemetryConnection.getMetricsProviders().addMeteredComponent(location);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.avioconsulting.mule.opentelemetry;

import org.assertj.core.api.SoftAssertions;
import org.awaitility.core.ConditionTimeoutException;
import org.junit.Test;
import org.mule.runtime.core.api.event.CoreEvent;

import java.time.Duration;
import java.util.Map;
import java.util.Set;

import static com.avioconsulting.mule.opentelemetry.internal.opentelemetry.sdk.test.DelegatedLoggingSpanTestExporter.spanQueue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.awaitility.Awaitility.await;

public class TurnOffTracingByConfig extends AbstractMuleArtifactTraceTest {

@Override
protected String getConfigFile() {
return "turn-off-tracing-by-config.xml";
}

@Override
public void clearSpansQueue() {
// No tracing is expected so nothing to clean
}

@Test
public void testNoTracingInteraction() throws Exception {
CoreEvent event = flowRunner("simple-flow").run();
ConditionTimeoutException conditionTimeoutException = catchThrowableOfType(
() -> await().timeout(Duration.ofSeconds(2)).until(() -> !spanQueue.isEmpty()),
ConditionTimeoutException.class);
assertThat(conditionTimeoutException).isNotNull();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public void getInstance() {
when(configuration.getResource()).thenReturn(resource);
when(configuration.getExporterConfiguration()).thenReturn(exporterConfig);
when(configuration.getSpanProcessorConfiguration()).thenReturn(spc);
when(configuration.isTurnOffMetrics()).thenReturn(true);
OpenTelemetryConfigWrapper wrapper = new OpenTelemetryConfigWrapper(configuration);
OpenTelemetryConnection instance = OpenTelemetryConnection.getInstance(wrapper);
verify(resource).getConfigMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ public class MessageProcessorTracingInterceptorFactoryTest extends AbstractInter
@Mock
ConfigurationComponentLocator configurationComponentLocator;

@Mock
OpenTelemetryConnection openTelemetryConnection;

@Before
public void setMocks() {
when(muleNotificationProcessor.hasConnection()).thenReturn(true);
when(muleNotificationProcessor.getOpenTelemetryConnection()).thenReturn(openTelemetryConnection);
}

@Test
Expand Down Expand Up @@ -193,6 +197,24 @@ public void interceptionDefaultEnabled() {
.isTrue();
}

@Test
public void interceptionDisabledWithTurnOff() {
ComponentLocation location = Mockito.mock(ComponentLocation.class);

LocationPart part1 = mock(LocationPart.class);
TypedComponentIdentifier identifier = mock(TypedComponentIdentifier.class);

TypedComponentIdentifier componentIdentifier = getComponentIdentifier(null, null);
when(location.getComponentIdentifier()).thenReturn(componentIdentifier);

when(openTelemetryConnection.isTurnOffTracing()).thenReturn(true);

assertThat(
new MessageProcessorTracingInterceptorFactory(muleNotificationProcessor, configurationComponentLocator)
.intercept(location))
.isFalse();
}

private static LocationPart getLocationPart(String path) {
LocationPart part = mock(LocationPart.class);
doReturn(part).when(part).getPartPath();
Expand Down
31 changes: 31 additions & 0 deletions src/test/resources/turn-off-tracing-by-config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/opentelemetry http://www.mulesoft.org/schema/mule/opentelemetry/current/mule-opentelemetry.xsd">
<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"
turnOffTracing="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>
<flow name="simple-flow">
<logger level="INFO" message="post:\orders:application\json:order-exp-config" />
</flow>
</mule>
Loading