diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
index 1b0595bfc6dd6a..1e3df5d3f3ca2a 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
@@ -71,7 +71,10 @@ public enum CommandList {
METADATA("--meta", new MetadataCommand()),
/** */
- SHUTDOWN_POLICY("--shutdown-policy", new ShutdownPolicyCommand());
+ SHUTDOWN_POLICY("--shutdown-policy", new ShutdownPolicyCommand()),
+
+ /** */
+ TRACING_CONFIGURATION("--tracing-configuration", new TracingConfigurationCommand());
/** Private values copy so there's no need in cloning it every time. */
private static final CommandList[] VALUES = CommandList.values();
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
index b8a25346b89283..73bcce978aaf01 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.commandline;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
@@ -32,6 +33,7 @@
import org.apache.ignite.internal.commandline.cache.CacheValidateIndexes;
import org.apache.ignite.internal.commandline.cache.FindAndDeleteGarbage;
import org.apache.ignite.internal.commandline.cache.argument.FindAndDeleteGarbageArg;
+import org.apache.ignite.spi.tracing.Scope;
import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.visor.tx.VisorTxOperation;
import org.apache.ignite.internal.visor.tx.VisorTxProjection;
@@ -594,6 +596,195 @@ public void testKillArguments() {
"--kill", "continuous", UUID.randomUUID().toString(), "not_a_uuid");
}
+ /**
+ * Negative argument validation test for tracing-configuration command.
+ *
+ * validate that following tracing-configuration arguments validated as expected:
+ *
+ * -
+ * reset_all, get_all
+ *
+ * -
+ * --scope
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The scope should be specified. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX].")
+ *
+ * -
+ * if unsupported value is used:
+ * IllegalArgumentException (Invalid scope 'aaa'. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX])
+ *
+ *
+ *
+ *
+ *
+ * -
+ * reset, get:
+ *
+ * -
+ * --scope
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The scope should be specified. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX].")
+ *
+ * -
+ * if unsupported value is used:
+ * IllegalArgumentException (Invalid scope 'aaa'. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX])
+ *
+ *
+ *
+ * -
+ * --label
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The label should be specified.)
+ *
+ *
+ *
+ *
+ *
+ * -
+ * set:
+ *
+ * -
+ * --scope
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The scope should be specified. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX].")
+ *
+ * -
+ * if unsupported value is used:
+ * IllegalArgumentException (Invalid scope 'aaa'. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX])
+ *
+ *
+ *
+ * -
+ * --label
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The label should be specified.)
+ *
+ *
+ *
+ * -
+ * --sampling-rate
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (The sampling-rate should be specified. Decimal value between 0 and 1 should be used.)
+ *
+ * -
+ * if unsupported value is used:
+ * IllegalArgumentException (Invalid samling-rate 'aaa'. Decimal value between 0 and 1 should be used.)
+ *
+ *
+ *
+ * -
+ * --included-scopes
+ *
+ * -
+ * if value is missing:
+ * IllegalArgumentException (At least one supported scope should be specified.)
+ *
+ * -
+ * if unsupported value is used:
+ * IllegalArgumentException (Invalid supported scope: aaa. The following values can be used: [DISCOVERY, EXCHANGE, COMMUNICATION, TX].)
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ @Test
+ public void testTracingConfigurationArgumentsValidation() {
+ // reset
+ assertParseArgsThrows("The scope should be specified. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "reset", "--scope");
+
+ assertParseArgsThrows("Invalid scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "reset", "--scope", "aaa");
+
+ assertParseArgsThrows("The label should be specified.",
+ "--tracing-configuration", "reset", "--label");
+
+ // reset all
+ assertParseArgsThrows("The scope should be specified. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "reset_all", "--scope");
+
+ assertParseArgsThrows("Invalid scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "reset_all", "--scope", "aaa");
+
+ // get
+ assertParseArgsThrows("The scope should be specified. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "get", "--scope");
+
+ assertParseArgsThrows("Invalid scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "get", "--scope", "aaa");
+
+ assertParseArgsThrows("The label should be specified.",
+ "--tracing-configuration", "get", "--label");
+
+ // get all
+ assertParseArgsThrows("The scope should be specified. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "get_all", "--scope");
+
+ assertParseArgsThrows("Invalid scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "get_all", "--scope", "aaa");
+
+ // set
+ assertParseArgsThrows("The scope should be specified. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "set", "--scope");
+
+ assertParseArgsThrows("Invalid scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "set", "--scope", "aaa");
+
+ assertParseArgsThrows("The label should be specified.",
+ "--tracing-configuration", "set", "--label");
+
+ assertParseArgsThrows("The sampling rate should be specified. Decimal value between 0 and 1 should be used.",
+ "--tracing-configuration", "set", "--sampling-rate");
+
+ assertParseArgsThrows("Invalid sampling-rate 'aaa'. Decimal value between 0 and 1 should be used.",
+ "--tracing-configuration", "set", "--sampling-rate", "aaa");
+
+ assertParseArgsThrows("Invalid sampling-rate '-1'. Decimal value between 0 and 1 should be used.",
+ "--tracing-configuration", "set", "--sampling-rate", "-1");
+
+ assertParseArgsThrows("Invalid sampling-rate '2'. Decimal value between 0 and 1 should be used.",
+ "--tracing-configuration", "set", "--sampling-rate", "2");
+
+ assertParseArgsThrows("At least one supported scope should be specified.",
+ "--tracing-configuration", "set", "--included-scopes");
+
+ assertParseArgsThrows("Invalid supported scope 'aaa'. The following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "set", "--included-scopes", "TX,aaa");
+ }
+
+ /**
+ * Positive argument validation test for tracing-configuration command.
+ */
+ @Test
+ public void testTracingConfigurationArgumentsValidationMandatoryArgumentSet() {
+ parseArgs(asList("--tracing-configuration"));
+
+ parseArgs(asList("--tracing-configuration", "get_all"));
+
+ assertParseArgsThrows("Scope attribute is missing. Following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "reset");
+
+ assertParseArgsThrows("Scope attribute is missing. Following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "get");
+
+ assertParseArgsThrows("Scope attribute is missing. Following values can be used: "
+ + Arrays.toString(Scope.values()) + '.', "--tracing-configuration", "set");
+ }
+
/**
* Test checks that option {@link CommonArgParser#CMD_VERBOSE} is parsed
* correctly and if it is not present, it takes the default value
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
index 09722a1b5c4e4f..c445a72932b13e 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
@@ -98,6 +99,7 @@
import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR;
import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
import static org.apache.ignite.internal.commandline.CommandList.BASELINE;
+import static org.apache.ignite.internal.commandline.CommandList.TRACING_CONFIGURATION;
import static org.apache.ignite.internal.commandline.CommandList.METADATA;
import static org.apache.ignite.internal.commandline.CommandList.WAL;
import static org.apache.ignite.internal.commandline.CommonArgParser.CMD_VERBOSE;
@@ -1594,6 +1596,7 @@ public void testContainsWarnInsteadExecExperimentalCmdWhenEnableExperimentalFals
cmdArgs.put(WAL, asList("print", "delete"));
cmdArgs.put(METADATA, asList("help", "list"));
+ cmdArgs.put(TRACING_CONFIGURATION, Collections.singletonList("get_all"));
String warning = String.format(
"For use experimental command add %s=true to JVM_OPTS in %s",
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java
new file mode 100644
index 00000000000000..cb87946847a77f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/TracingConfigurationCommand.java
@@ -0,0 +1,346 @@
+/*
+ * 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.commandline;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Consumer;
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.client.GridClientNode;
+import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
+import org.apache.ignite.internal.commandline.cache.argument.TracingConfigurationCommandArg;
+import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationArguments;
+import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand;
+import org.apache.ignite.spi.tracing.Scope;
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTask;
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskArg;
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskResult;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
+import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
+import static org.apache.ignite.internal.commandline.CommandList.TRACING_CONFIGURATION;
+import static org.apache.ignite.internal.commandline.CommandLogger.grouped;
+import static org.apache.ignite.internal.commandline.CommandLogger.join;
+import static org.apache.ignite.internal.commandline.CommandLogger.optional;
+import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
+import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.GET_ALL;
+import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.RESET_ALL;
+import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.of;
+import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_ALWAYS;
+import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_NEVER;
+
+/**
+ * Commands associated with tracing configuration functionality.
+ */
+public class TracingConfigurationCommand implements Command {
+ /** Arguments. */
+ private TracingConfigurationArguments args;
+
+ /** {@inheritDoc} */
+ @Override public void printUsage(Logger log) {
+ if (!experimentalEnabled())
+ return;
+
+ Command.usage(
+ log,
+ "Print tracing configuration: ",
+ TRACING_CONFIGURATION);
+
+ Command.usage(
+ log,
+ "Print tracing configuration: ",
+ TRACING_CONFIGURATION,
+ TracingConfigurationSubcommand.GET_ALL.text(),
+ optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));
+
+ Command.usage(
+ log,
+ "Print specific tracing configuration based on specified " +
+ TracingConfigurationCommandArg.SCOPE.argName() + " and " +
+ TracingConfigurationCommandArg.LABEL.argName() + ": ",
+ TRACING_CONFIGURATION,
+ TracingConfigurationSubcommand.GET.text(),
+ grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
+ optional(TracingConfigurationCommandArg.LABEL.argName()));
+
+ Command.usage(
+ log,
+ "Reset all specific tracing configuration the to default. If " +
+ TracingConfigurationCommandArg.SCOPE.argName() +
+ " is specified, then remove all label specific configuration for the given scope and reset given scope" +
+ " specific configuration to the default, if " + TracingConfigurationCommandArg.SCOPE.argName() +
+ " is skipped then reset all tracing configurations to the default. Print tracing configuration.",
+ TRACING_CONFIGURATION,
+ RESET_ALL.text(),
+ optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));
+
+ Command.usage(
+ log,
+ "Reset specific tracing configuration to the default. If both " +
+ TracingConfigurationCommandArg.SCOPE.argName() + " and " +
+ TracingConfigurationCommandArg.LABEL.argName() + " are specified then remove given configuration," +
+ " if only " + TracingConfigurationCommandArg.SCOPE.argName() +
+ " is specified then reset given configuration to the default." +
+ " Print reseted configuration.",
+ TRACING_CONFIGURATION,
+ TracingConfigurationSubcommand.RESET.text(),
+ grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
+ optional(TracingConfigurationCommandArg.LABEL.argName()));
+
+ Command.usage(
+ log,
+ "Set new tracing configuration. If both " +
+ TracingConfigurationCommandArg.SCOPE.argName() + " and " +
+ TracingConfigurationCommandArg.LABEL.argName() + " are specified then add or override label" +
+ " specific configuration, if only " + TracingConfigurationCommandArg.SCOPE.argName() +
+ " is specified, then override scope specific configuration. Print applied configuration.",
+ TRACING_CONFIGURATION,
+ TracingConfigurationSubcommand.SET.text(),
+ grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values()),
+ optional(TracingConfigurationCommandArg.LABEL.argName()),
+ optional(TracingConfigurationCommandArg.SAMPLING_RATE.argName(),
+ "Decimal value between 0 and 1, " +
+ "where 0 means never and 1 means always. " +
+ "More or less reflects the probability of sampling specific trace."),
+ optional(TracingConfigurationCommandArg.INCLUDED_SCOPES.argName(),
+ "Set of scopes with comma as separator ",
+ join("|", Scope.values()))));
+ }
+
+ /**
+ * Execute tracing-configuration command.
+ *
+ * @param clientCfg Client configuration.
+ * @throws Exception If failed to execute tracing-configuration action.
+ */
+ @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ if (experimentalEnabled()) {
+ try (GridClient client = Command.startClient(clientCfg)) {
+ UUID crdId = client.compute()
+ //Only non client node can be coordinator.
+ .nodes(node -> !node.isClient())
+ .stream()
+ .min(Comparator.comparingLong(GridClientNode::order))
+ .map(GridClientNode::nodeId)
+ .orElse(null);
+
+ VisorTracingConfigurationTaskResult res = executeTaskByNameOnNode(
+ client,
+ VisorTracingConfigurationTask.class.getName(),
+ toVisorArguments(args),
+ crdId,
+ clientCfg
+ );
+
+ printResult(res, log::info);
+
+ return res;
+ }
+ catch (Throwable e) {
+ log.severe("Failed to execute tracing-configuration command='" + args.command().text() + "'");
+
+ throw e;
+ }
+ } else {
+ log.warning(String.format("For use experimental command add %s=true to JVM_OPTS in %s",
+ IGNITE_ENABLE_EXPERIMENTAL_COMMAND, UTILITY_NAME));
+
+ return null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void parseArguments(CommandArgIterator argIter) {
+ // If there is no arguments, use list command.
+ if (!argIter.hasNextSubArg()) {
+ args = new TracingConfigurationArguments.Builder(TracingConfigurationSubcommand.GET_ALL).build();
+
+ return;
+ }
+
+ TracingConfigurationSubcommand cmd = of(argIter.nextArg("Expected tracing configuration action."));
+
+ if (cmd == null)
+ throw new IllegalArgumentException("Expected correct tracing configuration action.");
+
+ TracingConfigurationArguments.Builder tracingConfigurationArgs = new TracingConfigurationArguments.Builder(cmd);
+
+ Scope scope = null;
+
+ String lb = null;
+
+ double samplingRate = SAMPLING_RATE_NEVER;
+
+ Set includedScopes = new HashSet<>();
+
+ while (argIter.hasNextSubArg()) {
+ TracingConfigurationCommandArg arg =
+ CommandArgUtils.of(argIter.nextArg(""), TracingConfigurationCommandArg.class);
+
+ String strVal;
+
+ assert arg != null;
+
+ switch (arg) {
+ case SCOPE: {
+ String peekedNextArg = argIter.peekNextArg();
+
+ if (!TracingConfigurationCommandArg.args().contains(peekedNextArg)) {
+ strVal = argIter.nextArg(
+ "The scope should be specified. The following " +
+ "values can be used: " + Arrays.toString(Scope.values()) + '.');
+
+ try {
+ scope = Scope.valueOf(strVal);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "Invalid scope '" + strVal + "'. The following " +
+ "values can be used: " + Arrays.toString(Scope.values()) + '.');
+ }
+ }
+
+ break;
+ }
+ case LABEL: {
+ lb = argIter.nextArg(
+ "The label should be specified.");
+
+ break;
+ }
+ case SAMPLING_RATE: {
+ strVal = argIter.nextArg(
+ "The sampling rate should be specified. Decimal value between 0 and 1 should be used.");
+
+ try {
+ samplingRate = Double.parseDouble(strVal);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");
+ }
+
+ if (samplingRate < SAMPLING_RATE_NEVER || samplingRate > SAMPLING_RATE_ALWAYS)
+ throw new IllegalArgumentException(
+ "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");
+
+ break;
+ }
+ case INCLUDED_SCOPES: {
+ Set setStrVals = argIter.nextStringSet(
+ "At least one supported scope should be specified.");
+
+ for (String scopeStrVal : setStrVals) {
+ try {
+ includedScopes.add(Scope.valueOf(scopeStrVal));
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "Invalid supported scope '" + scopeStrVal + "'. The following " +
+ "values can be used: " + Arrays.toString(Scope.values()) + '.');
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Scope is a mandatory attribute for all sub-commands except get_all and reset_all.
+ if ((cmd != GET_ALL && cmd != RESET_ALL) && scope == null) {
+ throw new IllegalArgumentException(
+ "Scope attribute is missing. Following values can be used: " + Arrays.toString(Scope.values()) + '.');
+ }
+
+ switch (cmd) {
+ case GET_ALL:
+ case RESET_ALL: {
+ tracingConfigurationArgs.withScope(scope);
+
+ break;
+ }
+
+ case RESET:
+ case GET: {
+ tracingConfigurationArgs.withScope(scope).withLabel(lb);
+
+ break;
+ }
+
+ case SET: {
+ tracingConfigurationArgs.withScope(scope).withLabel(lb).withSamplingRate(samplingRate).
+ withIncludedScopes(includedScopes);
+
+ break;
+ }
+
+ default: {
+ // We should never get here.
+ assert false : "Unexpected tracing configuration argument [arg= " + cmd + ']';
+ }
+ }
+
+ args = tracingConfigurationArgs.build();
+ }
+
+ /** {@inheritDoc} */
+ @Override public TracingConfigurationArguments arg() {
+ return args;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return TRACING_CONFIGURATION.toCommandName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean experimental() {
+ return true;
+ }
+
+ /**
+ * Print result.
+ *
+ * @param res Visor tracing configuration result.
+ * @param printer Printer.
+ */
+ private void printResult(VisorTracingConfigurationTaskResult res, Consumer printer) {
+ res.print(printer);
+ }
+
+ /**
+ * Prepare task argument.
+ *
+ * @param args Argument from command line.
+ * @return Task argument.
+ */
+ private VisorTracingConfigurationTaskArg toVisorArguments(TracingConfigurationArguments args) {
+ return new VisorTracingConfigurationTaskArg(
+ args.command().visorBaselineOperation(),
+ args.scope(),
+ args.label(),
+ args.samplingRate(),
+ args.includedScopes()
+ );
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/argument/TracingConfigurationCommandArg.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/argument/TracingConfigurationCommandArg.java
new file mode 100644
index 00000000000000..65b2b39a87bc21
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/cache/argument/TracingConfigurationCommandArg.java
@@ -0,0 +1,79 @@
+/*
+ * 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.commandline.cache.argument;
+
+import org.apache.ignite.internal.commandline.CommandList;
+import org.apache.ignite.internal.commandline.argument.CommandArg;
+import org.apache.ignite.spi.tracing.Scope;
+import org.apache.ignite.internal.processors.tracing.Span;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * {@link CommandList#TRACING_CONFIGURATION} command arguments.
+ */
+public enum TracingConfigurationCommandArg implements CommandArg {
+ /**
+ * Specify the {@link Scope} of a trace's root span to which some specific tracing configuration will be applied.
+ */
+ SCOPE("--scope"),
+
+ /** Specify the label of a traced operation. It's an optional attribute. */
+ LABEL("--label"),
+
+ /**
+ * 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).
+ */
+ SAMPLING_RATE("--sampling-rate"),
+
+ /**
+ * 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.
+ */
+ INCLUDED_SCOPES("--included-scopes");
+
+ /** Arg name. */
+ private final String name;
+
+ /**
+ * Creates a new instance of tracing configuration argument.
+ *
+ * @param name command name.
+ */
+ TracingConfigurationCommandArg(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return List of arguments.
+ */
+ public static Set args() {
+ return Arrays.stream(TracingConfigurationCommandArg.values())
+ .map(TracingConfigurationCommandArg::argName)
+ .collect(Collectors.toSet());
+ }
+
+ /** {inheritDoc} */
+ @Override public String argName() {
+ return name;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationArguments.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationArguments.java
new file mode 100644
index 00000000000000..e2119425f6221b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationArguments.java
@@ -0,0 +1,180 @@
+/*
+ * 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.commandline.tracing.configuration;
+
+import java.util.Collections;
+import java.util.Set;
+import org.apache.ignite.spi.tracing.Scope;
+import org.apache.ignite.internal.processors.tracing.Span;
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationItem;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * This class contains all possible arguments after parsing tracing-configuration command input.
+ */
+ public final class TracingConfigurationArguments extends VisorTracingConfigurationItem {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Command. */
+ private TracingConfigurationSubcommand cmd;
+
+ /**
+ * Default constructor.
+ */
+ public TracingConfigurationArguments() {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param cmd Command
+ * @param scope Specify the {@link Scope} of a trace's root span
+ * to which some specific tracing configuration will be applied.
+ * @param lb Specifies the label of a traced operation. It's an optional attribute.
+ * @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 TracingConfigurationArguments(
+ TracingConfigurationSubcommand cmd,
+ Scope scope,
+ String lb,
+ double samplingRate,
+ Set includedScopes
+ ) {
+ super(
+ scope,
+ lb,
+ samplingRate,
+ includedScopes);
+
+ this.cmd = cmd;
+ }
+
+ /**
+ * @return Command.
+ */
+ public TracingConfigurationSubcommand command() {
+ return cmd;
+ }
+
+ /**
+ * Builder of {@link TracingConfigurationArguments}.
+ */
+ @SuppressWarnings("PublicInnerClass") public static class Builder {
+ /** Counterpart of {@code TracingConfigurationArguments}'s command. */
+ private TracingConfigurationSubcommand cmd;
+
+ /** Counterpart of {@code TracingConfigurationArguments}'s scope. */
+ private Scope scope;
+
+ /** Counterpart of {@code TracingConfigurationArguments}'s label. */
+ private String lb;
+
+ /** Counterpart of {@code TracingConfigurationArguments}'s samplingRate. */
+ private double samplingRate;
+
+ /** Counterpart of {@code TracingConfigurationArguments}'s includedScopes. */
+ private Set includedScopes;
+
+ /**
+ * Constructor.
+ *
+ * @param cmd {@code TracingConfigurationSubcommand} command.
+ */
+ public Builder(TracingConfigurationSubcommand cmd) {
+ this.cmd = cmd;
+ }
+
+ /**
+ * Builder method that allows to set scope.
+ * @param scope {@link Scope} of a trace's root span
+ * to which some specific tracing configuration will be applied.
+ * @return Builder.
+ */
+ public @NotNull Builder withScope(Scope scope) {
+ this.scope = scope;
+
+ return this;
+ }
+
+ /**
+ * 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 Builder.
+ */
+ public @NotNull Builder withSamplingRate(double samplingRate) {
+ this.samplingRate = samplingRate;
+
+ return this;
+ }
+
+ /**
+ * Builder method that allows to set optional label attribute.
+ *
+ * @param lb Label of traced operation. It's an optional attribute.
+ * @return Builder
+ */
+ public @NotNull Builder withLabel(@Nullable String lb) {
+ this.lb = lb;
+
+ 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 Builder
+ */
+ @SuppressWarnings("UnusedReturnValue")
+ public @NotNull Builder withIncludedScopes(Set includedScopes) {
+ this.includedScopes = includedScopes == null ? Collections.emptySet() : includedScopes;
+
+ return this;
+ }
+
+ /**
+ * Builder's build method that produces {@link TracingConfigurationArguments}.
+ *
+ * @return {@code TracingConfigurationArguments} instance.
+ */
+ public TracingConfigurationArguments build() {
+ return new TracingConfigurationArguments(
+ cmd,
+ scope,
+ lb,
+ samplingRate,
+ includedScopes);
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationSubcommand.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationSubcommand.java
new file mode 100644
index 00000000000000..a3b04c67fc5be4
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/tracing/configuration/TracingConfigurationSubcommand.java
@@ -0,0 +1,104 @@
+/*
+ * 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.commandline.tracing.configuration;
+
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationOperation;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Set of tracing configuration commands.
+ */
+public enum TracingConfigurationSubcommand {
+ /** Get specific tracing configuration. */
+ GET("get", VisorTracingConfigurationOperation.GET),
+
+ /** Get tracing configuration. */
+ GET_ALL("get_all", VisorTracingConfigurationOperation.GET_ALL),
+
+ /** Reset specific tracing configuration to default. */
+ RESET("reset", VisorTracingConfigurationOperation.RESET),
+
+ /**
+ * Reset all scope specific tracing configuration to default,
+ * or reset all tracing configurations to default if scope is not specified.
+ */
+ RESET_ALL("reset_all", VisorTracingConfigurationOperation.RESET_ALL),
+
+ /** Set new tracing configuration. */
+ SET("set", VisorTracingConfigurationOperation.SET);
+
+ /** Enumerated values. */
+ private static final TracingConfigurationSubcommand[] VALS = values();
+
+ /** Name. */
+ private final String name;
+
+ /** Corresponding visor tracing configuration operation. */
+ private final VisorTracingConfigurationOperation visorOperation;
+
+ /**
+ * @param name Name.
+ * @param visorOperation Corresponding visor tracing configuration operation.
+ */
+ TracingConfigurationSubcommand(String name, VisorTracingConfigurationOperation visorOperation) {
+ this.name = name;
+ this.visorOperation = visorOperation;
+ }
+
+ /**
+ * @param text Command text.
+ * @return Command for the text.
+ */
+ public static TracingConfigurationSubcommand of(String text) {
+ for (TracingConfigurationSubcommand cmd : TracingConfigurationSubcommand.values()) {
+ if (cmd.text().equalsIgnoreCase(text))
+ return cmd;
+ }
+
+ return null;
+ }
+
+ /**
+ * @return Name.
+ */
+ public String text() {
+ return name;
+ }
+
+ /**
+ * @return {@link VisorTracingConfigurationOperation} which is associated with tracing configuration subcommand.
+ */
+ public VisorTracingConfigurationOperation visorBaselineOperation() {
+ return visorOperation;
+ }
+
+ /**
+ * Efficiently gets enumerated value from its ordinal.
+ *
+ * @param ord Ordinal value.
+ * @return Enumerated value or {@code null} if ordinal out of range.
+ */
+ @Nullable public static TracingConfigurationSubcommand fromOrdinal(int ord) {
+ return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return name;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationItem.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationItem.java
new file mode 100644
index 00000000000000..152233d0b1f002
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationItem.java
@@ -0,0 +1,177 @@
+/*
+ * 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.visor.tracing.configuration;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Set;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.spi.tracing.Scope;
+import org.apache.ignite.internal.processors.tracing.Span;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Data transfer object that contains scope, label, sampling rate and set of included scopes.
+ */
+@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
+public class VisorTracingConfigurationItem extends IgniteDataTransferObject {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * Specifies the {@link Scope} of a trace's root span to which some specific tracing configuration will be applied.
+ * It's a mandatory attribute.
+ */
+ private Scope scope;
+
+ /**
+ * Specifies the label of a traced operation. It's an optional attribute.
+ */
+ private String lb;
+
+ /**
+ * 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).
+ */
+ private Double samplingRate;
+
+ /**
+ * 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 Set includedScopes;
+
+ /**
+ * Default constructor.
+ */
+ public VisorTracingConfigurationItem() {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param scope Specifies the {@link Scope} of a trace's root span to which some specific tracing configuration will be applied.
+ * @param lb Specifies the label of a traced operation. It's an optional attribute.
+ * @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.
+ */
+ public VisorTracingConfigurationItem(
+ Scope scope,
+ String lb,
+ Double samplingRate,
+ Set includedScopes)
+ {
+ this.scope = scope;
+ this.lb = lb;
+ this.samplingRate = samplingRate;
+ this.includedScopes = includedScopes;
+ }
+
+ /**
+ * @return Specifies the of a trace's root span to which some specific tracing configuration will be applied. It's
+ * a mandatory attribute.
+ */
+ public Scope scope() {
+ return scope;
+ }
+
+ /**
+ * @return Specifies the label of a traced operation. It's an optional attribute.
+ */
+ public String label() {
+ return lb;
+ }
+
+ /**
+ * @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 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 for more details.
+ */
+ public Set includedScopes() {
+ return includedScopes;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ out.writeBoolean(scope != null);
+
+ if (scope != null)
+ out.writeShort(scope.idx());
+
+ U.writeString(out, label());
+
+ out.writeObject(samplingRate);
+
+ U.writeCollection(out, includedScopes);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(byte protoVer,
+ ObjectInput in) throws IOException, ClassNotFoundException {
+
+ if (in.readBoolean())
+ scope = Scope.fromIndex(in.readShort());
+
+ lb = U.readString(in);
+
+ samplingRate = (Double)in.readObject();
+
+ includedScopes = U.readSet(in);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(VisorTracingConfigurationItem.class, this);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ VisorTracingConfigurationItem that = (VisorTracingConfigurationItem)o;
+
+ if (scope != that.scope)
+ return false;
+ if (lb != null ? !lb.equals(that.lb) : that.lb != null)
+ return false;
+ if (samplingRate != null ? !samplingRate.equals(that.samplingRate) : that.samplingRate != null)
+ return false;
+ return includedScopes != null ? includedScopes.equals(that.includedScopes) : that.includedScopes == null;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationOperation.java
new file mode 100644
index 00000000000000..6db6954b321cb0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationOperation.java
@@ -0,0 +1,56 @@
+/*
+ * 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.visor.tracing.configuration;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Tracing configuration operation options.
+ */
+public enum VisorTracingConfigurationOperation {
+ /** Get specific tracing configuration. */
+ GET,
+
+ /** Get tracing configuration. */
+ GET_ALL,
+
+ /** Reset specific tracing configuration to default. */
+ RESET,
+
+ /**
+ * Reset all scope specific tracing configurations to default,
+ * or reset all tracing configurations to default if scope is not specified.
+ */
+ RESET_ALL,
+
+ /** Set new tracing configuration. */
+ SET;
+
+ /** Enumerated values. */
+ private static final VisorTracingConfigurationOperation[] VALS = values();
+
+ /**
+ * Efficiently gets enumerated value from its ordinal.
+ *
+ * @param ord Ordinal value.
+ * @return Enumerated value or {@code null} if ordinal out of range.
+ */
+ @Nullable public static VisorTracingConfigurationOperation fromOrdinal(int ord) {
+ return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTask.java
new file mode 100644
index 00000000000000..5be8d3f1262f40
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTask.java
@@ -0,0 +1,204 @@
+/*
+ * 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.visor.tracing.configuration;
+
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.processors.task.GridVisorManagementTask;
+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.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorOneNodeTask;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Task that will collect and update tracing configuration.
+ */
+@GridInternal
+@GridVisorManagementTask
+public class VisorTracingConfigurationTask
+ extends VisorOneNodeTask {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override protected VisorTracingConfigurationJob job(VisorTracingConfigurationTaskArg arg) {
+ return new VisorTracingConfigurationJob(arg, debug);
+ }
+
+ /**
+ * Job that will collect and update tracing configuration.
+ */
+ private static class VisorTracingConfigurationJob extends VisorJob {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * @param arg Formal job argument.
+ * @param debug Debug flag.
+ */
+ private VisorTracingConfigurationJob(VisorTracingConfigurationTaskArg arg, boolean debug) {
+ super(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected @NotNull VisorTracingConfigurationTaskResult run(
+ VisorTracingConfigurationTaskArg arg) throws IgniteException {
+ switch (arg.operation()) {
+ case GET_ALL:
+ return getAll(arg.scope());
+
+ case GET:
+ return get(arg.scope(), arg.label());
+
+ case RESET:
+ return reset(arg.scope(), arg.label());
+
+ case RESET_ALL:
+ return resetAll(arg.scope());
+
+ case SET:
+ return set(arg.scope(), arg.label(), arg.samplingRate(), arg.includedScopes());
+
+ default: {
+ // We should never get here.
+ assert false : "Unexpected tracing configuration argument [arg= " + arg + ']';
+
+ return getAll(null); // Just in case.
+ }
+ }
+ }
+
+ /**
+ * Get tracing configuration.
+ *
+ * @param scope Nullable scope of tracing configuration to be retrieved.
+ * If null - all configuration will be returned.
+ * @return Tracing configuration as {@link VisorTracingConfigurationTaskResult} instance.
+ */
+ private @NotNull VisorTracingConfigurationTaskResult getAll(@Nullable Scope scope) {
+ Map cfg =
+ ignite.tracingConfiguration().getAll(scope);
+
+ VisorTracingConfigurationTaskResult res = new VisorTracingConfigurationTaskResult();
+
+ for (Map.Entry entry: cfg.entrySet())
+ res.add(entry.getKey(), entry.getValue());
+
+ return res;
+ }
+
+ /**
+ * Get scope specific and optionally label specific tracing configuration.
+ *
+ * @param scope Scope.
+ * @param lb Label
+ * @return Scope specific and optionally label specific tracing configuration as
+ * {@link VisorTracingConfigurationTaskResult} instance.
+ */
+ private @NotNull VisorTracingConfigurationTaskResult get(
+ @NotNull Scope scope,
+ @Nullable String lb)
+ {
+ TracingConfigurationCoordinates coordinates =
+ new TracingConfigurationCoordinates.Builder(scope).withLabel(lb).build();
+
+ TracingConfigurationParameters updatedParameters =
+ ignite.tracingConfiguration().get(
+ new TracingConfigurationCoordinates.Builder(scope).withLabel(lb).build());
+
+ VisorTracingConfigurationTaskResult res = new VisorTracingConfigurationTaskResult();
+
+ res.add(coordinates, updatedParameters);
+
+ return res;
+ }
+
+ /**
+ * Reset scope specific and optionally label specific tracing configuration.
+ *
+ * @param scope Scope.
+ * @param lb Label.
+ * @return Scope based configuration that was partly of fully reseted as
+ * {@link VisorTracingConfigurationTaskResult} instance.
+ */
+ private @NotNull VisorTracingConfigurationTaskResult reset(
+ @NotNull Scope scope,
+ @Nullable String lb)
+ {
+ ignite.tracingConfiguration().reset(
+ new TracingConfigurationCoordinates.Builder(scope).withLabel(lb).build());
+
+ return getAll(scope);
+ }
+
+ /**
+ * Reset tracing configuration, or optionally scope specific tracing configuration.
+ *
+ * @param scope Scope.
+ * @return Tracing configuration as {@link VisorTracingConfigurationTaskResult} instance.
+ */
+ private @NotNull VisorTracingConfigurationTaskResult resetAll(@Nullable Scope scope) {
+ ignite.tracingConfiguration().resetAll(scope);
+
+ return getAll(scope);
+ }
+
+ /**
+ * Set new tracing configuration.
+ *
+ * @param scope Scope.
+ * @param lb Label.
+ * @param samplingRate Sampling rate.
+ * @param includedScopes Set of included scopes.
+ * @return Scope based configuration that was partly of fully updated as
+ * * {@link VisorTracingConfigurationTaskResult} instance.
+ */
+ private @NotNull VisorTracingConfigurationTaskResult set(
+ @NotNull Scope scope,
+ @Nullable String lb,
+ @Nullable Double samplingRate,
+ @Nullable Set includedScopes)
+ {
+ TracingConfigurationCoordinates coordinates =
+ new TracingConfigurationCoordinates.Builder(scope).withLabel(lb).build();
+
+ TracingConfigurationParameters.Builder parametersBuilder = new TracingConfigurationParameters.Builder();
+
+ if (samplingRate != null)
+ parametersBuilder.withSamplingRate(samplingRate);
+
+ if (includedScopes != null)
+ parametersBuilder.withIncludedScopes(includedScopes);
+
+ ignite.tracingConfiguration().set(coordinates, parametersBuilder.build());
+
+ return getAll(scope);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(VisorTracingConfigurationJob.class, this);
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskArg.java
new file mode 100644
index 00000000000000..972a0a16327039
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskArg.java
@@ -0,0 +1,103 @@
+/*
+ * 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.visor.tracing.configuration;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Set;
+import org.apache.ignite.spi.tracing.Scope;
+import org.apache.ignite.internal.processors.tracing.Span;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Argument for {@link VisorTracingConfigurationTask}.
+ */
+public class VisorTracingConfigurationTaskArg extends VisorTracingConfigurationItem {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ private VisorTracingConfigurationOperation op;
+
+ /**
+ * Default constructor.
+ */
+ public VisorTracingConfigurationTaskArg() {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param op Operation.
+ * @param scope Specifies the {@link Scope} of a trace's root span to which some specific tracing configuration will be applied.
+ * @param lb Specifies the label of a traced operation. It's an optional attribute.
+ * @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.
+ */
+ public VisorTracingConfigurationTaskArg(
+ VisorTracingConfigurationOperation op,
+ Scope scope,
+ String lb,
+ Double samplingRate,
+ Set includedScopes)
+ {
+ super(scope,
+ lb,
+ samplingRate,
+ includedScopes);
+
+ this.op = op;
+ }
+
+ /**
+ * @return Operation.
+ */
+ public VisorTracingConfigurationOperation operation() {
+ return op;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ U.writeEnum(out, op);
+
+ super.writeExternalData(out);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(
+ byte protoVer,
+ ObjectInput in) throws IOException, ClassNotFoundException
+ {
+ op = VisorTracingConfigurationOperation.fromOrdinal(in.readByte());
+
+ super.readExternalData(protoVer, in);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(VisorTracingConfigurationTaskArg.class, this);
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskResult.java
new file mode 100644
index 00000000000000..dd892b2d3d36ad
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/tracing/configuration/VisorTracingConfigurationTaskResult.java
@@ -0,0 +1,104 @@
+/*
+ * 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.visor.tracing.configuration;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Consumer;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates;
+import org.apache.ignite.spi.tracing.TracingConfigurationParameters;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Result for {@link VisorTracingConfigurationTask}.
+ */
+public class VisorTracingConfigurationTaskResult extends IgniteDataTransferObject {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ private static final Character RES_PRINTER_SEPARATOR = ',';
+
+ /** Retrieved reseted or updated tracing configuration. */
+ private List tracingConfigurations = new ArrayList<>();
+
+ /**
+ * Default constructor.
+ */
+ public VisorTracingConfigurationTaskResult() {
+ // No-op.
+ }
+
+ /**
+ * Add coordinates and parameters pair to the result.
+ *
+ * @param coordinates {@link TracingConfigurationCoordinates} instance.
+ * @param parameters {@link TracingConfigurationParameters} instance.
+ */
+ @SuppressWarnings("unchecked")
+ public void add(TracingConfigurationCoordinates coordinates, TracingConfigurationParameters parameters) {
+ tracingConfigurations.add(new VisorTracingConfigurationItem(
+ coordinates.scope(),
+ coordinates.label(),
+ parameters.samplingRate(),
+ parameters.includedScopes()
+ ));
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ U.writeCollection(out, tracingConfigurations);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked") @Override protected void readExternalData(byte protoVer, ObjectInput in)
+ throws IOException, ClassNotFoundException {
+ tracingConfigurations = (List)U.readCollection(in);
+ }
+
+ /**
+ * Fills printer {@link Consumer } by string view of this class.
+ */
+ public void print(Consumer printer) {
+ printer.accept("Scope, Label, Sampling Rate, included scopes");
+
+ Collections.sort(tracingConfigurations, Comparator.comparing(VisorTracingConfigurationItem::scope));
+
+ for (VisorTracingConfigurationItem tracingConfiguration : tracingConfigurations) {
+ printer.accept(
+ tracingConfiguration.scope().name() + RES_PRINTER_SEPARATOR +
+ (tracingConfiguration.label() == null ? "" : tracingConfiguration.label()) + RES_PRINTER_SEPARATOR +
+ tracingConfiguration.samplingRate() + RES_PRINTER_SEPARATOR +
+ Arrays.toString(tracingConfiguration.includedScopes().toArray()));
+ }
+ }
+
+ /**
+ * @return Retrieved reseted or updated tracing configuration.
+ */
+ public List tracingConfigurations() {
+ return tracingConfigurations;
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index c0e78225d409e5..4a413458f9afa8 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -128,6 +128,7 @@
import org.apache.ignite.testframework.test.ParametersTest;
import org.apache.ignite.testframework.test.VariationsIteratorTest;
import org.apache.ignite.util.AttributeNodeFilterSelfTest;
+import org.apache.ignite.util.GridCommandHandlerTracingConfigurationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -296,7 +297,10 @@
ClusterActivationStartedEventTest.class,
- IgniteThreadGroupNodeRestartTest.class
+ IgniteThreadGroupNodeRestartTest.class,
+
+ // Tests for tracing configuration
+ GridCommandHandlerTracingConfigurationTest.class
})
public class IgniteBasicTestSuite {
}
diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTracingConfigurationTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTracingConfigurationTest.java
new file mode 100644
index 00000000000000..b5074844890238
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTracingConfigurationTest.java
@@ -0,0 +1,390 @@
+/*
+ * 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.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.commandline.CommandHandler;
+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.apache.ignite.internal.commandline.TracingConfigurationCommand;
+import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskResult;
+import org.junit.Test;
+
+import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+import static org.apache.ignite.spi.tracing.Scope.COMMUNICATION;
+import static org.apache.ignite.spi.tracing.Scope.EXCHANGE;
+import static org.apache.ignite.spi.tracing.Scope.TX;
+
+/**
+ * Tests for {@link TracingConfigurationCommand}
+ */
+public class GridCommandHandlerTracingConfigurationTest extends GridCommandHandlerClusterPerMethodAbstractTest {
+ /** Default configuration map. */
+ private static final Map DFLT_CONFIG_MAP =
+ new HashMap<>();
+
+ /** TX scope specific coordinates to be used within several tests. */
+ private static final TracingConfigurationCoordinates TX_SCOPE_SPECIFIC_COORDINATES =
+ new TracingConfigurationCoordinates.Builder(TX).build();
+
+ /** EXCHANGE scope specific coordinates to be used within several tests. */
+ private static final TracingConfigurationCoordinates EXCHANGE_SCOPE_SPECIFIC_COORDINATES =
+ new TracingConfigurationCoordinates.Builder(EXCHANGE).build();
+
+ /** Updated scope specific parameters to be used within several tests. */
+ private static final TracingConfigurationParameters SOME_SCOPE_SPECIFIC_PARAMETERS =
+ new TracingConfigurationParameters.Builder().withSamplingRate(0.75).
+ withIncludedScopes(Collections.singleton(COMMUNICATION)).build();
+
+ /** TX Label specific coordinates to be used within several tests. */
+ private static final TracingConfigurationCoordinates TX_LABEL_SPECIFIC_COORDINATES =
+ new TracingConfigurationCoordinates.Builder(TX).withLabel("label").build();
+
+ /** Updated label specific parameters to be used within several tests. */
+ private static final TracingConfigurationParameters SOME_LABEL_SPECIFIC_PARAMETERS =
+ new TracingConfigurationParameters.Builder().withSamplingRate(0.111).
+ withIncludedScopes(Collections.singleton(EXCHANGE)).build();
+
+ static {
+ DFLT_CONFIG_MAP.put(
+ new TracingConfigurationCoordinates.Builder(Scope.TX).build(),
+ TracingConfigurationManager.DEFAULT_TX_CONFIGURATION);
+
+ DFLT_CONFIG_MAP.put(
+ new TracingConfigurationCoordinates.Builder(Scope.COMMUNICATION).build(),
+ TracingConfigurationManager.DEFAULT_COMMUNICATION_CONFIGURATION);
+
+ DFLT_CONFIG_MAP.put(
+ new TracingConfigurationCoordinates.Builder(Scope.EXCHANGE).build(),
+ TracingConfigurationManager.DEFAULT_EXCHANGE_CONFIGURATION);
+
+ DFLT_CONFIG_MAP.put(
+ new TracingConfigurationCoordinates.Builder(Scope.DISCOVERY).build(),
+ TracingConfigurationManager.DEFAULT_DISCOVERY_CONFIGURATION);
+ }
+
+ /** */
+ protected IgniteEx ignite;
+
+ /** */
+ private static CommandHandler hnd;
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ ignite = startGrids(2);
+
+ hnd = new CommandHandler();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ // Cleanup configuration.
+ grid(0).tracingConfiguration().resetAll(null);
+
+ // Populate tracing with some custom configurations.
+ grid(0).tracingConfiguration().set(
+ TX_SCOPE_SPECIFIC_COORDINATES,
+ SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ grid(0).tracingConfiguration().set(
+ TX_LABEL_SPECIFIC_COORDINATES,
+ SOME_LABEL_SPECIFIC_PARAMETERS);
+
+ grid(0).tracingConfiguration().set(
+ EXCHANGE_SCOPE_SPECIFIC_COORDINATES,
+ SOME_SCOPE_SPECIFIC_PARAMETERS);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ // Do nothing;
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration" without arguments
+ * tracing configuration for all scopes will be returned.
+ */
+ @Test
+ public void testTracingConfigurationWithoutSubCommandsReturnsTracingConfiguratoinForAllScopes() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration"));
+
+ Map expTracingCfg =
+ new HashMap<>(DFLT_CONFIG_MAP);
+
+ expTracingCfg.put(TX_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+ expTracingCfg.put(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+ expTracingCfg.put(EXCHANGE_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expTracingCfg.forEach(expRes::add);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration get_all --scope TX"
+ * TX based tracing configuration will be returned: both scope specific and label specific.
+ */
+ @Test
+ public void testGetAllWithScopeReturnsOnlySpecifiedScopeSpecificConfiguratoin() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "get_all", "--scope", "TX"));
+
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+ expRes.add(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration get_all" without scope
+ * tracing configuration for all scopes will be returned.
+ */
+ @Test
+ public void testGetAllWithoutScopeReturnsTracingConfigurationsForAllScopes() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "get_all"));
+
+ // Check command result.
+ Map expTracingCfg =
+ new HashMap<>(DFLT_CONFIG_MAP);
+
+ expTracingCfg.put(TX_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+ expTracingCfg.put(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+ expTracingCfg.put(EXCHANGE_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expTracingCfg.forEach(expRes::add);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration get --scope TX"
+ * TX specific and only TX specific tracing configuration will be returned:
+ * TX-label specific configuration not expected.
+ */
+ @Test
+ public void testGetWithScopeReturnsScopeSpecificConfiguratoin() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "get", "--scope", "TX"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration get --scope TX --label label"
+ * TX label specific and only TX label specific tracing configuration will be returned:
+ * TX specific configuration not expected.
+ */
+ @Test
+ public void testGetWithScopeAndLabelReturnsLabelSpecificConfigurationIfSuchOneExists() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "get", "--scope",
+ "TX", "--label", "label"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration reset_all --scope TX"
+ * TX based configuration will be reseted and returned:
+ */
+ @Test
+ public void testResetAllWithScopeResetsScopeBasedConfigurationAndReturnsIt() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "reset_all", "--scope", "TX"));
+
+ // Ensure that configuration was actually reseted.
+ assertEquals(
+ Collections.singletonMap(
+ TX_SCOPE_SPECIFIC_COORDINATES,
+ TracingConfigurationManager.DEFAULT_TX_CONFIGURATION),
+ grid(0).tracingConfiguration().getAll(TX));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_SCOPE_SPECIFIC_COORDINATES, TracingConfigurationManager.DEFAULT_TX_CONFIGURATION);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration reset_all"
+ * Whole tracing configurations will be reseted and returned.
+ */
+ @Test
+ public void testResetAllWithoutScopeResetsTracingConfigurationForAllScopesAndReturnsIt() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "reset_all"));
+
+ // Ensure that configuration was actually reseted.
+ assertEquals(
+ Collections.singletonMap(
+ TX_SCOPE_SPECIFIC_COORDINATES,
+ TracingConfigurationManager.DEFAULT_TX_CONFIGURATION),
+ grid(0).tracingConfiguration().getAll(TX));
+
+ assertEquals(
+ Collections.singletonMap(
+ EXCHANGE_SCOPE_SPECIFIC_COORDINATES,
+ TracingConfigurationManager.DEFAULT_EXCHANGE_CONFIGURATION),
+ grid(0).tracingConfiguration().getAll(EXCHANGE));
+
+ // Check command result.
+ Map expTracingCfg =
+ new HashMap<>(DFLT_CONFIG_MAP);
+
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expTracingCfg.forEach(expRes::add);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration reset --scope TX"
+ * TX scope specific configuration will be reseted, TX label specific configuration should stay unchanged.
+ * Whole TX based configuration should be returned.
+ */
+ @Test
+ public void testResetWithScopeResetsScopeSpecificConfiguratoinAndReturnesScopeBasedConfiguration() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "reset", "--scope", "TX"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_SCOPE_SPECIFIC_COORDINATES, TracingConfigurationManager.DEFAULT_EXCHANGE_CONFIGURATION);
+ expRes.add(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration reset --scope TX --label label"
+ * TX label specific configuration will be removed, TX scope specific configuration should stay unchanged.
+ * Whole TX based configuration should be returned.
+ */
+ @Test
+ public void testResetWithScopeAndLabelResetsLabelSpecificConfiguratoinAndReturnesScopeBasedConfiguration() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "reset", "--scope", "TX",
+ "--label", "label"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(TX_SCOPE_SPECIFIC_COORDINATES, SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration set --scope TX --sampling-rate 0.123
+ * --included-scopes COMMUNICATION,EXCHANGE"
+ * TX scope specific configuration should be updated.
+ * Whole TX based configuration should be returned.
+ */
+ @Test
+ public void testSetWithScopeSetsScopeSpecificConfiguratoinAndReturnesScopeBasedConfiguration() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "set", "--scope", "TX",
+ "--sampling-rate", "0.123", "--included-scopes", "COMMUNICATION,EXCHANGE"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(
+ TX_SCOPE_SPECIFIC_COORDINATES,
+ new TracingConfigurationParameters.Builder().
+ withSamplingRate(0.123).
+ withIncludedScopes(new HashSet<>(Arrays.asList(COMMUNICATION, EXCHANGE))).build());
+
+ expRes.add(TX_LABEL_SPECIFIC_COORDINATES, SOME_LABEL_SPECIFIC_PARAMETERS);
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Ensure that in case of "--tracing-configuration set --scope TX --label label --sampling-rate 0.123
+ * --included-scopes COMMUNICATION,EXCHANGE"
+ * TX label specific configuration should be updated.
+ * Whole TX based configuration should be returned.
+ */
+ @Test
+ public void testSetWithScopeAndLabelSetsLabelSpecificConfiguratoinAndReturnsScopeBasedConfiguration() {
+ assertEquals(EXIT_CODE_OK, execute(hnd, "--tracing-configuration", "set", "--scope", "TX",
+ "--label", "label", "--sampling-rate", "0.123", "--included-scopes", "COMMUNICATION,EXCHANGE"));
+
+ // Check command result.
+ VisorTracingConfigurationTaskResult expRes = new VisorTracingConfigurationTaskResult();
+
+ expRes.add(
+ TX_SCOPE_SPECIFIC_COORDINATES,
+ SOME_SCOPE_SPECIFIC_PARAMETERS);
+
+ expRes.add(
+ TX_LABEL_SPECIFIC_COORDINATES,
+ new TracingConfigurationParameters.Builder().
+ withSamplingRate(0.123).
+ withIncludedScopes(new HashSet<>(Arrays.asList(COMMUNICATION, EXCHANGE))).build());
+
+ verifyResult(expRes);
+ }
+
+ /**
+ * Verify that expected result equals got one.
+ *
+ * @param expRes Expected command result.
+ */
+ private void verifyResult(VisorTracingConfigurationTaskResult expRes) {
+ VisorTracingConfigurationTaskResult gotRes = hnd.getLastOperationResult();
+
+ assertNotNull(gotRes);
+
+ assertNotNull(gotRes.tracingConfigurations());
+
+ assertTrue(expRes.tracingConfigurations().containsAll(gotRes.tracingConfigurations()) &&
+ gotRes.tracingConfigurations().containsAll(expRes.tracingConfigurations()));
+ }
+}
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index 7e1e1dbddd6b1e..0a13460dd28f24 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -147,6 +147,24 @@ If the file name isn't specified the output file name is: '.bin'
Set or display shutdown policy:
control.(sh|bat) --shutdown-policy [IMMEDIATE|GRACEFUL]
+ Print tracing configuration:
+ control.(sh|bat) --tracing-configuration
+
+ Print tracing configuration:
+ control.(sh|bat) --tracing-configuration get_all [--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX]
+
+ Print specific tracing configuration based on specified --scope and --label:
+ control.(sh|bat) --tracing-configuration get (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX) [--label]
+
+ Reset all specific tracing configuration the to default. If --scope is specified, then remove all label specific configuration for the given scope and reset given scope specific configuration to the default, if --scope is skipped then reset all tracing configurations to the default. Print tracing configuration.
+ control.(sh|bat) --tracing-configuration reset_all [--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX]
+
+ Reset specific tracing configuration to the default. If both --scope and --label are specified then remove given configuration, if only --scope is specified then reset given configuration to the default. Print reseted configuration.
+ control.(sh|bat) --tracing-configuration reset (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX) [--label]
+
+ Set new tracing configuration. If both --scope and --label are specified then add or override label specific configuration, if only --scope is specified, then override scope specific configuration. Print applied configuration.
+ control.(sh|bat) --tracing-configuration set (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX [--label] [--sampling-rate Decimal value between 0 and 1, where 0 means never and 1 means always. More or less reflects the probability of sampling specific trace.] [--included-scopes Set of scopes with comma as separator DISCOVERY|EXCHANGE|COMMUNICATION|TX])
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index 7e1e1dbddd6b1e..0a13460dd28f24 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -147,6 +147,24 @@ If the file name isn't specified the output file name is: '.bin'
Set or display shutdown policy:
control.(sh|bat) --shutdown-policy [IMMEDIATE|GRACEFUL]
+ Print tracing configuration:
+ control.(sh|bat) --tracing-configuration
+
+ Print tracing configuration:
+ control.(sh|bat) --tracing-configuration get_all [--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX]
+
+ Print specific tracing configuration based on specified --scope and --label:
+ control.(sh|bat) --tracing-configuration get (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX) [--label]
+
+ Reset all specific tracing configuration the to default. If --scope is specified, then remove all label specific configuration for the given scope and reset given scope specific configuration to the default, if --scope is skipped then reset all tracing configurations to the default. Print tracing configuration.
+ control.(sh|bat) --tracing-configuration reset_all [--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX]
+
+ Reset specific tracing configuration to the default. If both --scope and --label are specified then remove given configuration, if only --scope is specified then reset given configuration to the default. Print reseted configuration.
+ control.(sh|bat) --tracing-configuration reset (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX) [--label]
+
+ Set new tracing configuration. If both --scope and --label are specified then add or override label specific configuration, if only --scope is specified, then override scope specific configuration. Print applied configuration.
+ control.(sh|bat) --tracing-configuration set (--scope DISCOVERY|EXCHANGE|COMMUNICATION|TX [--label] [--sampling-rate Decimal value between 0 and 1, where 0 means never and 1 means always. More or less reflects the probability of sampling specific trace.] [--included-scopes Set of scopes with comma as separator DISCOVERY|EXCHANGE|COMMUNICATION|TX])
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.