You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by na...@apache.org on 2021/02/17 07:01:26 UTC

[ignite] branch master updated: IGNITE-14191 Add command to control.(sh|bin) to manage performance statistics (#8806)

This is an automated email from the ASF dual-hosted git repository.

namelchev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new a4631d6  IGNITE-14191 Add command to control.(sh|bin) to manage performance statistics (#8806)
a4631d6 is described below

commit a4631d6b2263b2acb6b4972f0aa2fd9deba2331d
Author: Nikita Amelchev <ns...@gmail.com>
AuthorDate: Wed Feb 17 10:00:52 2021 +0300

    IGNITE-14191 Add command to control.(sh|bin) to manage performance statistics (#8806)
---
 .../ignite/internal/commandline/CommandList.java   |   6 +-
 .../PerformanceStatisticsCommand.java              | 103 +++++++++++++++++++
 .../PerformanceStatisticsSubCommand.java           |  77 +++++++++++++++
 .../commandline/CommandHandlerParsingTest.java     |   3 +-
 .../testsuites/IgniteControlUtilityTestSuite.java  |   4 +-
 .../util/PerformanceStatisticsCommandTest.java     | 109 +++++++++++++++++++++
 .../VisorPerformanceStatisticsOperation.java       |  45 +++++++++
 .../VisorPerformanceStatisticsTask.java            |  88 +++++++++++++++++
 .../VisorPerformanceStatisticsTaskArg.java         |  64 ++++++++++++
 .../AbstractPerformanceStatisticsTest.java         |   2 +-
 ...ridCommandHandlerClusterByClassTest_help.output |   9 ++
 ...andHandlerClusterByClassWithSSLTest_help.output |   9 ++
 12 files changed, 515 insertions(+), 4 deletions(-)

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 7c45a36..897a5ac 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
@@ -22,6 +22,7 @@ import org.apache.ignite.internal.commandline.diagnostic.DiagnosticCommand;
 import org.apache.ignite.internal.commandline.encryption.EncryptionCommands;
 import org.apache.ignite.internal.commandline.meta.MetadataCommand;
 import org.apache.ignite.internal.commandline.metric.MetricCommand;
+import org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsCommand;
 import org.apache.ignite.internal.commandline.property.PropertyCommand;
 import org.apache.ignite.internal.commandline.query.KillCommand;
 import org.apache.ignite.internal.commandline.snapshot.SnapshotCommand;
@@ -95,7 +96,10 @@ public enum CommandList {
     PERSISTENCE("--persistence", new PersistenceCommand()),
 
     /** Command to manage PDS defragmentation. */
-    DEFRAGMENTATION("--defragmentation", new DefragmentationCommand());
+    DEFRAGMENTATION("--defragmentation", new DefragmentationCommand()),
+
+    /** Command to manage performance statistics. */
+    PERFORMANCE_STATISTICS("--performance-statistics", new PerformanceStatisticsCommand());
 
     /** 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/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsCommand.java
new file mode 100644
index 0000000..6887f71
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsCommand.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.commandline.performancestatistics;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.commandline.AbstractCommand;
+import org.apache.ignite.internal.commandline.Command;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.CommandLogger;
+import org.apache.ignite.internal.processors.performancestatistics.PerformanceStatisticsProcessor;
+import org.apache.ignite.internal.visor.performancestatistics.VisorPerformanceStatisticsTask;
+import org.apache.ignite.internal.visor.performancestatistics.VisorPerformanceStatisticsTaskArg;
+import org.apache.ignite.mxbean.PerformanceStatisticsMBean;
+
+import static org.apache.ignite.internal.commandline.CommandList.PERFORMANCE_STATISTICS;
+import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.START;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.STATUS;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.STOP;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.of;
+
+/**
+ * Performance statistics command.
+ *
+ * @see PerformanceStatisticsProcessor
+ * @see PerformanceStatisticsMBean
+ */
+public class PerformanceStatisticsCommand extends AbstractCommand<Object> {
+    /** Command argument. */
+    private VisorPerformanceStatisticsTaskArg taskArgs;
+
+    /** {@inheritDoc} */
+    @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+        try (GridClient client = Command.startClient(clientCfg)) {
+            String res = executeTaskByNameOnNode(
+                client,
+                VisorPerformanceStatisticsTask.class.getName(),
+                taskArgs,
+                null,
+                clientCfg
+            );
+
+            log.info(res);
+
+            return res;
+        }
+        catch (Throwable e) {
+            log.severe("Failed to perform operation.");
+            log.severe(CommandLogger.errorMessage(e));
+
+            throw e;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object arg() {
+        return taskArgs;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void parseArguments(CommandArgIterator argIter) {
+        PerformanceStatisticsSubCommand cmd = of(argIter.nextArg("Expected performance statistics action."));
+
+        if (cmd == null)
+            throw new IllegalArgumentException("Expected correct performance statistics action.");
+
+        taskArgs = new VisorPerformanceStatisticsTaskArg(cmd.visorOperation());
+    }
+
+    /** {@inheritDoc} */
+    @Override public void printUsage(Logger log) {
+        Command.usage(log, "Start collecting performance statistics in the cluster:",
+            PERFORMANCE_STATISTICS, START.toString());
+
+        Command.usage(log, "Stop collecting performance statistics in the cluster:",
+            PERFORMANCE_STATISTICS, STOP.toString());
+
+        Command.usage(log, "Get status of collecting performance statistics in the cluster:",
+            PERFORMANCE_STATISTICS, STATUS.toString());
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        return PERFORMANCE_STATISTICS.toCommandName();
+    }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsSubCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsSubCommand.java
new file mode 100644
index 0000000..3f33200
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/performancestatistics/PerformanceStatisticsSubCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.performancestatistics;
+
+import org.apache.ignite.internal.visor.performancestatistics.VisorPerformanceStatisticsOperation;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Set of performance statistics sub-commands.
+ *
+ * @see PerformanceStatisticsCommand
+ */
+public enum PerformanceStatisticsSubCommand {
+    /** Sub-command to start collecting performance statistics in the cluster. */
+    START("start", VisorPerformanceStatisticsOperation.START),
+
+    /** Sub-command to stop collecting performance statistics in the cluster. */
+    STOP("stop", VisorPerformanceStatisticsOperation.STOP),
+
+    /** Sub-command to get status of collecting performance statistics in the cluster. */
+    STATUS("status", VisorPerformanceStatisticsOperation.STATUS);
+
+    /** Sub-command name. */
+    private final String name;
+
+    /** Corresponding visor performance statistics operation. */
+    private final VisorPerformanceStatisticsOperation visorOp;
+
+    /**
+     * @param name Performance statistics sub-command name.
+     * @param visorOp Corresponding visor performance statistics operation.
+     */
+    PerformanceStatisticsSubCommand(String name, VisorPerformanceStatisticsOperation visorOp) {
+        this.name = name;
+        this.visorOp = visorOp;
+    }
+
+    /**
+     * @param text Command text (case insensitive).
+     * @return Command for the text. {@code Null} if there is no such command.
+     */
+    @Nullable public static PerformanceStatisticsSubCommand of(String text) {
+        for (PerformanceStatisticsSubCommand cmd : values()) {
+            if (cmd.name.equalsIgnoreCase(text))
+                return cmd;
+        }
+
+        return null;
+    }
+
+    /**
+     * @return {@link VisorPerformanceStatisticsOperation} which is associated with performance statistics subcommand.
+     */
+    public VisorPerformanceStatisticsOperation visorOperation() {
+        return visorOp;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return name;
+    }
+}
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 b1ab5f8..c4b3aa6 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
@@ -1034,6 +1034,7 @@ public class CommandHandlerParsingTest {
             cmd == CommandList.PROPERTY ||
             cmd == CommandList.SYSTEM_VIEW ||
             cmd == CommandList.METRIC ||
-            cmd == CommandList.DEFRAGMENTATION;
+            cmd == CommandList.DEFRAGMENTATION ||
+            cmd == CommandList.PERFORMANCE_STATISTICS;
     }
 }
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
index 6466487..28d643b 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
@@ -43,6 +43,7 @@ import org.apache.ignite.util.GridCommandHandlerTracingConfigurationTest;
 import org.apache.ignite.util.GridCommandHandlerWithSSLTest;
 import org.apache.ignite.util.KillCommandsCommandShTest;
 import org.apache.ignite.util.MetricCommandTest;
+import org.apache.ignite.util.PerformanceStatisticsCommandTest;
 import org.apache.ignite.util.SystemViewCommandTest;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
@@ -88,7 +89,8 @@ import org.junit.runners.Suite;
     GridCommandHandlerDefragmentationTest.class,
 
     SystemViewCommandTest.class,
-    MetricCommandTest.class
+    MetricCommandTest.class,
+    PerformanceStatisticsCommandTest.class
 })
 public class IgniteControlUtilityTestSuite {
 }
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/PerformanceStatisticsCommandTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/PerformanceStatisticsCommandTest.java
new file mode 100644
index 0000000..04da5de
--- /dev/null
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/PerformanceStatisticsCommandTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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 org.apache.ignite.internal.commandline.CommandList;
+import org.junit.Test;
+
+import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+import static org.apache.ignite.internal.commandline.CommandList.PERFORMANCE_STATISTICS;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.START;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.STATUS;
+import static org.apache.ignite.internal.commandline.performancestatistics.PerformanceStatisticsSubCommand.STOP;
+import static org.apache.ignite.internal.processors.performancestatistics.AbstractPerformanceStatisticsTest.cleanPerformanceStatisticsDir;
+import static org.apache.ignite.internal.processors.performancestatistics.AbstractPerformanceStatisticsTest.waitForStatisticsEnabled;
+import static org.apache.ignite.internal.visor.performancestatistics.VisorPerformanceStatisticsTask.STATUS_DISABLED;
+import static org.apache.ignite.internal.visor.performancestatistics.VisorPerformanceStatisticsTask.STATUS_ENABLED;
+
+/** Tests {@link CommandList#PERFORMANCE_STATISTICS} command. */
+public class PerformanceStatisticsCommandTest extends GridCommandHandlerClusterByClassAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        if (crd.context().performanceStatistics().enabled()) {
+            crd.context().performanceStatistics().stopCollectStatistics();
+
+            waitForStatisticsEnabled(false);
+        }
+
+        cleanPerformanceStatisticsDir();
+
+        assertFalse(crd.context().performanceStatistics().enabled());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        cleanPerformanceStatisticsDir();
+    }
+
+    /** @throws Exception If failed. */
+    @Test
+    public void testCommands() throws Exception {
+        int res = execute(PERFORMANCE_STATISTICS.text(), STATUS.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+        assertEquals(STATUS_DISABLED, lastOperationResult);
+
+        res = execute(PERFORMANCE_STATISTICS.text(), START.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+
+        waitForStatisticsEnabled(true);
+
+        res = execute(PERFORMANCE_STATISTICS.text(), STATUS.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+        assertEquals(STATUS_ENABLED, lastOperationResult);
+
+        res = execute(PERFORMANCE_STATISTICS.text(), STOP.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+
+        waitForStatisticsEnabled(false);
+
+        res = execute(PERFORMANCE_STATISTICS.text(), STATUS.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+        assertEquals(STATUS_DISABLED, lastOperationResult);
+    }
+
+    /** @throws Exception If failed. */
+    @Test
+    public void testStartAlreadyStarted() throws Exception {
+        int res = execute(PERFORMANCE_STATISTICS.text(), START.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+
+        waitForStatisticsEnabled(true);
+
+        res = execute(PERFORMANCE_STATISTICS.text(), START.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+    }
+
+    /** */
+    @Test
+    public void testStopAlreadyStopped() {
+        int res = execute(PERFORMANCE_STATISTICS.text(), STOP.toString());
+
+        assertEquals(EXIT_CODE_OK, res);
+    }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsOperation.java
new file mode 100644
index 0000000..ad3f738
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsOperation.java
@@ -0,0 +1,45 @@
+/*
+ * 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.performancestatistics;
+
+import org.jetbrains.annotations.Nullable;
+
+/** Performance statistics operation options. */
+public enum VisorPerformanceStatisticsOperation {
+    /** Start collecting performance statistics in the cluster. */
+    START,
+
+    /** Stop collecting performance statistics in the cluster. */
+    STOP,
+
+    /** Get status of collecting performance statistics in the cluster. */
+    STATUS;
+
+    /** Enumerated values. */
+    private static final VisorPerformanceStatisticsOperation[] 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 VisorPerformanceStatisticsOperation 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/performancestatistics/VisorPerformanceStatisticsTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsTask.java
new file mode 100644
index 0000000..b9052df
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsTask.java
@@ -0,0 +1,88 @@
+/*
+ * 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.performancestatistics;
+
+import org.apache.ignite.IgniteCheckedException;
+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.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorOneNodeTask;
+
+/** Represents visor task to manage performance statistics. */
+@GridInternal
+@GridVisorManagementTask
+public class VisorPerformanceStatisticsTask extends VisorOneNodeTask<VisorPerformanceStatisticsTaskArg, String> {
+    /** Performance statistics enabled status. */
+    public static final String STATUS_ENABLED = "Enabled.";
+
+    /** Performance statistics disabled status. */
+    public static final String STATUS_DISABLED = "Disabled.";
+
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** {@inheritDoc} */
+    @Override protected VisorJob<VisorPerformanceStatisticsTaskArg, String> job(VisorPerformanceStatisticsTaskArg arg) {
+        return new VisorPerformanceStatisticsJob(arg, false);
+    }
+
+    /** */
+    private static class VisorPerformanceStatisticsJob extends VisorJob<VisorPerformanceStatisticsTaskArg, String> {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /**
+         * Create job with specified argument.
+         *
+         * @param arg   Job argument.
+         * @param debug Flag indicating whether debug information should be printed into node log.
+         */
+        protected VisorPerformanceStatisticsJob(VisorPerformanceStatisticsTaskArg arg, boolean debug) {
+            super(arg, debug);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected String run(VisorPerformanceStatisticsTaskArg arg) throws IgniteException {
+            try {
+                switch (arg.operation()) {
+                    case START:
+                        ignite.context().performanceStatistics().startCollectStatistics();
+
+                        return "Started.";
+
+                    case STOP:
+                        ignite.context().performanceStatistics().stopCollectStatistics();
+
+                        return "Stopped.";
+
+                    case STATUS:
+
+                        return ignite.context().performanceStatistics().enabled() ? STATUS_ENABLED : STATUS_DISABLED;
+
+                    default:
+                        throw new IllegalArgumentException("Unknown operation: " + arg.operation());
+                }
+            }
+            catch (IgniteCheckedException e) {
+                throw U.convertException(e);
+            }
+        }
+    }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsTaskArg.java
new file mode 100644
index 0000000..72cc1ad
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/performancestatistics/VisorPerformanceStatisticsTaskArg.java
@@ -0,0 +1,64 @@
+/*
+ * 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.performancestatistics;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/** Represents argument for {@link VisorPerformanceStatisticsTask} execution. */
+public class VisorPerformanceStatisticsTaskArg extends IgniteDataTransferObject {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Operation. */
+    private VisorPerformanceStatisticsOperation op;
+
+    /** Default constructor. */
+    public VisorPerformanceStatisticsTaskArg() {
+        // No-op.
+    }
+
+    /** @param op Operation. */
+    public VisorPerformanceStatisticsTaskArg(VisorPerformanceStatisticsOperation op) {
+        this.op = op;
+    }
+
+    /** @return Operation. */
+    public VisorPerformanceStatisticsOperation operation() {
+        return op;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+        U.writeEnum(out, op);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException {
+        op = VisorPerformanceStatisticsOperation.fromOrdinal(in.readByte());
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorPerformanceStatisticsTaskArg.class, this);
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/performancestatistics/AbstractPerformanceStatisticsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/performancestatistics/AbstractPerformanceStatisticsTest.java
index e72794c..bdb6a05 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/performancestatistics/AbstractPerformanceStatisticsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/performancestatistics/AbstractPerformanceStatisticsTest.java
@@ -66,7 +66,7 @@ public abstract class AbstractPerformanceStatisticsTest extends GridCommonAbstra
     }
 
     /** Cleans performance statistics directory. */
-    protected static void cleanPerformanceStatisticsDir() throws Exception {
+    public static void cleanPerformanceStatisticsDir() throws Exception {
         U.resolveWorkDirectory(U.defaultWorkDirectory(), PERF_STAT_DIR, true);
     }
 
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 f67cd89..47da50b 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
@@ -251,6 +251,15 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
   Cancel scheduled or active PDS defragmentation on underlying node:
     control.(sh|bat) --defragmentation cancel
 
+  Start collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics start
+
+  Stop collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics stop
+
+  Get status of collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics status
+
 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 f67cd89..47da50b 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
@@ -251,6 +251,15 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
   Cancel scheduled or active PDS defragmentation on underlying node:
     control.(sh|bat) --defragmentation cancel
 
+  Start collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics start
+
+  Stop collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics stop
+
+  Get status of collecting performance statistics in the cluster:
+    control.(sh|bat) --performance-statistics status
+
 By default commands affecting the cluster require interactive confirmation.
 Use --yes option to disable it.