diff --git a/modules/core/src/main/java/org/apache/ignite/Ignite.java b/modules/core/src/main/java/org/apache/ignite/Ignite.java index 7332eaa91a0415..194a7e993d0c3a 100644 --- a/modules/core/src/main/java/org/apache/ignite/Ignite.java +++ b/modules/core/src/main/java/org/apache/ignite/Ignite.java @@ -31,11 +31,14 @@ import org.apache.ignite.configuration.DataStorageConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.lang.IgniteExperimental; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; /** * Main entry-point for all Ignite APIs. @@ -741,4 +744,18 @@ public IgniteQueue queue(String name, int cap, @Nullable CollectionConfig * @return Snapshot manager. */ public IgniteSnapshot snapshot(); + + /** + * Returns the {@link TracingConfigurationManager} instance that allows to + * + * @return {@link TracingConfigurationManager} instance. + */ + @IgniteExperimental + public @NotNull TracingConfigurationManager tracingConfiguration(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index e9d4ba00ea7749..6b653bbe376739 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -192,6 +192,7 @@ import org.apache.ignite.internal.processors.subscription.GridInternalSubscriptionProcessor; import org.apache.ignite.internal.processors.task.GridTaskProcessor; import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; import org.apache.ignite.internal.suggestions.JvmConfigurationSuggestions; import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions; @@ -233,6 +234,7 @@ import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode; import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2; @@ -4003,6 +4005,18 @@ private Collection baselineNodes() { } } + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager tracingConfiguration() { + guard(); + + try { + return ctx.tracing().configuration(); + } + finally { + unguard(); + } + } + /** {@inheritDoc} */ @Override public IgniteEncryption encryption() { return ctx.encryption(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/tracing/GridTracingManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/tracing/GridTracingManager.java index b3eabe4514512f..2da83fea7b100c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/tracing/GridTracingManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/tracing/GridTracingManager.java @@ -18,7 +18,6 @@ package org.apache.ignite.internal.managers.tracing; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.ignite.IgniteCheckedException; @@ -28,22 +27,28 @@ import org.apache.ignite.internal.processors.tracing.DeferredSpan; import org.apache.ignite.internal.processors.tracing.NoopSpan; import org.apache.ignite.internal.processors.tracing.NoopTracing; -import org.apache.ignite.internal.processors.tracing.Span; import org.apache.ignite.internal.processors.tracing.SpanImpl; +import org.apache.ignite.internal.processors.tracing.configuration.GridTracingConfigurationManager; +import org.apache.ignite.spi.tracing.NoopTracingSpi; +import org.apache.ignite.spi.tracing.Scope; +import org.apache.ignite.internal.processors.tracing.Span; import org.apache.ignite.internal.processors.tracing.SpanTags; import org.apache.ignite.internal.processors.tracing.SpanType; import org.apache.ignite.internal.processors.tracing.Tracing; +import org.apache.ignite.spi.tracing.SpiSpecificSpan; +import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; +import org.apache.ignite.spi.tracing.TracingSpi; +import org.apache.ignite.spi.tracing.TracingConfigurationParameters; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesHandler; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.logger.NullLogger; import org.apache.ignite.spi.IgniteSpiException; -import org.apache.ignite.spi.tracing.NoopTracingSpi; -import org.apache.ignite.spi.tracing.Scope; -import org.apache.ignite.spi.tracing.TracingSpi; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.internal.processors.tracing.SpanTags.NODE; +import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_NEVER; import static org.apache.ignite.internal.util.GridClientByteUtils.bytesToInt; import static org.apache.ignite.internal.util.GridClientByteUtils.bytesToShort; import static org.apache.ignite.internal.util.GridClientByteUtils.intToBytes; @@ -86,6 +91,9 @@ public class GridTracingManager extends GridManagerAdapter implement /** Traceable messages handler. */ private final TraceableMessagesHandler msgHnd; + /** Tracing configuration */ + private final TracingConfigurationManager tracingConfiguration; + /** * Major span serialization protocol version. * Within same major protocol version span serialization should be backward compatible. @@ -114,6 +122,8 @@ public GridTracingManager(GridKernalContext ctx, boolean useNoopTracingSpi) { super(ctx, useNoopTracingSpi ? new NoopTracingSpi() : ctx.config().getTracingSpi()); msgHnd = new TraceableMessagesHandler(this, ctx.log(GridTracingManager.class)); + + tracingConfiguration = new GridTracingConfigurationManager(ctx); } /** @@ -168,9 +178,16 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { /** {@inheritDoc} */ @Override public Span create(@NotNull SpanType spanType, @Nullable Span parentSpan) { + // Optimization for noop spi. if (noop) return NoopSpan.INSTANCE; + // Optimization for zero sampling rate == 0. + if ((parentSpan == NoopSpan.INSTANCE || parentSpan == null) && + tracingConfiguration.get(new TracingConfigurationCoordinates.Builder(spanType.scope()).build()). + samplingRate() == SAMPLING_RATE_NEVER) + return NoopSpan.INSTANCE; + return enrichWithLocalNodeParameters( generateSpan( parentSpan, @@ -180,9 +197,16 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { /** {@inheritDoc} */ @Override public Span create(@NotNull SpanType spanType, @Nullable byte[] serializedParentSpan) { + // Optimization for noop spi. if (noop) return NoopSpan.INSTANCE; + // Optimization for zero sampling rate == 0. + if ((serializedParentSpan.length == 0 || serializedParentSpan == null) && + tracingConfiguration.get(new TracingConfigurationCoordinates.Builder(spanType.scope()).build()). + samplingRate() == SAMPLING_RATE_NEVER) + return NoopSpan.INSTANCE; + // 1 byte: special flags; // 1 bytes: spi type; // 2 bytes: major protocol version; @@ -196,7 +220,7 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { Span span; try { - if (serializedParentSpan == null || serializedParentSpan == NoopTracing.NOOP_SERIALIZED_SPAN) + if (serializedParentSpan == null || serializedParentSpan.length == 0) return create(spanType, NoopSpan.INSTANCE); // First byte of the serializedSpan is reserved for special flags - it's not used right now. @@ -311,9 +335,17 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { @Nullable Span parentSpan, @Nullable String lb ) { + // Optimization for noop spi. if (noop) return NoopSpan.INSTANCE; + // Optimization for zero sampling rate == 0. + if ((parentSpan == NoopSpan.INSTANCE || parentSpan == null) && + tracingConfiguration.get( + new TracingConfigurationCoordinates.Builder(spanType.scope()).withLabel(lb).build()). + samplingRate() == SAMPLING_RATE_NEVER) + return NoopSpan.INSTANCE; + return enrichWithLocalNodeParameters( generateSpan( parentSpan, @@ -322,10 +354,16 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public byte[] serialize(@NotNull Span span) { + // Optimization for noop spi. if (noop) return NoopTracing.NOOP_SERIALIZED_SPAN; + // Optimization for NoopSpan. + if (span == NoopSpan.INSTANCE) + return NoopTracing.NOOP_SERIALIZED_SPAN; + // 1 byte: special flags; // 1 bytes: spi type; // 2 bytes: major protocol version; @@ -339,10 +377,6 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { if (span instanceof DeferredSpan) return ((DeferredSpan)span).serializedSpan(); - // Optimization for NoopSpan. - if (span == NoopSpan.INSTANCE) - return NoopTracing.NOOP_SERIALIZED_SPAN; - // Spi specific serialized span. byte[] spiSpecificSerializedSpan = getSpi().serialize(((SpanImpl)span).spiSpecificSpan()); @@ -422,6 +456,7 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { * @param spanTypeToCreate Span type to create. * @param lb Label. */ + @SuppressWarnings("unchecked") private @NotNull Span generateSpan( @Nullable Span parentSpan, @NotNull SpanType spanTypeToCreate, @@ -430,16 +465,20 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { if (parentSpan instanceof DeferredSpan) return create(spanTypeToCreate, ((DeferredSpan)parentSpan).serializedSpan()); - if (parentSpan == null || parentSpan == NoopSpan.INSTANCE) { + if (parentSpan == NoopSpan.INSTANCE || parentSpan == null) { if (spanTypeToCreate.rootSpan()) { - - return new SpanImpl( - getSpi().create( - spanTypeToCreate.spanName(), - null, - 1), - spanTypeToCreate, - Collections.emptySet()); + // Get tracing configuration. + TracingConfigurationParameters tracingConfigurationParameters = tracingConfiguration.get( + new TracingConfigurationCoordinates.Builder(spanTypeToCreate.scope()).withLabel(lb).build()); + + return shouldSample(tracingConfigurationParameters.samplingRate()) ? + new SpanImpl( + getSpi().create( + spanTypeToCreate.spanName(), + (SpiSpecificSpan)null), + spanTypeToCreate, + tracingConfigurationParameters.includedScopes()) : + NoopSpan.INSTANCE; } else return NoopSpan.INSTANCE; @@ -457,8 +496,7 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { return new SpanImpl( getSpi().create( spanTypeToCreate.spanName(), - ((SpanImpl)parentSpan).spiSpecificSpan(), - 1), + ((SpanImpl)parentSpan).spiSpecificSpan()), spanTypeToCreate, mergedIncludedScopes); } @@ -471,9 +509,26 @@ private Span enrichWithLocalNodeParameters(@Nullable Span span) { /** {@inheritDoc} */ @Override public TraceableMessagesHandler messages() { + // Optimization for noop spi. if (noop) return NOOP_TRACEABLE_MSG_HANDLER; return msgHnd; } -} + + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager configuration() { + return tracingConfiguration; + } + + /** + * @param samlingRate Sampling rate. + * @return {@code true} if according to given sampling-rate span should be sampled. + */ + private boolean shouldSample(double samlingRate) { + if (samlingRate == SAMPLING_RATE_NEVER) + return false; + + return Math.random() <= samlingRate; + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/NoopTracing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/NoopTracing.java index 5aa8a72f3114bf..0427bb0de81025 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/NoopTracing.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/NoopTracing.java @@ -17,6 +17,8 @@ package org.apache.ignite.internal.processors.tracing; +import org.apache.ignite.internal.processors.tracing.configuration.NoopTracingConfigurationManager; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesHandler; import org.apache.ignite.logger.NullLogger; import org.jetbrains.annotations.NotNull; @@ -66,4 +68,9 @@ public NoopTracing() { @Override public byte[] serialize(@NotNull Span span) { return NOOP_SERIALIZED_SPAN; } + + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager configuration() { + return NoopTracingConfigurationManager.INSTANCE; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/Tracing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/Tracing.java index bc957c54cc29b2..8bc9a804511090 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/Tracing.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/Tracing.java @@ -18,6 +18,8 @@ package org.apache.ignite.internal.processors.tracing; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesHandler; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; +import org.jetbrains.annotations.NotNull; /** * Tracing sub-system interface. @@ -27,4 +29,17 @@ public interface Tracing extends SpanManager { * @return Helper to handle traceable messages. */ public TraceableMessagesHandler messages(); + + /** + * Returns the {@link TracingConfigurationManager} instance that allows to + *
    + *
  • Configure tracing parameters such as sampling rate for the specific tracing coordinates + * such as scope and label.
  • + *
  • Retrieve the most specific tracing parameters for the specified tracing coordinates (scope and label)
  • + *
  • Restore the tracing parameters for the specified tracing coordinates to the default.
  • + *
  • List all pairs of tracing configuration coordinates and tracing configuration parameters.
  • + *
+ * @return {@link TracingConfigurationManager} instance. + */ + public @NotNull TracingConfigurationManager configuration(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java new file mode 100644 index 00000000000000..fd74c84569f157 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.tracing.configuration; + +import java.util.HashMap; +import org.apache.ignite.internal.processors.configuration.distributed.SimpleDistributedProperty; +import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates; +import org.apache.ignite.spi.tracing.TracingConfigurationParameters; +import org.apache.ignite.internal.processors.configuration.distributed.DistributedConfigurationProcessor; + +/** + * The wrapper of {@code HashMap} + * for the distributed metastorage binding. + */ +public class DistributedTracingConfiguration + extends SimpleDistributedProperty> { + /** */ + private static final String TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY = "tr.config"; + + /** + * Constructor. + */ + public DistributedTracingConfiguration() { + super(TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY); + } + + /** + * @return A new property that is detached from {@link DistributedConfigurationProcessor}. + * This means distributed updates are not accessible. + */ + public static DistributedTracingConfiguration detachedProperty() { + return new DistributedTracingConfiguration(); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/GridTracingConfigurationManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/GridTracingConfigurationManager.java new file mode 100644 index 00000000000000..cd03738efee1ff --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/GridTracingConfigurationManager.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.tracing.configuration; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.spi.tracing.Scope; +import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; +import org.apache.ignite.spi.tracing.TracingConfigurationParameters; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Tracing configuration manager implementation that uses distributed meta storage + * in order to store tracing configuration. + */ +public class GridTracingConfigurationManager implements TracingConfigurationManager { + /** Map with default configurations. */ + private static final Map DEFAULT_CONFIGURATION_MAP; + + /** */ + public static final String WARNING_MSG_TRACING_CONFIG_UPDATE_FAILED_COORDINATES = + "Failed to update tracing configuration for coordinates=[%s]."; + + /** */ + public static final String WARNING_MSG_TRACING_CONFIG_UPDATE_FAILED_SCOPE = + "Failed to update tracing configuration for scope=[%s]."; + + /** Tracing configuration distributed property. */ + private final DistributedTracingConfiguration distributedTracingConfiguration = + DistributedTracingConfiguration.detachedProperty(); + + /** Tracing configuration. */ + private volatile Map tracingConfiguration = + DEFAULT_CONFIGURATION_MAP; + + /** Mutex for updating local tracing configuration. */ + @GridToStringExclude + private final Object mux = new Object(); + + static { + Map tmpDfltConfigurationMap = new HashMap<>(); + + tmpDfltConfigurationMap.put( + new TracingConfigurationCoordinates.Builder(Scope.TX).build(), + TracingConfigurationManager.DEFAULT_TX_CONFIGURATION); + + tmpDfltConfigurationMap.put( + new TracingConfigurationCoordinates.Builder(Scope.COMMUNICATION).build(), + TracingConfigurationManager.DEFAULT_COMMUNICATION_CONFIGURATION); + + tmpDfltConfigurationMap.put( + new TracingConfigurationCoordinates.Builder(Scope.EXCHANGE).build(), + TracingConfigurationManager.DEFAULT_EXCHANGE_CONFIGURATION); + + tmpDfltConfigurationMap.put( + new TracingConfigurationCoordinates.Builder(Scope.DISCOVERY).build(), + TracingConfigurationManager.DEFAULT_DISCOVERY_CONFIGURATION); + + DEFAULT_CONFIGURATION_MAP = Collections.unmodifiableMap(tmpDfltConfigurationMap); + } + + /** Kernal context. */ + @GridToStringExclude + protected final GridKernalContext ctx; + + /** Grid logger. */ + @GridToStringExclude + protected final IgniteLogger log; + + /** + * Constructor. + * + * @param ctx Context. + */ + public GridTracingConfigurationManager(@NotNull GridKernalContext ctx) { + this.ctx = ctx; + + log = ctx.log(getClass()); + + ctx.internalSubscriptionProcessor().registerDistributedConfigurationListener(dispatcher -> { + distributedTracingConfiguration.addListener((name, oldVal, newVal) -> { + synchronized (mux) { + if (log.isDebugEnabled()) + log.debug("Tracing configuration was updated [oldVal= " + oldVal + ", newVal=" + newVal + "]"); + + if (newVal != null && !newVal.isEmpty()) + tracingConfiguration = newVal; + } + }); + + dispatcher.registerProperty(distributedTracingConfiguration); + }); + } + + /** {@inheritDoc} */ + @Override public void set( + @NotNull TracingConfigurationCoordinates coordinates, + @NotNull TracingConfigurationParameters parameters) + { + HashMap newTracingConfiguration = + new HashMap<>(tracingConfiguration); + + newTracingConfiguration.put(coordinates, parameters); + + try { + distributedTracingConfiguration.propagate(newTracingConfiguration); + } + catch (IgniteCheckedException e) { + String warningMsg = String.format(WARNING_MSG_TRACING_CONFIG_UPDATE_FAILED_COORDINATES, coordinates); + + log.warning(warningMsg, e); + + throw new IgniteException(warningMsg, e); + } + } + + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationParameters get(@NotNull TracingConfigurationCoordinates coordinates) { + TracingConfigurationParameters coordinateSpecificParameters = tracingConfiguration.get(coordinates); + + // If parameters for the specified coordinates (both scope and label) were not found use only scope specific one. + // If there are no custom scope specific parameters, default one will be used. + return coordinateSpecificParameters == null ? + tracingConfiguration.get(new TracingConfigurationCoordinates.Builder(coordinates.scope()).build()) : + coordinateSpecificParameters; + } + + /** {@inheritDoc} */ + @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType") + @Override public @NotNull Map getAll( + @Nullable Scope scope) { + return scope != null ? + tracingConfiguration.entrySet().stream(). + filter(e -> e.getKey().scope() == scope). + collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) : + tracingConfiguration; + } + + /** {@inheritDoc} */ + @Override public void reset(@NotNull TracingConfigurationCoordinates coordinates) { + HashMap newTracingConfiguration = + new HashMap<>(tracingConfiguration); + + if (coordinates.label() != null) + newTracingConfiguration.remove(coordinates); + else + newTracingConfiguration.put(coordinates, DEFAULT_CONFIGURATION_MAP.get(new TracingConfigurationCoordinates.Builder(coordinates.scope()).build())); + + try { + distributedTracingConfiguration.propagate(newTracingConfiguration); + } + catch (IgniteCheckedException e) { + String warningMsg = String.format(WARNING_MSG_TRACING_CONFIG_UPDATE_FAILED_COORDINATES, coordinates); + + log.warning(warningMsg, e); + + throw new IgniteException(warningMsg, e); + } + } + + /** {@inheritDoc} */ + @Override public void resetAll(@Nullable Scope scope) throws IgniteException { + HashMap newTracingConfiguration; + + if (scope != null) { + newTracingConfiguration = new HashMap<>(tracingConfiguration.entrySet().stream(). + filter(e -> e.getKey().scope() != scope). + collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + + TracingConfigurationCoordinates scopeSpecificCoordinates = + new TracingConfigurationCoordinates.Builder(scope).build(); + + newTracingConfiguration.put(scopeSpecificCoordinates, + DEFAULT_CONFIGURATION_MAP.get(scopeSpecificCoordinates)); + } + else + newTracingConfiguration = new HashMap<>(DEFAULT_CONFIGURATION_MAP); + + try { + distributedTracingConfiguration.propagate(newTracingConfiguration); + } + catch (IgniteCheckedException e) { + String warningMsg = String.format(WARNING_MSG_TRACING_CONFIG_UPDATE_FAILED_SCOPE, scope); + + log.warning(warningMsg, e); + + throw new IgniteException(warningMsg, e); + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/NoopTracingConfigurationManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/NoopTracingConfigurationManager.java new file mode 100644 index 00000000000000..3345148f5c6d58 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/NoopTracingConfigurationManager.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.tracing.configuration; + +import java.util.Collections; +import java.util.Map; + +import org.apache.ignite.IgniteException; +import org.apache.ignite.spi.tracing.Scope; +import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; +import org.apache.ignite.spi.tracing.TracingConfigurationParameters; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Noop tracing configuration manager. + * To be used mainly with {@link org.apache.ignite.internal.processors.tracing.NoopTracing}. + */ +public final class NoopTracingConfigurationManager implements TracingConfigurationManager { + /** */ + public static final NoopTracingConfigurationManager INSTANCE = new NoopTracingConfigurationManager(); + + /** {@inheritDoc} */ + @Override public void set(@NotNull TracingConfigurationCoordinates coordinates, + @NotNull TracingConfigurationParameters parameters) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationParameters get( + @NotNull TracingConfigurationCoordinates coordinates) { + return TracingConfigurationManager.NOOP_CONFIGURATION; + } + + /** {@inheritDoc} */ + @Override public @NotNull Map getAll( + @Nullable Scope scope + ) { + return Collections.emptyMap(); + } + + /** {@inheritDoc} */ + @Override public void reset(@NotNull TracingConfigurationCoordinates coordinates) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void resetAll(@Nullable Scope scope) throws IgniteException { + // No-op. + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/tracing/NoopTracingSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/tracing/NoopTracingSpi.java index dfb785a026b43c..9ddb63d936b82a 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/tracing/NoopTracingSpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/tracing/NoopTracingSpi.java @@ -42,8 +42,7 @@ public class NoopTracingSpi extends IgniteSpiAdapter implements TracingSpi + *
  • + * If there's tracing configuration that matches all tracing configuration attributes (scope and label) — + * it'll be returned. + *
  • + *
  • + * If there's no tracing configuration with specified label, or label wasn't specified — + * scope specific tracing configuration will be returned. + *
  • + *
  • + * If there's no tracing configuration with specified scope — + * default scope specific configuration will be returned. + *
  • + * + * + * @param coordinates {@link TracingConfigurationCoordinates} Specific set of locators like {@link Scope} and label + * that defines a subset of traces and/or spans that'll use given configuration. + * @return {@link TracingConfigurationParameters} instance. + * @throws IgniteException If failed to get tracing configuration. + */ + default @NotNull TracingConfigurationParameters get( + @NotNull TracingConfigurationCoordinates coordinates) throws IgniteException + { + switch (coordinates.scope()) { + case TX: { + return DEFAULT_TX_CONFIGURATION; + } + + case EXCHANGE: { + return DEFAULT_EXCHANGE_CONFIGURATION; + } + + case DISCOVERY: { + return DEFAULT_DISCOVERY_CONFIGURATION; + } + + case COMMUNICATION: { + return DEFAULT_COMMUNICATION_CONFIGURATION; + } + + default: { + return NOOP_CONFIGURATION; + } + } + } + + /** + * List all pairs of tracing configuration coordinates and tracing configuration parameters + * or list all pairs of tracing configuration and parameters for the specific scope. + * + * @param scope Nullable scope of tracing configuration to be retrieved. + * If null - all configuration will be returned. + * @return The whole set of tracing configuration. + * @throws IgniteException If failed to get tracing configuration. + */ + @NotNull Map getAll( + @Nullable Scope scope) throws IgniteException; + + /** + * Reset tracing configuration for the specific tracing coordinates (scope, label, etc.) to default values. + * Please pay attention, that there's no default values for label specific coordinates, + * so such kinds of configurations will be removed. + * + * @param coordinates {@link TracingConfigurationCoordinates} specific set of locators like {@link Scope} and label + * that defines a subset of traces and/or spans that will be reset. + * @throws IgniteException If failed to reset tracing configuration. + */ + void reset(@NotNull TracingConfigurationCoordinates coordinates) throws IgniteException; + + /** + * Reset tracing configuration for the specific scope, or all tracing configurations if scope not specified. + * + * @param scope {@link Scope} that defines a set of applicable tracing configurations. + * @throws IgniteException If failed to reset tracing configuration. + */ + void resetAll(@Nullable Scope scope) throws IgniteException; +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingConfigurationParameters.java b/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingConfigurationParameters.java new file mode 100644 index 00000000000000..b4c90ac6dd40fd --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingConfigurationParameters.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.tracing; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Set; +import org.apache.ignite.internal.processors.tracing.Span; +import org.jetbrains.annotations.NotNull; + +/** + * Set of tracing configuration parameters like sampling rate or included scopes. + */ +public class TracingConfigurationParameters implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Min valid sampling rate with special meaning that span won't be created. */ + public static final double SAMPLING_RATE_NEVER = 0d; + + /** Max valid sampling rate with special meaning that span will be always created. */ + public static final double SAMPLING_RATE_ALWAYS = 1d; + + /** + * Number between 0 and 1 that more or less reflects the probability of sampling a specific trace. + * 0 and 1 have special meaning here, 0 means never 1 means always. Default value is 0 (never). + */ + private final double samplingRate; + + /** + * Set of {@link Scope} that defines which sub-traces will be included in a given trace. + * In other words, if the child's span scope is equal to parent's scope + * or it belongs to the parent's span included scopes, then the given child span will be attached to the current trace, + * otherwise it'll be skipped. + * See {@link Span#isChainable(Scope)} for more details. + */ + private final Set includedScopes; + + /** + * Constructor. + * + * @param samplingRate Number between 0 and 1 that more or less reflects the probability of sampling specific trace. + * 0 and 1 have special meaning here, 0 means never 1 means always. Default value is 0 (never). + * @param includedScopes Set of {@link Scope} that defines which sub-traces will be included in given trace. + * In other words, if child's span scope is equals to parent's scope + * or it belongs to the parent's span included scopes, then given child span will be attached to the current trace, + * otherwise it'll be skipped. + * See {@link Span#isChainable(Scope)} for more details. + */ + private TracingConfigurationParameters(double samplingRate, + Set includedScopes) { + this.samplingRate = samplingRate; + this.includedScopes = Collections.unmodifiableSet(includedScopes); + } + + /** + * @return Number between 0 and 1 that more or less reflects the probability of sampling specific trace. + * 0 and 1 have special meaning here, 0 means never 1 means always. Default value is 0 (never). + */ + public double samplingRate() { + return samplingRate; + } + + /** + * @return Set of {@link Scope} that defines which sub-traces will be included in given trace. + * In other words, if child's span scope is equals to parent's scope + * or it belongs to the parent's span included scopes, then given child span will be attached to the current trace, + * otherwise it'll be skipped. + * See {@link Span#isChainable(Scope)} for more details. + * If no scopes are specified, empty set will be returned. + */ + public @NotNull Set includedScopes() { + return Collections.unmodifiableSet(includedScopes); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + TracingConfigurationParameters that = (TracingConfigurationParameters)o; + + if (Double.compare(that.samplingRate, samplingRate) != 0) + return false; + return includedScopes != null ? includedScopes.equals(that.includedScopes) : that.includedScopes == null; + } + + /** + * {@code TracingConfigurationParameters} builder. + */ + @SuppressWarnings("PublicInnerClass") public static class Builder { + /** Counterpart of {@code TracingConfigurationParameters} samplingRate. */ + private double samplingRate; + + /** Counterpart of {@code TracingConfigurationParameters} includedScopes. */ + private Set includedScopes = Collections.emptySet(); + + /** + * Builder method that allows to set sampling rate. + * + * @param samplingRate Number between 0 and 1 that more or less reflects the probability of sampling specific trace. + * 0 and 1 have special meaning here, 0 means never 1 means always. Default value is 0 (never). + * @return {@code TracingConfigurationParameters} instance. + */ + public @NotNull Builder withSamplingRate(double samplingRate) { + if (samplingRate < SAMPLING_RATE_NEVER || samplingRate > SAMPLING_RATE_ALWAYS) { + throw new IllegalArgumentException("Specified sampling rate=[" + samplingRate + "] has invalid value." + + " Should be between 0 and 1 including boundaries."); + } + this.samplingRate = samplingRate; + + return this; + } + + /** + * Builder method that allows to set included scopes. + * + * @param includedScopes Set of {@link Scope} that defines which sub-traces will be included in given trace. + * In other words, if child's span scope is equals to parent's scope + * or it belongs to the parent's span included scopes, then given child span will be attached to the current trace, + * otherwise it'll be skipped. + * See {@link Span#isChainable(Scope)} for more details. + * @return {@code TracingConfigurationParameters} instance. + */ + public @NotNull Builder withIncludedScopes(Set includedScopes) { + this.includedScopes = includedScopes == null ? Collections.emptySet() : includedScopes; + + return this; + } + + /** + * Builder's build() method. + * + * @return {@code TracingConfigurationParameters} instance. + */ + public TracingConfigurationParameters build() { + return new TracingConfigurationParameters(samplingRate, includedScopes); + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingSpi.java index 71d375566098a4..adcb5e69d84561 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingSpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/tracing/TracingSpi.java @@ -40,14 +40,10 @@ public interface TracingSpi extends IgniteSpi { * * @param name Name of span to create. * @param parentSpan Parent span. - * @param samplingRate Number between 0 and 1 that more or less reflects the probability of sampling specific trace. - * 0 and 1 have special meaning here, 0 means never 1 means always. Default value is 0 (never). - * @return Created span. */ @NotNull S create( @NotNull String name, - @Nullable S parentSpan, - double samplingRate); + @Nullable S parentSpan); /** * Serializes span to byte array to send context over network. diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java index bd7b913d79a965..4c7e984f18e446 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java @@ -64,12 +64,15 @@ import org.apache.ignite.internal.processors.cache.GridCacheUtilityKey; import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.hadoop.Hadoop; +import org.apache.ignite.internal.processors.tracing.configuration.NoopTracingConfigurationManager; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -623,6 +626,11 @@ public IgfsIgniteMock(@Nullable String name, IgniteFileSystem igfs) { return null; } + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager tracingConfiguration() { + return NoopTracingConfigurationManager.INSTANCE; + } + /** {@inheritDoc} */ @Override public Collection memoryMetrics() { return DataRegionMetricsAdapter.collectionOf(dataRegionMetrics()); diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java index 30d220f03f8834..1306d8003ef660 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java @@ -67,12 +67,15 @@ import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl; import org.apache.ignite.internal.processors.cacheobject.NoOpBinary; +import org.apache.ignite.internal.processors.tracing.configuration.NoopTracingConfigurationManager; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.logger.NullLogger; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -499,6 +502,11 @@ public IgniteMock( return null; } + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager tracingConfiguration() { + return NoopTracingConfigurationManager.INSTANCE; + } + /** {@inheritDoc} */ @Override public Collection memoryMetrics() { return DataRegionMetricsAdapter.collectionOf(dataRegionMetrics()); diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java index 1f64f4cb4a54c0..344c31ebd07c4f 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java @@ -82,6 +82,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheUtilityKey; import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.hadoop.Hadoop; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.util.GridJavaProcess; import org.apache.ignite.internal.util.lang.IgnitePredicateX; import org.apache.ignite.internal.util.typedef.G; @@ -99,6 +100,7 @@ import org.apache.ignite.plugin.PluginNotFoundException; import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.testframework.junits.IgniteTestResources; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -847,6 +849,11 @@ public void kill() throws Exception { return DataStorageMetricsAdapter.valueOf(dataStorageMetrics()); } + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager tracingConfiguration() { + throw new UnsupportedOperationException("Operation isn't supported yet."); + } + /** {@inheritDoc} */ @Override public void close() throws IgniteException { if (localJvmGrid() != null) { diff --git a/modules/opencensus/src/main/java/org/apache/ignite/spi/tracing/opencensus/OpenCensusTracingSpi.java b/modules/opencensus/src/main/java/org/apache/ignite/spi/tracing/opencensus/OpenCensusTracingSpi.java index 3bd89fe7d756cf..4c43f2f7ae6bdd 100644 --- a/modules/opencensus/src/main/java/org/apache/ignite/spi/tracing/opencensus/OpenCensusTracingSpi.java +++ b/modules/opencensus/src/main/java/org/apache/ignite/spi/tracing/opencensus/OpenCensusTracingSpi.java @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import io.opencensus.trace.Sampler; import io.opencensus.trace.Tracing; import io.opencensus.trace.export.SpanExporter; import io.opencensus.trace.samplers.Samplers; @@ -103,34 +102,19 @@ public OpenCensusTracingSpi(SpanExporter.Handler... exporters) { /** {@inheritDoc} */ @Override public @NotNull OpenCensusSpanAdapter create( @NotNull String name, - @Nullable OpenCensusSpanAdapter parentSpan, - double samplingRate) { + @Nullable OpenCensusSpanAdapter parentSpan) { try { io.opencensus.trace.Span openCensusParent = null; if (parentSpan != null) openCensusParent = parentSpan.impl(); - Sampler sampler; - - if (Double.compare(samplingRate, 0) == 0) { - // We should never get here, because of an optimization that produces {@code NoopSpan.Instance} - // instead of a span with {@code SAMPLING_RATE_NEVER} sampling rate. It is useful cause in case - // of {@code NoopSpan.Instance} we will not send span data over the network.assert false; - - sampler = Samplers.neverSample(); // Just in case. - } - else if (Double.compare(samplingRate, 1) == 0) - sampler = Samplers.alwaysSample(); - else - sampler = Samplers.probabilitySampler(samplingRate); - return new OpenCensusSpanAdapter( Tracing.getTracer().spanBuilderWithExplicitParent( name, openCensusParent ) - .setSampler(sampler) + .setSampler(Samplers.alwaysSample()) .startSpan() ); } diff --git a/modules/opencensus/src/test/java/org/apache/ignite/TracingConfigurationValidationTest.java b/modules/opencensus/src/test/java/org/apache/ignite/TracingConfigurationValidationTest.java new file mode 100644 index 00000000000000..753311d3f0851b --- /dev/null +++ b/modules/opencensus/src/test/java/org/apache/ignite/TracingConfigurationValidationTest.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import org.apache.ignite.spi.tracing.Scope; +import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates; +import org.apache.ignite.spi.tracing.TracingConfigurationParameters; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +import static org.apache.ignite.spi.tracing.Scope.COMMUNICATION; +import static org.apache.ignite.spi.tracing.Scope.DISCOVERY; +import static org.apache.ignite.spi.tracing.Scope.EXCHANGE; +import static org.apache.ignite.spi.tracing.Scope.TX; + +/** + * Tests for tracing configuration validation rules. + */ +@SuppressWarnings("ThrowableNotThrown") +public class TracingConfigurationValidationTest extends GridCommonAbstractTest { + /** + * Ensure that in case of null scope as part of tracing coordinates {@code IllegalArgumentException} is thrown with + * message "Null scope is not valid for tracing coordinates." + */ + @Test + public void testThatItsNotPossibleToSetNullAsScopeForTracingCoordinates() { + GridTestUtils.assertThrows( + log, + () -> new TracingConfigurationCoordinates.Builder(null).build(), + IllegalArgumentException.class, + "Null scope is not valid for tracing coordinates."); + } + + /** + * Ensure that it's possible to set any non-null {@link Scope} as part of TracingConfigurationCoordinates. + */ + @Test + public void testThatItsPossibleToSpecifyAnyScopeAsPartOfTracingConfigurationCoordinates() { + for (Scope scope : Scope.values()) + new TracingConfigurationCoordinates.Builder(scope).build(); + } + + /** + * Ensure that it's possible to set any string as label as part of TracingConfigurationCoordinates. + */ + @Test + public void testThatItsPossibleToSpecifyAnyStringAsLabelAsPartOfTracingConfigurationCoordinates() { + Stream.of( + null, + "", + "label", "Some really long label with spaces, Some really long label with spaces," + + " Some really long label with spaces, Some really long label with spaces," + + " Some really long label with spaces").forEach( + lb -> new TracingConfigurationCoordinates.Builder(TX).withLabel(lb).build()); + } + + /** + * Ensure that it's possible to set any 0<= double <= 1 as sampling rate as part of TracingConfigurationParameters. + */ + @Test + public void testThatItsPossibleToSpecifyAnyDoubleBetweenZeroAndOneIncludingAsSamplingRate() { + for (double validSamplingRate : new double[] { + 0, + 0.1, + 0.11, + 0.1234567890, + 1}) + new TracingConfigurationParameters.Builder().withSamplingRate(validSamplingRate).build(); + } + + /** + * Ensure that in case of invalid sampling rate {@code IllegalArgumentException} is thrown with message "Specified + * sampling rate=[invalidVal] has invalid value.Should be between 0 and 1 including boundaries." + */ + @Test + public void testThatItsPossibleToSpecifyOnlyValidSamplingRate() { + for (Double invalidSamplingRate : new double[] { + -1d, + 10d}) + { + GridTestUtils.assertThrows( + log, + () -> new TracingConfigurationParameters.Builder().withSamplingRate(invalidSamplingRate).build(), + IllegalArgumentException.class, + "Specified sampling rate=[" + invalidSamplingRate + + "] has invalid value. Should be between 0 and 1 including boundaries."); + } + } + + /** + * Ensure that it's possible to set any set of {@code Scope} as included scopes as part of + * {@link TracingConfigurationParameters}. + */ + @Test @SuppressWarnings("unchecked") + public void testThatItsPossibleToSpecifyAnySetincludedScopesAsPartOfTracingConfigurationParameters() { + for (Set validincludedScopes : new Set[] { + null, + Collections.emptySet(), + Collections.singleton(COMMUNICATION), + new HashSet<>(Arrays.asList(COMMUNICATION, DISCOVERY, TX, EXCHANGE))}) + new TracingConfigurationParameters.Builder().withIncludedScopes(validincludedScopes).build(); + } +} diff --git a/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java b/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java index 38c5a6b192ed31..1866706aa7144b 100644 --- a/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java +++ b/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java @@ -30,11 +30,13 @@ import org.apache.ignite.configuration.CollectionConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.spi.tracing.TracingConfigurationManager; import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.lang.IgniteProductVersion; import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; @@ -321,6 +323,13 @@ public ApplicationContext getApplicationContext() throws BeansException { return g.snapshot(); } + /** {@inheritDoc} */ + @Override public @NotNull TracingConfigurationManager tracingConfiguration() { + checkIgnite(); + + return g.tracingConfiguration(); + } + /** {@inheritDoc} */ @Override public Collection memoryMetrics() { return DataRegionMetricsAdapter.collectionOf(dataRegionMetrics());