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

Add telemetry tracer/metric enable flag and integ test #10395

Merged
merged 12 commits into from
Oct 17, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Enable remote segment upload backpressure by default ([#10356](https://github.com/opensearch-project/OpenSearch/pull/10356))
- [Remote Store] Add support to reload repository metadata inplace ([#9569](https://github.com/opensearch-project/OpenSearch/pull/9569))
- [Metrics Framework] Add Metrics framework. ([#10241](https://github.com/opensearch-project/OpenSearch/pull/10241))
- Add telemetry tracer/metric enable flag and integ test. ([#10395](https://github.com/opensearch-project/OpenSearch/pull/10395))

### Deprecated

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@

import org.opensearch.common.annotation.ExperimentalApi;

import java.io.Closeable;

/**
* Interface for metrics telemetry providers
*
* @opensearch.experimental
*/
@ExperimentalApi
public interface MetricsTelemetry extends MetricsRegistry, Closeable {
public interface MetricsTelemetry extends MetricsRegistry {

}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public SpanScope withSpanInScope(Span span) {
return DefaultSpanScope.create(span, tracerContextStorage).attach();
}

@Override
public boolean isRecording() {
return true;
Gaganjuneja marked this conversation as resolved.
Show resolved Hide resolved
reta marked this conversation as resolved.
Show resolved Hide resolved
}

private Span createSpan(SpanCreationContext spanCreationContext, Span parentSpan) {
return tracingTelemetry.createSpan(spanCreationContext, parentSpan);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,10 @@ public interface Tracer extends HttpTracer, Closeable {
*/
SpanScope withSpanInScope(Span span);

/**
* Tells if the traces are being recorded or not
* @return boolean
*/
boolean isRecording();

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public SpanScope withSpanInScope(Span span) {
return SpanScope.NO_OP;
}

@Override
public boolean isRecording() {
return false;
}

@Override
public void close() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void testCreateSpan() {

String spanName = defaultTracer.getCurrentSpan().getSpan().getSpanName();
assertEquals("span_name", spanName);
assertTrue(defaultTracer.isRecording());
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@
* compatible open source license.
*/

package org.opensearch.telemetry.tracing;
package org.opensearch.telemetry;

import org.opensearch.common.settings.Settings;
import org.opensearch.telemetry.OTelTelemetryPlugin;
import org.opensearch.telemetry.Telemetry;
import org.opensearch.telemetry.TelemetrySettings;

import java.util.Optional;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

import java.util.Collection;
import java.util.List;

import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter;

public class InMemorySingletonMetricsExporter implements MetricExporter {

public static final InMemorySingletonMetricsExporter INSTANCE = new InMemorySingletonMetricsExporter(InMemoryMetricExporter.create());

private static InMemoryMetricExporter delegate;

public static InMemorySingletonMetricsExporter create() {
return INSTANCE;
}

private InMemorySingletonMetricsExporter(InMemoryMetricExporter delegate) {
InMemorySingletonMetricsExporter.delegate = delegate;
}

@Override
public CompletableResultCode export(Collection<MetricData> metrics) {
return delegate.export(metrics);
}

@Override
public CompletableResultCode flush() {
return delegate.flush();
}

@Override
public CompletableResultCode shutdown() {
return delegate.shutdown();
}

public List<MetricData> getFinishedMetricItems() {
return delegate.getFinishedMetricItems();
}

/**
* Clears the state.
*/
public void reset() {
delegate.reset();
}

@Override
public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) {
return delegate.getAggregationTemporality(instrumentType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.plugins.Plugin;
import org.opensearch.telemetry.IntegrationTestOTelTelemetryPlugin;
import org.opensearch.telemetry.OTelTelemetrySettings;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.metrics.noop.NoopCounter;
import org.opensearch.telemetry.metrics.noop.NoopMetricsRegistry;
import org.opensearch.test.OpenSearchIntegTestCase;

import java.util.Arrays;
import java.util.Collection;

@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.TEST, minNumDataNodes = 1)
public class TelemetryMetricsDisabledSanityIT extends OpenSearchIntegTestCase {

@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(TelemetrySettings.METRICS_FEATURE_ENABLED_SETTING.getKey(), false)
.put(
OTelTelemetrySettings.OTEL_METRICS_EXPORTER_CLASS_SETTING.getKey(),
"org.opensearch.telemetry.metrics.InMemorySingletonMetricsExporter"
)
.put(TelemetrySettings.METRICS_PUBLISH_INTERVAL_SETTING.getKey(), TimeValue.timeValueSeconds(1))
.build();
}

@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(IntegrationTestOTelTelemetryPlugin.class);
}

@Override
protected boolean addMockTelemetryPlugin() {
return false;
}

public void testSanityChecksWhenMetricsDisabled() throws Exception {
MetricsRegistry metricsRegistry = internalCluster().getInstance(MetricsRegistry.class);

Counter counter = metricsRegistry.createCounter("test-counter", "test", "1");
counter.add(1.0);

Thread.sleep(2000);

assertTrue(metricsRegistry instanceof NoopMetricsRegistry);
assertTrue(counter instanceof NoopCounter);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.plugins.Plugin;
import org.opensearch.telemetry.IntegrationTestOTelTelemetryPlugin;
import org.opensearch.telemetry.OTelTelemetrySettings;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.test.OpenSearchIntegTestCase;
import org.junit.After;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import io.opentelemetry.sdk.metrics.data.DoublePointData;

@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.SUITE, minNumDataNodes = 1)
public class TelemetryMetricsEnabledSanityIT extends OpenSearchIntegTestCase {

@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(TelemetrySettings.METRICS_FEATURE_ENABLED_SETTING.getKey(), true)
.put(
OTelTelemetrySettings.OTEL_METRICS_EXPORTER_CLASS_SETTING.getKey(),
"org.opensearch.telemetry.metrics.InMemorySingletonMetricsExporter"
)
.put(TelemetrySettings.METRICS_PUBLISH_INTERVAL_SETTING.getKey(), TimeValue.timeValueSeconds(1))
.build();
}

@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(IntegrationTestOTelTelemetryPlugin.class);
}

@Override
protected boolean addMockTelemetryPlugin() {
return false;
}

public void testCounter() throws Exception {
MetricsRegistry metricsRegistry = internalCluster().getInstance(MetricsRegistry.class);
InMemorySingletonMetricsExporter.INSTANCE.reset();

Counter counter = metricsRegistry.createCounter("test-counter", "test", "1");
counter.add(1.0);
// Sleep for about 2s to wait for metrics to be published.
Thread.sleep(2000);

InMemorySingletonMetricsExporter exporter = InMemorySingletonMetricsExporter.INSTANCE;
double value = ((DoublePointData) ((ArrayList) exporter.getFinishedMetricItems()
.stream()
.filter(a -> a.getName().equals("test-counter"))
.collect(Collectors.toList())
.get(0)
.getDoubleSumData()
.getPoints()).get(0)).getValue();
assertEquals(1.0, value, 0.0);
}

public void testUpDownCounter() throws Exception {

MetricsRegistry metricsRegistry = internalCluster().getInstance(MetricsRegistry.class);
InMemorySingletonMetricsExporter.INSTANCE.reset();

Counter counter = metricsRegistry.createUpDownCounter("test-up-down-counter", "test", "1");
counter.add(1.0);
counter.add(-2.0);
// Sleep for about 2s to wait for metrics to be published.
Thread.sleep(2000);

InMemorySingletonMetricsExporter exporter = InMemorySingletonMetricsExporter.INSTANCE;
double value = ((DoublePointData) ((ArrayList) exporter.getFinishedMetricItems()
.stream()
.filter(a -> a.getName().equals("test-up-down-counter"))
.collect(Collectors.toList())
.get(0)
.getDoubleSumData()
.getPoints()).get(0)).getValue();
assertEquals(-1.0, value, 0.0);
}

@After
public void reset() {
InMemorySingletonMetricsExporter.INSTANCE.reset();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.plugins.Plugin;
import org.opensearch.telemetry.IntegrationTestOTelTelemetryPlugin;
Gaganjuneja marked this conversation as resolved.
Show resolved Hide resolved
import org.opensearch.telemetry.OTelTelemetrySettings;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.test.OpenSearchIntegTestCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.plugins.Plugin;
import org.opensearch.telemetry.IntegrationTestOTelTelemetryPlugin;
import org.opensearch.telemetry.OTelTelemetrySettings;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.tracing.attributes.Attributes;
Expand Down Expand Up @@ -88,9 +89,7 @@ public void testSanityChecksWhenTracingEnabled() throws Exception {
);

InMemorySingletonSpanExporter exporter = InMemorySingletonSpanExporter.INSTANCE;
if (!exporter.getFinishedSpanItems().isEmpty()) {
validators.validate(exporter.getFinishedSpanItems(), 6);
}
validators.validate(exporter.getFinishedSpanItems(), 6);
}

private static void updateTelemetrySetting(Client client, boolean value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@

package org.opensearch.telemetry;

import org.opensearch.common.concurrent.RefCountedReleasable;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.plugins.Plugin;
import org.opensearch.plugins.TelemetryPlugin;
import org.opensearch.telemetry.metrics.OTelMetricsTelemetry;
import org.opensearch.telemetry.tracing.OTelResourceProvider;
import org.opensearch.telemetry.tracing.OTelTelemetry;
import org.opensearch.telemetry.tracing.OTelTracingTelemetry;

import java.util.Arrays;
import java.util.List;
Expand All @@ -37,6 +36,8 @@ public class OTelTelemetryPlugin extends Plugin implements TelemetryPlugin {

private final Settings settings;

private RefCountedReleasable<OpenTelemetrySdk> refCountedOpenTelemetry;

/**
* Creates Otel plugin
* @param settings cluster settings
Expand All @@ -58,20 +59,29 @@ public List<Setting<?>> getSettings() {

@Override
public Optional<Telemetry> getTelemetry(TelemetrySettings telemetrySettings) {
initializeOpenTelemetrySdk(telemetrySettings);
return Optional.of(telemetry(telemetrySettings));
}

private void initializeOpenTelemetrySdk(TelemetrySettings telemetrySettings) {
OpenTelemetrySdk openTelemetrySdk = OTelResourceProvider.get(telemetrySettings, settings);
Gaganjuneja marked this conversation as resolved.
Show resolved Hide resolved
refCountedOpenTelemetry = new RefCountedReleasable<>("openTelemetry", openTelemetrySdk, openTelemetrySdk::close);
}

@Override
public String getName() {
return OTEL_TRACER_NAME;
}

private Telemetry telemetry(TelemetrySettings telemetrySettings) {
final OpenTelemetrySdk openTelemetry = OTelResourceProvider.get(telemetrySettings, settings);
return new OTelTelemetry(
new OTelTracingTelemetry<>(openTelemetry, openTelemetry.getSdkTracerProvider()),
new OTelMetricsTelemetry<>(openTelemetry.getSdkMeterProvider())
);
return new OTelTelemetry(refCountedOpenTelemetry);
}

@Override
public void close() {
if (refCountedOpenTelemetry != null) {
refCountedOpenTelemetry.close();
}
}

}
Loading
Loading