Skip to content

Commit

Permalink
Adds mock implementation for TelemetryPlugin (opensearch-project#8357)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Gagan Juneja <[email protected]>
Signed-off-by: Gagan Juneja <[email protected]>
Co-authored-by: Gagan Juneja <[email protected]>
  • Loading branch information
2 people authored and vikasvb90 committed Jul 12, 2023
1 parent 8e99099 commit a729786
Show file tree
Hide file tree
Showing 15 changed files with 504 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add distributed tracing framework ([#7543](https://github.com/opensearch-project/OpenSearch/issues/7543))
- Enable Point based optimization for custom comparators ([#8168](https://github.com/opensearch-project/OpenSearch/pull/8168))
- [Extensions] Support extension additional settings with extension REST initialization ([#8414](https://github.com/opensearch-project/OpenSearch/pull/8414))
- Adds mock implementation for TelemetryPlugin ([#7545](https://github.com/opensearch-project/OpenSearch/issues/7545))

### Dependencies
- Bump `com.azure:azure-storage-common` from 12.21.0 to 12.21.1 (#7566, #7814)
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/org/opensearch/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ public synchronized void close() throws IOException {
toClose.add(injector.getInstance(NodeEnvironment.class));
toClose.add(stopWatch::stop);
if (FeatureFlags.isEnabled(TELEMETRY)) {
toClose.add(() -> injector.getInstance(TracerFactory.class));
toClose.add(injector.getInstance(TracerFactory.class));
}

if (logger.isTraceEnabled()) {
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ List projects = [
'test:fixtures:minio-fixture',
'test:fixtures:old-elasticsearch',
'test:fixtures:s3-fixture',
'test:logger-usage'
'test:logger-usage',
'test:telemetry'
]

/**
Expand Down
1 change: 1 addition & 0 deletions test/framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
api project(':libs:opensearch-nio')
api project(":server")
api project(":libs:opensearch-cli")
api project(":test:telemetry")
api "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
api "junit:junit:${versions.junit}"
api "org.hamcrest:hamcrest:${versions.hamcrest}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
import org.opensearch.common.unit.ByteSizeUnit;
import org.opensearch.common.unit.ByteSizeValue;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.common.util.FeatureFlags;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.common.xcontent.XContentHelper;
import org.opensearch.common.xcontent.XContentType;
Expand Down Expand Up @@ -152,6 +153,7 @@
import org.opensearch.test.disruption.ServiceDisruptionScheme;
import org.opensearch.test.store.MockFSIndexStore;
import org.opensearch.test.transport.MockTransportService;
import org.opensearch.test.telemetry.MockTelemetryPlugin;
import org.opensearch.transport.TransportInterceptor;
import org.opensearch.transport.TransportRequest;
import org.opensearch.transport.TransportRequestHandler;
Expand Down Expand Up @@ -776,6 +778,7 @@ protected Settings featureFlagSettings() {
for (Setting builtInFlag : FeatureFlagSettings.BUILT_IN_FEATURE_FLAGS) {
featureSettings.put(builtInFlag.getKey(), builtInFlag.getDefaultRaw(Settings.EMPTY));
}
featureSettings.put(FeatureFlags.TELEMETRY_SETTING.getKey(), true);
return featureSettings.build();
}

Expand Down Expand Up @@ -2101,6 +2104,7 @@ protected Collection<Class<? extends Plugin>> getMockPlugins() {
if (addMockGeoShapeFieldMapper()) {
mocks.add(TestGeoShapeFieldMapperPlugin.class);
}
mocks.add(MockTelemetryPlugin.class);

return Collections.unmodifiableList(mocks);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.common.util.BigArrays;
import org.opensearch.common.util.FeatureFlags;
import org.opensearch.common.util.concurrent.OpenSearchExecutors;
import org.opensearch.common.util.io.IOUtils;
import org.opensearch.core.common.Strings;
Expand All @@ -66,6 +67,8 @@
import org.opensearch.plugins.Plugin;
import org.opensearch.script.MockScriptService;
import org.opensearch.search.internal.SearchContext;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.test.telemetry.MockTelemetryPlugin;
import org.opensearch.transport.TransportSettings;
import org.junit.AfterClass;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -242,6 +245,8 @@ private Node newNode() {
.put(HierarchyCircuitBreakerService.USE_REAL_MEMORY_USAGE_SETTING.getKey(), false)
.putList(DISCOVERY_SEED_HOSTS_SETTING.getKey()) // empty list disables a port scan for other nodes
.putList(INITIAL_CLUSTER_MANAGER_NODES_SETTING.getKey(), nodeName)
.put(FeatureFlags.TELEMETRY_SETTING.getKey(), true)
.put(TelemetrySettings.TRACER_ENABLED_SETTING.getKey(), true)
.put(nodeSettings()) // allow test cases to provide their own settings or override these
.build();

Expand All @@ -254,6 +259,7 @@ private Node newNode() {
plugins.add(MockHttpTransport.TestPlugin.class);
}
plugins.add(MockScriptService.TestPlugin.class);
plugins.add(MockTelemetryPlugin.class);
Node node = new MockNode(settings, plugins, forbidPrivateIndexSettings());
try {
node.start();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.test.telemetry;

import org.opensearch.telemetry.Telemetry;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.metrics.MetricsTelemetry;
import org.opensearch.test.telemetry.tracing.MockTracingTelemetry;
import org.opensearch.telemetry.tracing.TracingTelemetry;

/**
* Mock {@link Telemetry} implementation for testing.
*/
public class MockTelemetry implements Telemetry {

private final TelemetrySettings settings;

/**
* Constructor with settings.
* @param settings telemetry settings.
*/
public MockTelemetry(TelemetrySettings settings) {
this.settings = settings;
}

@Override
public TracingTelemetry getTracingTelemetry() {
return new MockTracingTelemetry();
}

@Override
public MetricsTelemetry getMetricsTelemetry() {
return new MetricsTelemetry() {
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.test.telemetry;

import java.util.Optional;
import org.opensearch.plugins.Plugin;
import org.opensearch.plugins.TelemetryPlugin;
import org.opensearch.telemetry.Telemetry;
import org.opensearch.telemetry.TelemetrySettings;

/**
* Mock {@link TelemetryPlugin} implementation for testing.
*/
public class MockTelemetryPlugin extends Plugin implements TelemetryPlugin {
private static final String MOCK_TRACER_NAME = "mock";

/**
* Base constructor.
*/
public MockTelemetryPlugin() {

}

@Override
public Optional<Telemetry> getTelemetry(TelemetrySettings settings) {
return Optional.of(new MockTelemetry(settings));
}

@Override
public String getName() {
return MOCK_TRACER_NAME;
}
}
25 changes: 25 additions & 0 deletions test/telemetry/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

apply plugin: 'opensearch.build'
apply plugin: 'opensearch.publish'

dependencies {
api project(":libs:opensearch-common")
api project(":libs:opensearch-telemetry")
}

tasks.named('forbiddenApisMain').configure {
//package does not depend on core, so only jdk signatures should be checked
replaceSignatureFiles 'jdk-signatures'
}

test.enabled = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* 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.test.telemetry.tracing;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Supplier;
import org.opensearch.telemetry.tracing.AbstractSpan;
import org.opensearch.telemetry.tracing.Span;

/**
* MockSpan for testing and strict check validations. Not to be used for production cases.
*/
public class MockSpan extends AbstractSpan {
private final SpanProcessor spanProcessor;
private final Map<String, Object> metadata;
private final String traceId;
private final String spanId;
private boolean hasEnded;
private final Long startTime;
private Long endTime;

private final Object lock = new Object();

private static final Supplier<Random> randomSupplier = ThreadLocalRandom::current;

/**
* Base Constructor.
* @param spanName span name
* @param parentSpan parent span
* @param spanProcessor span processor
*/
public MockSpan(String spanName, Span parentSpan, SpanProcessor spanProcessor) {
this(
spanName,
parentSpan,
parentSpan != null ? parentSpan.getTraceId() : IdGenerator.generateTraceId(),
IdGenerator.generateSpanId(),
spanProcessor
);
}

/**
* Constructor with traceId and SpanIds
* @param spanName Span Name
* @param parentSpan Parent Span
* @param traceId Trace ID
* @param spanId Span ID
* @param spanProcessor Span Processor
*/
public MockSpan(String spanName, Span parentSpan, String traceId, String spanId, SpanProcessor spanProcessor) {
super(spanName, parentSpan);
this.spanProcessor = spanProcessor;
this.metadata = new HashMap<>();
this.traceId = traceId;
this.spanId = spanId;
this.startTime = System.nanoTime();
}

@Override
public void endSpan() {
synchronized (lock) {
if (hasEnded) {
return;
}
endTime = System.nanoTime();
hasEnded = true;
}
spanProcessor.onEnd(this);
}

@Override
public void addAttribute(String key, String value) {
putMetadata(key, value);
}

@Override
public void addAttribute(String key, Long value) {
putMetadata(key, value);
}

@Override
public void addAttribute(String key, Double value) {
putMetadata(key, value);
}

@Override
public void addAttribute(String key, Boolean value) {
putMetadata(key, value);
}

@Override
public void addEvent(String event) {
putMetadata(event, null);
}

private void putMetadata(String key, Object value) {
metadata.put(key, value);
}

@Override
public String getTraceId() {
return traceId;
}

@Override
public String getSpanId() {
return spanId;
}

/**
* Returns whether the span is ended or not.
* @return span end status.
*/
public boolean hasEnded() {
synchronized (lock) {
return hasEnded;
}
}

/**
* Returns the start time of the span.
* @return start time of the span.
*/
public Long getStartTime() {
return startTime;
}

/**
* Returns the start time of the span.
* @return end time of the span.
*/
public Long getEndTime() {
return endTime;
}

private static class IdGenerator {
private static String generateSpanId() {
long id = randomSupplier.get().nextLong();
return Long.toHexString(id);
}

private static String generateTraceId() {
long idHi = randomSupplier.get().nextLong();
long idLo = randomSupplier.get().nextLong();
long result = idLo | (idHi << 32);
return Long.toHexString(result);
}

}
}
Loading

0 comments on commit a729786

Please sign in to comment.