http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e1c3c8ce/modules/visor-console/src/main/scala/org/gridgain/visor/commands/tasks/VisorTasksCommand.scala ---------------------------------------------------------------------- diff --git a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/tasks/VisorTasksCommand.scala b/modules/visor-console/src/main/scala/org/gridgain/visor/commands/tasks/VisorTasksCommand.scala deleted file mode 100644 index b659b1d..0000000 --- a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/tasks/VisorTasksCommand.scala +++ /dev/null @@ -1,1488 +0,0 @@ -/* - * 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.gridgain.visor.commands.tasks - -import org.apache.ignite.internal.util.GridUtils -import org.apache.ignite.internal.util.typedef.internal.U -import org.apache.ignite.internal.visor.event.{VisorGridEvent, VisorGridJobEvent, VisorGridTaskEvent} -import org.apache.ignite.internal.visor.node.VisorNodeEventsCollectorTask -import org.apache.ignite.internal.visor.node.VisorNodeEventsCollectorTask.VisorNodeEventsCollectorTaskArg -import org.apache.ignite.internal.util.typedef.X - -import org.apache.ignite._ -import org.apache.ignite.events.IgniteEventType -import org.apache.ignite.events.IgniteEventType._ -import org.apache.ignite.lang.IgniteUuid - -import java.util.UUID - -import org.gridgain.visor._ -import org.gridgain.visor.commands.{VisorConsoleCommand, VisorTextTable} -import org.gridgain.visor.visor._ - -import scala.collection.JavaConversions._ -import scala.language.implicitConversions -import scala.util.control.Breaks._ - -/** - * Task execution state. - */ -private object State extends Enumeration { - /** Type shortcut. */ - type State = Value - - val STARTED = Value("Started") - val FINISHED = Value("Finished") - val TIMEDOUT = Value("Timed out") - val FAILED = Value("Failed") - val UNDEFINED = Value("<undefined>") -} - -import org.gridgain.visor.commands.tasks.State._ - -/** - * Task execution data. - */ -private case class VisorExecution( - id: IgniteUuid, - taskName: String, - var evts: List[_ <: VisorGridEvent] = Nil, - var nodeIds: Set[UUID] = Set.empty[UUID], - var failedNodeIds: Set[UUID] = Set.empty[UUID], - var startTs: Long = Long.MaxValue, - var endTs: Long = Long.MinValue, - var state: State = UNDEFINED, - var origNodeId: UUID = null -) { - assert(id != null) - assert(taskName != null) - - /** - * ID8 form of task execution ID. - */ - lazy val id8: String = - GridUtils.id8(id) - - /** - * ID8 of the task execution + its associated variable. - */ - lazy val id8Var: String = - id8 + "(@" + setVarIfAbsent(id, "e") + ')' - - /** - * Task host + its associated variable host. - */ - lazy val taskNameVar: String = - taskName + "(@" + setVarIfAbsent(taskName, "t") + ')' - - /** - * Gets number of job rejections in this session. - */ - lazy val rejections: Int = - evts.count(_.typeId() == EVT_JOB_REJECTED) - - /** - * Gets number of job cancellations in this session. - */ - lazy val cancels: Int = - evts.count(_.typeId() == EVT_JOB_CANCELLED) - - /** - * Gets number of job finished in this session. - */ - lazy val finished: Int = - evts.count(_.typeId() == EVT_JOB_FINISHED) - - /** - * Gets number of job started in this session. - */ - lazy val started: Int = - evts.count(_.typeId() == EVT_JOB_STARTED) - - /** - * Gets number of job failures in this session. - */ - lazy val failures: Int = - evts.count(_.typeId() == EVT_JOB_FAILED) - - /** - * Gets number of job failovers in this session. - */ - lazy val failovers: Int = - evts.count(_.typeId() == EVT_JOB_FAILED_OVER) - - /** - * Gets duration of the session. - */ - lazy val duration: Long = - endTs - startTs - - override def equals(r: Any) = - if (this eq r.asInstanceOf[AnyRef]) - true - else if (r == null || !r.isInstanceOf[VisorExecution]) - false - else - r.asInstanceOf[VisorExecution].id == id - - override def hashCode() = - id.hashCode() -} - -/** - * Task data. - */ -private case class VisorTask( - taskName: String, - var execs: Set[VisorExecution] = Set.empty[VisorExecution] -) { - /** - * Task host + its associated variable host. - */ - lazy val taskNameVar: String = - taskName + "(@" + setVarIfAbsent(taskName, "t") + ')' - - /** - * Oldest timestamp for this task (oldest event related to this task). - */ - lazy val oldest: Long = - execs.min(Ordering.by[VisorExecution, Long](_.startTs)).startTs - - /** - * Latest timestamp for this task (latest event related to this task). - */ - lazy val latest: Long = - execs.max(Ordering.by[VisorExecution, Long](_.endTs)).endTs - - /** - * Gets timeframe of this task executions. - */ - lazy val timeframe: Long = - latest - oldest - - /** - * Total number of execution for this task. - */ - lazy val totalExecs: Int = - execs.size - - /** - * Gets number of execution with given state. - * - * @param state Execution state to filter by. - */ - def execsFor(state: State): Int = - execs.count(_.state == state) - - /** - * Minimal duration of this task execution. - */ - lazy val minDuration: Long = - execs.min(Ordering.by[VisorExecution, Long](_.duration)).duration - - /** - * Maximum duration of this task execution. - */ - lazy val maxDuration: Long = - execs.max(Ordering.by[VisorExecution, Long](_.duration)).duration - - /** - * Average duration of this task execution. - */ - lazy val avgDuration: Long = - (0L /: execs)((b, a) => a.duration + b) / execs.size - - /** - * Minimal number of nodes this task was executed on. - */ - lazy val minNodes: Int = - execs.min(Ordering.by[VisorExecution, Int](_.nodeIds.size)).nodeIds.size - - /** - * Minimal number of nodes this task was executed on. - */ - lazy val maxNodes: Int = - execs.max(Ordering.by[VisorExecution, Int](_.nodeIds.size)).nodeIds.size - - /** - * Average number of nodes this task was executed on. - */ - lazy val avgNodes: Int = - (0 /: execs)((b, a) => a.nodeIds.size + b) / execs.size - - override def equals(r: Any) = - if (this eq r.asInstanceOf[AnyRef]) - true - else if (r == null || !r.isInstanceOf[VisorTask]) - false - else - r.asInstanceOf[VisorTask].taskName == taskName - - override def hashCode() = - taskName.hashCode() -} - -/** - * ==Overview== - * Visor 'tasks' command implementation. - * - * ==Help== - * {{{ - * +---------------------------------------------------------------------------------------+ - * | tasks | Prints statistics about tasks and executions. | - * | | | - * | | Note that this command depends on GridGain events. | - * | | | - * | | GridGain events can be individually enabled and disabled and disabled events | - * | | can affect the results produced by this command. Note also that configuration | - * | | of Event Storage SPI that is responsible for temporary storage of generated | - * | | events on each node can also affect the functionality of this command. | - * | | | - * | | By default - all events are enabled and GridGain stores last 10,000 local | - * | | events on each node. Both of these defaults can be changed in configuration. | - * +---------------------------------------------------------------------------------------+ - * }}} - * - * ====Specification==== - * {{{ - * tasks - * tasks "-l {-t=<num>s|m|h|d} {-r}" - * tasks "-s=<substring> {-t=<num>s|m|h|d} {-r}" - * tasks "-g {-t=<num>s|m|h|d} {-r}" - * tasks "-h {-t=<num>s|m|h|d} {-r}" - * tasks "-n=<task-name> {-r}" - * tasks "-e=<exec-id>" - * }}} - * - * ====Arguments==== - * {{{ - * -l - * List all tasks and executions for a given time period. - * Executions sorted chronologically (see '-r'), and tasks alphabetically - * See '-t=<num>s|m|h|d' on how to specify the time limit. - * Default time period is one hour, i.e '-t=1h' - * - * This is a default mode when command is called without parameters. - * -s=<substring> - * List all tasks and executions for a given task name substring. - * Executions sorted chronologically (see '-r'), and tasks alphabetically - * See '-t=<num>s|m|h|d' on how to specify the time limit. - * Default time period is one hour, i.e '-t=1h' - * -g - * List all tasks grouped by nodes for a given time period. - * Tasks sorted alphabetically - * See '-t=<num>s|m|h|d' on how to specify the time limit. - * Default time period is one hour, i.e '-t=1h' - * -h - * List all tasks grouped by hosts for a given time period. - * Tasks sorted alphabetically - * See '-t=<num>s|m|h|d' on how to specify the time limit. - * Default time period is one hour, i.e '-t=1h' - * -t=<num>s|m|h|d - * Defines time frame for '-l' parameter: - * =<num>s Last <num> seconds. - * =<num>m Last <num> minutes. - * =<num>h Last <num> hours. - * =<num>d Last <num> days. - * -r - * Reverse sorting of executions. - * -n=<task-name> - * Prints aggregated statistic for named task. - * -e=<exec-id> - * Prints aggregated statistic for given task execution. - * }}} - * - * ====Examples==== - * {{{ - * visor tasks "-l" - * Prints list of all tasks and executions for the last hour (default). - * visor tasks - * Prints list of all tasks and executions for the last hour (default). - * visor tasks "-l -t=5m" - * Prints list of tasks and executions that started during last 5 minutes. - * visor tasks "-s=Task" - * Prints list of all tasks and executions that have 'Task' in task name. - * visor tasks "-g" - * Prints list of tasks grouped by nodes. - * visor tasks "-g -t=5m" - * Prints list of tasks that started during last 5 minutes grouped by nodes. - * visor tasks "-h" - * Prints list of tasks grouped by hosts. - * visor tasks "-h -t=5m" - * Prints list of tasks that started during last 5 minutes grouped by hosts. - * visor tasks "-n=GridTask" - * Prints summary for task named 'GridTask'. - * visor tasks "-e=7D5CB773-225C-4165-8162-3BB67337894B" - * Traces task execution with ID '7D5CB773-225C-4165-8162-3BB67337894B'. - * visor tasks "-e=@s1" - * Traces task execution with ID taken from 's1' memory variable. - * }}} - */ -class VisorTasksCommand { - /** Limit for printing tasks and executions. */ - private val SHOW_LIMIT = 100 - - /** - * Prints error message and advise. - * - * @param errMsgs Error messages. - */ - private def scold(errMsgs: Any*) { - assert(errMsgs != null) - - warn(errMsgs: _*) - warn("Type 'help tasks' to see how to use this command.") - } - - /** - * ===Command=== - * Prints statistics about executed tasks. - * - * ===Examples=== - * <ex>tasks</ex> - * Prints list of all tasks for the last hour (default). - * - * <ex>tasks "-l"</ex> - * Prints list of all tasks for the last hour (default). - * - * <ex>tasks "-l -a"</ex> - * Prints list of all tasks and executions for the last hour (default). - * - * <ex>tasks "-l -t=5m"</ex> - * Prints list of tasks that started during last 5 minutes. - * - * <ex>tasks "-g"</ex> - * Prints list of tasks grouped by nodes. - * - * <ex>tasks "-g -t=5m"</ex> - * Prints list of tasks that started during last 5 minutes grouped by nodes. - * - * <ex>tasks "-h"</ex> - * Prints list of tasks grouped by hosts. - * - * <ex>tasks "-h -t=5m"</ex> - * Prints list of tasks that started during last 5 minutes grouped by hosts. - * - * <ex>tasks "-n=GridTask"</ex> - * Prints summary for task named 'GridTask'. - * - * <ex>tasks "-n=GridTask -a"</ex> - * Prints summary and executions for task named 'GridTask'. - * - * <ex>tasks "-e=7D5CB773-225C-4165-8162-3BB67337894B"</ex> - * Traces task execution with ID '7D5CB773-225C-4165-8162-3BB67337894B'. - * - * <ex>tasks "-e=@s1"</ex> - * Traces task execution with ID taken from 's1' memory variable. - * - * @param args Command arguments. - */ - def tasks(args: String) { - if (!isConnected) - adviseToConnect() - else { - val argLst = parseArgs(args) - - if (hasArgFlag("l", argLst)) { - val p = timePeriod(argValue("t", argLst) getOrElse "1h") - - if (p.isDefined) - list(p.get, null, hasArgFlag("r", argLst), hasArgFlag("a", argLst)) - } - else if (hasArgName("s", argLst)) { - val tf = timePeriod(argValue("t", argLst) getOrElse "1h") - - if (tf.isDefined) { - val s = argValue("s", argLst) - - if (s.isDefined) { - list(tf.get, s.get, hasArgFlag("r", argLst), hasArgFlag("a", argLst)) - } - else - scold("Invalid arguments: " + args) - } - } - else if (hasArgFlag("g", argLst)) { - val f = timePeriod(argValue("t", argLst) getOrElse "1h") - - if (f.isDefined) - nodes(f.get) - } - else if (hasArgFlag("h", argLst)) { - val f = timePeriod(argValue("t", argLst) getOrElse "1h") - - if (f.isDefined) - hosts(f.get) - } - else if (hasArgName("n", argLst)) { - val n = argValue("n", argLst) - - if (!n.isDefined) - scold("Invalid arguments: " + args) - else - task(n.get, hasArgFlag("r", argLst), hasArgFlag("a", argLst)) - } - else if (hasArgName("e", argLst)) { - val s = argValue("e", argLst) - - if (!s.isDefined) - scold("Invalid arguments: " + args) - else - exec(s.get, hasArgFlag("r", argLst)) - } - else - scold("Incorrect arguments: " + args) - } - } - - /** - * ===Command=== - * Simply a shortcut for `tasks("-l")` - * - * ===Examples=== - * <ex>tasks</ex> - * Prints list of all tasks and executions for the last hour (default). - */ - def tasks() { - tasks("-l") - } - - /** - * Creates predicate that filters events by timestamp. - * - * @param arg Command argument. - * @return time period. - */ - private def timePeriod(arg: String): Option[Long] = { - assert(arg != null) - - var n = 0 - - try - n = arg.substring(0, arg.length - 1).toInt - catch { - case e: NumberFormatException => - scold("Time frame size is not numeric in: " + arg) - - return None - } - - if (n <= 0) { - scold("Time frame size is not positive in: " + arg) - - None - } - else { - val m = arg.last match { - case 's' => 1000 - case 'm' => 1000 * 60 - case 'h' => 1000 * 60 * 60 - case 'd' => 1000 * 60 * 60 * 24 - case _ => - scold("Invalid time frame suffix in: " + arg) - - return None - } - - Some(n * m) - } - } - - /** - * Gets collections of tasks and executions for given event filter. - * - * @param evts Collected events. - */ - private def mkData(evts: java.lang.Iterable[_ <: VisorGridEvent]): (List[VisorTask], List[VisorExecution]) = { - var sMap = Map.empty[IgniteUuid, VisorExecution] // Execution map. - var tMap = Map.empty[String, VisorTask] // Task map. - - if (evts == null) - return tMap.values.toList -> sMap.values.toList - - def getSession(id: IgniteUuid, taskName: String): VisorExecution = { - assert(id != null) - assert(taskName != null) - - sMap.getOrElse(id, { - val s = VisorExecution(id, taskName) - - sMap = sMap + (id -> s) - - s - }) - } - - def getTask(taskName: String): VisorTask = { - assert(taskName != null) - - tMap.getOrElse(taskName, { - val t = VisorTask(taskName) - - tMap = tMap + (taskName -> t) - - t - }) - } - - /** - * If task name is task class name, show simple class name. - * - * @param taskName Task name. - * @param taskClsName Task class name. - * @return Simple class name. - */ - def taskSimpleName(taskName: String, taskClsName: String) = { - if (taskName == taskClsName || taskName == null) { - val idx = taskClsName.lastIndexOf('.') - - if (idx >= 0) taskClsName.substring(idx + 1) else taskClsName - } - else - taskName - } - - evts.foreach { - case te: VisorGridTaskEvent => - val displayedTaskName = taskSimpleName(te.taskName(), te.taskClassName()) - - val s = getSession(te.taskSessionId(), displayedTaskName) - val t = getTask(displayedTaskName) - - t.execs = t.execs + s - - s.evts = s.evts :+ te - s.nodeIds = s.nodeIds + te.nid() - s.startTs = math.min(s.startTs, te.timestamp()) - s.endTs = math.max(s.endTs, te.timestamp()) - - te.typeId() match { - case EVT_TASK_STARTED => - if (s.state == UNDEFINED) s.state = STARTED - - s.origNodeId = te.nid() - - case EVT_TASK_FINISHED => - if (s.state == UNDEFINED || s.state == STARTED) s.state = FINISHED - - s.origNodeId = te.nid() - - case EVT_TASK_FAILED => if (s.state == UNDEFINED || s.state == STARTED) s.state = FAILED - case EVT_TASK_TIMEDOUT => if (s.state == UNDEFINED || s.state == STARTED) s.state = TIMEDOUT - case _ => - } - - case je: VisorGridJobEvent => - val displayedTaskName = taskSimpleName(je.taskName(), je.taskClassName()) - val s = getSession(je.taskSessionId(), displayedTaskName) - val t = getTask(displayedTaskName) - - t.execs = t.execs + s - - // Collect node IDs where jobs didn't finish ok. - je.typeId() match { - case EVT_JOB_CANCELLED | EVT_JOB_FAILED | EVT_JOB_REJECTED | EVT_JOB_TIMEDOUT => - s.failedNodeIds = s.failedNodeIds + je.nid() - case _ => - } - - s.evts = s.evts :+ je - s.nodeIds = s.nodeIds + je.nid() - s.startTs = math.min(s.startTs, je.timestamp()) - s.endTs = math.max(s.endTs, je.timestamp()) - - case _ => - } - - tMap.values.toList -> sMap.values.toList - } - - /** - * Prints list of tasks and executions. - * - * @param p Event period. - * @param taskName Task name filter. - * @param reverse Reverse session chronological sorting. - * @param all Whether to show full information. - */ - private def list(p: Long, taskName: String, reverse: Boolean, all: Boolean) { - breakable { - try { - val prj = grid.forRemotes() - - val evts = grid.compute(prj).execute(classOf[VisorNodeEventsCollectorTask], - toTaskArgument(prj.nodes.map(_.id()), VisorNodeEventsCollectorTaskArg.createTasksArg(p, taskName, null))) - - val (tLst, eLst) = mkData(evts) - - if (tLst.isEmpty) { - scold("No tasks or executions found.") - - break() - } - - if (all) { - val execsT = VisorTextTable() - - execsT.maxCellWidth = 35 - - execsT #=( - ( - "ID8(@ID), Start/End,", - "State & Duration" - ), - "Task Name(@)", - "Nodes IP, ID8(@)", - "Jobs" - ) - - var sortedExecs = if (!reverse) eLst.sortBy(_.startTs).reverse else eLst.sortBy(_.startTs) - - if (sortedExecs.size > SHOW_LIMIT) { - warnLimit(sortedExecs.size, "execution") - - sortedExecs = sortedExecs.slice(0, SHOW_LIMIT) - } - - sortedExecs foreach ((e: VisorExecution) => { - execsT +=( - ( - e.id8Var, - " ", - "Start: " + formatDateTime(e.startTs), - "End : " + formatDateTime(e.endTs), - " ", - e.state + ": " + X.timeSpan2HMSM(e.duration) - ), - e.taskNameVar, - (e.nodeIds.map((u: UUID) => { - var s = "" - - if (e.origNodeId != null && e.origNodeId == u) - s = s + "> " - else if (e.failedNodeIds.contains(u)) - s = s + "! " - else - s = s + " " - - s + nodeId8Addr(u) - }).toList :+ ("Nodes: " + e.nodeIds.size)).reverse - , - if (e.started > 0) - ( - "St: " + e.started, - "Fi: " + e.finished + " (" + formatInt(100 * e.finished / e.started) + "%)", - " ", - "Ca: " + e.cancels + " (" + formatInt(100 * e.cancels / e.started) + "%)", - "Re: " + e.rejections + " (" + formatInt(100 * e.rejections / e.started) + "%)", - "Fo: " + e.failovers + " (" + formatInt(100 * e.failovers / e.started) + "%)", - "Fa: " + e.failures + " (" + formatInt(100 * e.failures / e.started) + "%)" - ) - else - ( - "St: " + e.started, - "Fi: " + e.finished, - " ", - "Ca: " + e.cancels, - "Re: " + e.rejections, - "Fo: " + e.failovers, - "Fa: " + e.failures - ) - ) - }) - - println("Executions: " + eLst.size) - - execsT.render() - - nl() - - execFootnote() - - nl() - } - - val tasksT = VisorTextTable() - - tasksT.maxCellWidth = 55 - - tasksT #=( - "Task Name(@ID), Oldest/Latest & Rate", - "Duration", - "Nodes", - "Executions" - ) - - var sortedTasks = tLst.sortBy(_.taskName) - - if (sortedTasks.size > SHOW_LIMIT) { - warnLimit(sortedTasks.size, "task") - - sortedTasks = sortedTasks.slice(0, SHOW_LIMIT) - } - - sortedTasks foreach ((t: VisorTask) => { - val sE = t.execsFor(STARTED) - val fE = t.execsFor(FINISHED) - val eE = t.execsFor(FAILED) - val uE = t.execsFor(UNDEFINED) - val tE = t.execsFor(TIMEDOUT) - - val n = t.execs.size - - tasksT +=( - ( - t.taskNameVar, - " ", - "Oldest: " + formatDateTime(t.oldest), - "Latest: " + formatDateTime(t.latest), - " ", - "Exec. Rate: " + n + " in " + X.timeSpan2HMSM(t.timeframe) - ), - ( - "min: " + X.timeSpan2HMSM(t.minDuration), - "avg: " + X.timeSpan2HMSM(t.avgDuration), - "max: " + X.timeSpan2HMSM(t.maxDuration) - ), - ( - "min: " + t.minNodes, - "avg: " + t.avgNodes, - "max: " + t.maxNodes - ), - ( - "Total: " + n, - " ", - "St: " + sE + " (" + formatInt(100 * sE / n) + "%)", - "Fi: " + fE + " (" + formatInt(100 * fE / n) + "%)", - "Fa: " + eE + " (" + formatInt(100 * eE / n) + "%)", - "Un: " + uE + " (" + formatInt(100 * uE / n) + "%)", - "Ti: " + tE + " (" + formatInt(100 * tE / n) + "%)" - ) - ) - }) - - println("Tasks: " + tLst.size) - - tasksT.render() - - nl() - - taskFootnote() - } - catch { - case e: IgniteCheckedException => - scold(e.getMessage) - - break() - } - } - } - - /** - * Prints task footnote. - */ - private def taskFootnote() { - println("'St' - Started tasks.") - println("'Fi' - Finished tasks.") - println("'Fa' - Failed tasks.") - println("'Un' - Undefined tasks (originating node left topology).") - println("'Ti' - Timed out tasks.") - } - - /** - * Prints execution footnote. - */ - private def execFootnote() { - println("'St' - Started jobs during the task execution.") - println("'Fi' - Finished jobs during the task execution.") - println("'Ca' - Cancelled jobs during the task execution.") - println("'Re' - Rejected jobs during the task execution.") - println("'Fo' - Failed over jobs during the task execution.") - println("'Fa' - Failed jobs during the task execution.") - println("'>' - Originating node (if still in topology).") - println("'!' - Node on which job didn't complete successfully.") - println("\n<undefined> - Originating node left topology, i.e. execution state is unknown.") - } - - /** - * Prints task summary. - * - * @param taskName Task host. - * @param reverse Reverse session chronological sorting? - * @param all Whether to show full information. - */ - private def task(taskName: String, reverse: Boolean, all: Boolean) { - breakable { - assert(taskName != null) - - try { - val prj = grid.forRemotes() - - val evts = grid.compute(prj).execute(classOf[VisorNodeEventsCollectorTask], toTaskArgument(prj.nodes.map(_.id()), - VisorNodeEventsCollectorTaskArg.createTasksArg(null, taskName, null))) - - val (tLst, eLst) = mkData(evts) - - if (tLst.isEmpty) { - scold("Task not found: " + taskName) - - break() - } - - val tasksT = VisorTextTable() - - tasksT.maxCellWidth = 55 - - tasksT #= ("Oldest/Latest & Rate", "Duration", "Nodes", "Executions") - - assert(tLst.size == 1) - - val t = tLst.head - - val sE = t.execsFor(STARTED) - val fE = t.execsFor(FINISHED) - val eE = t.execsFor(FAILED) - val uE = t.execsFor(UNDEFINED) - val tE = t.execsFor(TIMEDOUT) - - val n = t.execs.size - - tasksT += ( - ( - "Oldest: " + formatDateTime(t.oldest), - "Latest: " + formatDateTime(t.latest), - " ", - "Exec. Rate: " + n + " in " + X.timeSpan2HMSM(t.timeframe) - ), - ( - "min: " + X.timeSpan2HMSM(t.minDuration), - "avg: " + X.timeSpan2HMSM(t.avgDuration), - "max: " + X.timeSpan2HMSM(t.maxDuration) - ), - ( - "min: " + t.minNodes, - "avg: " + t.avgNodes, - "max: " + t.maxNodes - ), - ( - "Total: " + n, - " ", - "St: " + sE + " (" + formatInt(100 * sE / n) + "%)", - "Fi: " + fE + " (" + formatInt(100 * fE / n) + "%)", - "Fa: " + eE + " (" + formatInt(100 * eE / n) + "%)", - "Un: " + uE + " (" + formatInt(100 * uE / n) + "%)", - "Ti: " + tE + " (" + formatInt(100 * tE / n) + "%)" - ) - ) - - println("Task: " + t.taskNameVar) - - tasksT.render() - - nl() - - taskFootnote() - - if (all) { - val execsT = VisorTextTable() - - execsT.maxCellWidth = 35 - - execsT #= ( - ( - "ID8(@ID), Start/End,", - "State & Duration" - ), - "Task Name(@)", - "Nodes IP, ID8(@)", - "Jobs" - ) - - var sorted = if (!reverse) eLst.sortBy(_.startTs).reverse else eLst.sortBy(_.startTs) - - if (sorted.size > SHOW_LIMIT) { - warnLimit(sorted.size, "execution") - - sorted = sorted.slice(0, SHOW_LIMIT) - } - - sorted foreach ((e: VisorExecution) => { - execsT += ( - ( - e.id8Var, - " ", - "Start: " + formatDateTime(e.startTs), - "End : " + formatDateTime(e.endTs), - " ", - e.state + ": " + X.timeSpan2HMSM(e.duration) - ), - e.taskNameVar, - (e.nodeIds.map((u: UUID) => { - var s = "" - - if (e.origNodeId != null && e.origNodeId == u) - s = s + "> " - else if (e.failedNodeIds.contains(u)) - s = s + "! " - else - s = s + " " - - s + nodeId8Addr(u) - }).toList :+ ("Nodes: " + e.nodeIds.size)).reverse - , - if (e.started > 0) - ( - "St: " + e.started, - "Fi: " + e.finished + " (" + formatInt(100 * e.finished / e.started) + "%)", - " ", - "Ca: " + e.cancels + " (" + formatInt(100 * e.cancels / e.started) + "%)", - "Re: " + e.rejections + " (" + formatInt(100 * e.rejections / e.started) + "%)", - "Fo: " + e.failovers + " (" + formatInt(100 * e.failovers / e.started) + "%)", - "Fa: " + e.failures + " (" + formatInt(100 * e.failures / e.started) + "%)" - ) - else - ( - "St: " + e.started, - "Fi: " + e.finished, - " ", - "Ca: " + e.cancels, - "Re: " + e.rejections, - "Fo: " + e.failovers, - "Fa: " + e.failures - ) - ) - }) - - println("\nExecutions: " + eLst.size) - - execsT.render() - - nl() - - execFootnote() - } - } - catch { - case e: IgniteCheckedException => - scold(e.getMessage) - - break() - } - } - } - - /** - * Prints task execution. - * - * @param sesId String representation of session ID. - * @param reverse Reverse session chronological sorting? - */ - private def exec(sesId: String, reverse: Boolean) { - breakable { - assert(sesId != null) - - var uuid: IgniteUuid = null - - try - uuid = IgniteUuid.fromString(sesId) - catch { - case e: Exception => - scold("Invalid execution ID: " + sesId) - - break() - } - - try { - val prj = grid.forRemotes() - - val evts = grid.compute(prj).execute(classOf[VisorNodeEventsCollectorTask], toTaskArgument(prj.nodes.map(_.id()), - VisorNodeEventsCollectorTaskArg.createTasksArg(null, null, uuid))) - - val (tLst, eLst) = mkData(evts) - - if (tLst.isEmpty) { - scold("Task execution not found: " + sesId) - - break() - } - - assert(eLst.size == 1) - assert(tLst.size == 1) - - val execT = VisorTextTable() - - execT.maxCellWidth = 35 - - execT #= ( - ( - "ID8(@ID), Start/End,", - "State & Duration" - ), - "Task Name(@)", - "Nodes IP, ID8(@)", - "Jobs" - ) - - val e = eLst.head - - execT += ( - ( - e.id8Var, - " ", - "Start: " + formatDateTime(e.startTs), - "End : " + formatDateTime(e.endTs), - " ", - e.state + ": " + X.timeSpan2HMSM(e.duration) - ), - e.taskNameVar, - (e.nodeIds.map((u: UUID) => { - var s = "" - - if (e.origNodeId != null && e.origNodeId == u) - s = s + "> " - else if (e.failedNodeIds.contains(u)) - s = s + "! " - else - s = s + " " - - s + nodeId8Addr(u) - }).toList :+ ("Nodes: " + e.nodeIds.size)).reverse - , - if (e.started > 0) - ( - "St: " + e.started, - "Fi: " + e.finished + " (" + formatInt(100 * e.finished / e.started) + "%)", - " ", - "Ca: " + e.cancels + " (" + formatInt(100 * e.cancels / e.started) + "%)", - "Re: " + e.rejections + " (" + formatInt(100 * e.rejections / e.started) + "%)", - "Fo: " + e.failovers + " (" + formatInt(100 * e.failovers / e.started) + "%)", - "Fa: " + e.failures + " (" + formatInt(100 * e.failures / e.started) + "%)" - ) - else - ( - "St: " + e.started, - "Fi: " + e.finished, - " ", - "Ca: " + e.cancels, - "Re: " + e.rejections, - "Fo: " + e.failovers, - "Fa: " + e.failures - ) - ) - - println("Execution: " + e.id8Var) - - execT.render() - - nl() - - execFootnote() - - val evtsT = VisorTextTable() - - evtsT #= ("Timestamp", "Node ID8(@)", "Event") - - val se = if (!reverse) e.evts.sortBy(_.timestamp()) else e.evts.sortBy(_.timestamp()).reverse - - se.foreach(e => evtsT += ( - formatDateTime(e.timestamp()), - nodeId8Addr(e.nid()), - e.name() - )) - - println("\nTrace:") - - evtsT.render() - } - catch { - case e: IgniteCheckedException => - scold(e.getMessage) - - break() - } - } - } - - /** - * Prints list of tasks grouped by nodes. - * - * @param f Event filter. - */ - private def nodes(f: Long) { - breakable { - try { - val prj = grid.forRemotes() - - val evts = grid.compute(prj).execute(classOf[VisorNodeEventsCollectorTask], toTaskArgument(prj.nodes.map(_.id()), - VisorNodeEventsCollectorTaskArg.createTasksArg(f, null, null))) - - val eLst = mkData(evts)._2 - - if (eLst.isEmpty) { - scold("No executions found.") - - break() - } - - var nMap = Map.empty[UUID, Set[VisorExecution]] - - eLst.foreach(e => { - e.nodeIds.foreach(id => { - var eSet = nMap.getOrElse(id, Set.empty[VisorExecution]) - - eSet += e - - nMap += (id -> eSet) - }) - }) - - nMap.foreach(e => { - val id = e._1 - val execs = e._2 - - val execsMap = execs.groupBy(_.taskName) - - val tasksT = VisorTextTable() - - tasksT.maxCellWidth = 55 - - tasksT #=( - "Task Name(@), Oldest/Latest & Rate", - "Duration", - "Executions" - ) - - println("Tasks executed on node " + nodeId8Addr(id) + ":") - - var sortedNames = execsMap.keys.toList.sorted - - if (sortedNames.size > SHOW_LIMIT) { - warnLimit(sortedNames.size, "task") - - sortedNames = sortedNames.slice(0, SHOW_LIMIT) - } - - sortedNames.foreach(taskName => { - val t = VisorTask(taskName, execsMap.get(taskName).get) - - val sE = t.execsFor(STARTED) - val fE = t.execsFor(FINISHED) - val eE = t.execsFor(FAILED) - val uE = t.execsFor(UNDEFINED) - val tE = t.execsFor(TIMEDOUT) - - val n = t.execs.size - - tasksT +=( - ( - t.taskNameVar, - " ", - "Oldest: " + formatDateTime(t.oldest), - "Latest: " + formatDateTime(t.latest), - " ", - "Exec. Rate: " + n + " in " + X.timeSpan2HMSM(t.timeframe) - ), - ( - "min: " + X.timeSpan2HMSM(t.minDuration), - "avg: " + X.timeSpan2HMSM(t.avgDuration), - "max: " + X.timeSpan2HMSM(t.maxDuration) - ), - ( - "Total: " + n, - " ", - "St: " + sE + " (" + formatInt(100 * sE / n) + "%)", - "Fi: " + fE + " (" + formatInt(100 * fE / n) + "%)", - "Fa: " + eE + " (" + formatInt(100 * eE / n) + "%)", - "Un: " + uE + " (" + formatInt(100 * uE / n) + "%)", - "Ti: " + tE + " (" + formatInt(100 * tE / n) + "%)" - ) - ) - }) - - tasksT.render() - - nl() - }) - - taskFootnote() - } - catch { - case e: IgniteCheckedException => - scold(e.getMessage) - - break() - } - } - } - - /** - * Prints list of tasks grouped by hosts. - * - * @param f Event filter. - */ - private def hosts(f: Long) { - breakable { - try { - val prj = grid.forRemotes() - - val evts = grid.compute(prj).execute(classOf[VisorNodeEventsCollectorTask], toTaskArgument(prj.nodes.map(_.id()), - VisorNodeEventsCollectorTaskArg.createTasksArg(f, null, null))) - - val eLst = mkData(evts)._2 - - if (eLst.isEmpty) { - scold("No executions found.") - - break() - } - - var hMap = Map.empty[String, Set[VisorExecution]] - - eLst.foreach(e => { - e.nodeIds.foreach(id => { - val host = grid.node(id).addresses.headOption - - if (host.isDefined) { - var eSet = hMap.getOrElse(host.get, Set.empty[VisorExecution]) - - eSet += e - - hMap += (host.get -> eSet) - } - }) - }) - - hMap.foreach(e => { - val host = e._1 - val execs = e._2 - - val execsMap = execs.groupBy(_.taskName) - - val tasksT = VisorTextTable() - - tasksT.maxCellWidth = 55 - - tasksT #=( - "Task Name(@), Oldest/Latest & Rate", - "Duration", - "Executions" - ) - - println("Tasks executed on host " + host + ":") - - var sortedNames = execsMap.keys.toList.sorted - - if (sortedNames.size > SHOW_LIMIT) { - warnLimit(sortedNames.size, "task") - - sortedNames = sortedNames.slice(0, SHOW_LIMIT) - } - - sortedNames.foreach(taskName => { - val t = VisorTask(taskName, execsMap.get(taskName).get) - - val sE = t.execsFor(STARTED) - val fE = t.execsFor(FINISHED) - val eE = t.execsFor(FAILED) - val uE = t.execsFor(UNDEFINED) - val tE = t.execsFor(TIMEDOUT) - - val n = t.execs.size - - tasksT +=( - ( - t.taskNameVar, - " ", - "Oldest: " + formatDateTime(t.oldest), - "Latest: " + formatDateTime(t.latest), - " ", - "Exec. Rate: " + n + " in " + X.timeSpan2HMSM(t.timeframe) - ), - ( - "min: " + X.timeSpan2HMSM(t.minDuration), - "avg: " + X.timeSpan2HMSM(t.avgDuration), - "max: " + X.timeSpan2HMSM(t.maxDuration) - ), - ( - "Total: " + n, - " ", - "St: " + sE + " (" + formatInt(100 * sE / n) + "%)", - "Fi: " + fE + " (" + formatInt(100 * fE / n) + "%)", - "Fa: " + eE + " (" + formatInt(100 * eE / n) + "%)", - "Un: " + uE + " (" + formatInt(100 * uE / n) + "%)", - "Ti: " + tE + " (" + formatInt(100 * tE / n) + "%)" - ) - ) - }) - - tasksT.render() - - nl() - }) - - taskFootnote() - } - catch { - case e: IgniteCheckedException => - scold(e.getMessage) - - break() - } - } - } - - /** - * Warns about the limit reached. - * - * @param n Actual number of elements - */ - private def warnLimit(n: Int, name: String) { - nl() - - warn(n + name + "s found.", "Only first " + SHOW_LIMIT + " are shown.") - - nl() - } -} - -/** - * Companion object that does initialization of the command. - */ -object VisorTasksCommand { - addHelp( - name = "tasks", - shortInfo = "Prints tasks execution statistics.", - longInfo = List( - "Prints statistics about tasks and executions.", - " ", - "Note that this command depends on GridGain events.", - " ", - "GridGain events can be individually enabled and disabled and disabled events", - "can affect the results produced by this command. Note also that configuration", - "of Event Storage SPI that is responsible for temporary storage of generated", - "events on each node can also affect the functionality of this command.", - " ", - "By default - all events are enabled and GridGain stores last 10,000 local", - "events on each node. Both of these defaults can be changed in configuration." - ), - spec = List( - "tasks", - "tasks -l {-t=<num>s|m|h|d} {-r} {-a}", - "tasks -s=<substring> {-t=<num>s|m|h|d} {-r}", - "tasks -g {-t=<num>s|m|h|d} {-r}", - "tasks -h {-t=<num>s|m|h|d} {-r}", - "tasks -n=<task-name> {-r} {-a}", - "tasks -e=<exec-id>" - ), - args = List( - "-l" -> List( - "List all tasks and executions for a given time period.", - "Executions sorted chronologically (see '-r'), and tasks alphabetically", - "See '-t=<num>s|m|h|d' on how to specify the time limit.", - "Default time period is one hour, i.e '-t=1h'", - " ", - "Execution list will be shown only if '-a' flag is provided.", - " ", - "This is a default mode when command is called without parameters." - ), - "-s=<substring>" -> List( - "List all tasks and executions for a given task name substring.", - "Executions sorted chronologically (see '-r'), and tasks alphabetically", - "See '-t=<num>s|m|h|d' on how to specify the time limit.", - "Default time period is one hour, i.e '-t=1h'", - " ", - "Execution list will be shown only if '-a' flag is provided." - ), - "-g" -> List( - "List all tasks grouped by nodes for a given time period.", - "Tasks sorted alphabetically", - "See '-t=<num>s|m|h|d' on how to specify the time limit.", - "Default time period is one hour, i.e '-t=1h'" - ), - "-h" -> List( - "List all tasks grouped by hosts for a given time period.", - "Tasks sorted alphabetically", - "See '-t=<num>s|m|h|d' on how to specify the time limit.", - "Default time period is one hour, i.e '-t=1h'" - ), - "-t=<num>s|m|h|d" -> List( - "Defines time frame for '-l' parameter:", - " =<num>s Last <num> seconds.", - " =<num>m Last <num> minutes.", - " =<num>h Last <num> hours.", - " =<num>d Last <num> days." - ), - "-r" -> List( - "Reverse sorting of executions." - ), - "-n=<task-name>" -> List( - "Prints aggregated statistic for named task.", - " ", - "Execution list will be shown only if '-a' flag is provided." - ), - "-e=<exec-id>" -> - "Prints aggregated statistic for given task execution.", - "-a" -> List( - "Defines whether to show list of executions.", - "Can be used with '-l', '-s' or '-n'." - ) - ), - examples = List( - "tasks" -> - "Prints list of all tasks for the last hour (default).", - "tasks -l" -> - "Prints list of all tasks for the last hour (default).", - "tasks -l -a" -> - "Prints list of all tasks and executions for the last hour (default).", - "tasks -l -t=5m" -> - "Prints list of tasks that started during last 5 minutes.", - "tasks -s=Task" -> - "Prints list of all tasks that have 'Task' in task name.", - "tasks -g" -> - "Prints list of tasks grouped by nodes.", - "tasks -g -t=5m" -> - "Prints list of tasks that started during last 5 minutes grouped by nodes.", - "tasks -h" -> - "Prints list of tasks grouped by hosts.", - "tasks -h -t=5m" -> - "Prints list of tasks that started during last 5 minutes grouped by hosts.", - "tasks -n=GridTask" -> - "Prints summary for task named 'GridTask'.", - "tasks -n=GridTask -a" -> - "Prints summary and executions for task named 'GridTask'.", - "tasks -e=7D5CB773-225C-4165-8162-3BB67337894B" -> - "Traces task execution with ID '7D5CB773-225C-4165-8162-3BB67337894B'." - ), - ref = VisorConsoleCommand(cmd.tasks, cmd.tasks) - ) - - /** Singleton command. */ - private val cmd = new VisorTasksCommand - - /** - * Singleton. - */ - def apply() = cmd - - /** - * Implicit converter from visor to commands "pimp". - * - * @param vs Visor tagging trait. - */ - implicit def fromTrace2Visor(vs: VisorTag) = cmd -}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e1c3c8ce/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/Packet.scala ---------------------------------------------------------------------- diff --git a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/Packet.scala b/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/Packet.scala deleted file mode 100644 index 31346be..0000000 --- a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/Packet.scala +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.gridgain.visor.commands - -/** - * ==Overview== - * Contains Visor command `top` implementation. - * - * ==Help== - * {{{ - * +--------------------------------+ - * | top | Prints current topology. | - * +--------------------------------+ - * }}} - * - * ====Specification==== - * {{{ - * top "{-c1=e1<num> -c2=e2<num> ... -ck=ek<num>} {-h=<host1> ... -h=<hostk>} {-a}" - * }}} - * - * ====Arguments==== - * {{{ - * -ck=ek<num> - * This defines a mnemonic for node filter: - * -cc Number of available CPUs on the node. - * -cl Average CPU load (in %) on the node. - * -aj Active jobs on the node. - * -cj Cancelled jobs on the node. - * -tc Thread count on the node. - * -it Idle time on the node. - * Note: <num> can have 's', 'm', or 'h' suffix indicating - * seconds, minutes, and hours. By default (no suffix provided) - * value is assumed to be in milliseconds. - * -ut Up time on the node. - * Note: <num> can have 's', 'm', or 'h' suffix indicating - * seconds, minutes, and hours. By default (no suffix provided) - * value is assumed to be in milliseconds. - * -je Job execute time on the node. - * -jw Job wait time on the node. - * -wj Waiting jobs count on the node. - * -rj Rejected jobs count on the node. - * -hu Heap memory used (in MB) on the node. - * -hm Heap memory maximum (in MB) on the node. - * - * Comparison part of the mnemonic predicate: - * =eq<num> Equal '=' to '<num>' number. - * =neq<num> Not equal '!=' to '<num>' number. - * =gt<num> Greater than '>' to '<num>' number. - * =gte<num> Greater than or equal '>=' to '<num>' number. - * =lt<num> Less than '<' to '<num>' number. - * =lte<num> Less than or equal '<=' to '<num>' number. - * -h=<host> - * This defines a host to show nodes from. - * Multiple hosts can be provided. - * -a - * This defines whether to show a separate table of nodes - * with detail per-node information. - * }}} - * - * ====Examples==== - * {{{ - * top "-cc=eq2" - * Prints topology for all nodes with two CPUs. - * top "-cc=eq2 -a" - * Prints full information for all nodes with two CPUs. - * top "-h=10.34.2.122 -h=10.65.3.11" - * Prints topology for provided hosts. - * top - * Prints full topology. - * }}} - */ -package object top http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e1c3c8ce/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/VisorTopologyCommand.scala ---------------------------------------------------------------------- diff --git a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/VisorTopologyCommand.scala b/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/VisorTopologyCommand.scala deleted file mode 100644 index e7bf0fe..0000000 --- a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/top/VisorTopologyCommand.scala +++ /dev/null @@ -1,432 +0,0 @@ -/* - * 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.gridgain.visor.commands.top - -import org.apache.ignite.internal.GridNodeAttributes -import org.apache.ignite.internal.util.GridUtils -import org.apache.ignite.internal.util.typedef.internal.U -import GridNodeAttributes._ -import org.apache.ignite.internal.util.typedef._ - -import org.apache.ignite._ -import org.apache.ignite.cluster.ClusterNode -import org.apache.ignite.lang.IgnitePredicate - -import java.net.{InetAddress, UnknownHostException} - -import org.gridgain.visor._ -import org.gridgain.visor.commands.{VisorConsoleCommand, VisorTextTable} -import org.gridgain.visor.visor._ - -import scala.collection.JavaConversions._ -import scala.language.{implicitConversions, reflectiveCalls} -import scala.util.control.Breaks._ - -/** - * ==Overview== - * Contains Visor command `top` implementation. - * - * ==Help== - * {{{ - * +--------------------------------+ - * | top | Prints current topology. | - * +--------------------------------+ - * }}} - * - * ====Specification==== - * {{{ - * top "{-c1=e1<num> -c2=e2<num> ... -ck=ek<num>} {-h=<host1> ... -h=<hostk>} {-a}" - * }}} - * - * ====Arguments==== - * {{{ - * -ck=ek<num> - * This defines a mnemonic for node filter: - * -cc Number of available CPUs on the node. - * -cl Average CPU load (in %) on the node. - * -aj Active jobs on the node. - * -cj Cancelled jobs on the node. - * -tc Thread count on the node. - * -it Idle time on the node. - * Note: <num> can have 's', 'm', or 'h' suffix indicating - * seconds, minutes, and hours. By default (no suffix provided) - * value is assumed to be in milliseconds. - * -ut Up time on the node. - * Note: <num> can have 's', 'm', or 'h' suffix indicating - * seconds, minutes, and hours. By default (no suffix provided) - * value is assumed to be in milliseconds. - * -je Job execute time on the node. - * -jw Job wait time on the node. - * -wj Waiting jobs count on the node. - * -rj Rejected jobs count on the node. - * -hu Heap memory used (in MB) on the node. - * -hm Heap memory maximum (in MB) on the node. - * - * Comparison part of the mnemonic predicate: - * =eq<num> Equal '=' to '<num>' number. - * =neq<num> Not equal '!=' to '<num>' number. - * =gt<num> Greater than '>' to '<num>' number. - * =gte<num> Greater than or equal '>=' to '<num>' number. - * =lt<num> Less than '<' to '<num>' number. - * =lte<num> Less than or equal '<=' to '<num>' number. - * -h=<host> - * This defines a host to show nodes from. - * Multiple hosts can be provided. - * -a - * This defines whether to show a separate table of nodes - * with detail per-node information. - * }}} - * - * ====Examples==== - * {{{ - * top "-cc=eq2" - * Prints topology for all nodes with two CPUs. - * top "-cc=eq2 -a" - * Prints full information for all nodes with two CPUs. - * top "-h=10.34.2.122 -h=10.65.3.11" - * Prints topology for provided hosts. - * top - * Prints full topology. - * }}} - */ -class VisorTopologyCommand { - /** - * Prints error message and advise. - * - * @param errMsgs Error messages. - */ - private def scold(errMsgs: Any*) { - assert(errMsgs != null) - - warn(errMsgs: _*) - warn("Type 'help top' to see how to use this command.") - } - - /** - * ===Command=== - * Prints full topology. - * - * ===Examples=== - * <ex>top</ex> - * Prints full topology. - */ - def top() { - top("") - } - - /** - * ===Command=== - * Prints topology for provided mnemonic predicate. - * - * ===Examples=== - * <ex>top "-cc=eq2"</ex> - * Prints topology for all nodes with two CPUs. - * - * <ex>top "-cc=eq2 -a"</ex> - * Prints full information for all nodes with two CPUs. - * - * <ex>top "-h=10.34.2.122 -h=10.65.3.11"</ex> - * Prints topology for provided hosts. - * - * @param args Command arguments. - */ - def top(args: String) = breakable { - assert(args != null) - - if (!isConnected) - adviseToConnect() - else { - val argLst = parseArgs(args) - - val hosts = argLst.filter(_._1 == "h").map((a: Arg) => - try - InetAddress.getByName(a._2).getHostAddress - catch { - case e: UnknownHostException => scold("Unknown host: " + a._2).^^ - - "" // Never happens. - } - ).filter(!_.isEmpty).toSet - - val all = hasArgFlag("a", argLst) - - var f: NodeFilter = (GridNode) => true - - try { - argLst foreach (arg => { - val (n, v) = arg - - n match { - case "cc" if v != null => f = make(v, f, _.metrics.getTotalCpus) - case "cl" if v != null => f = make(v, f, (n: ClusterNode) => - (n.metrics.getCurrentCpuLoad * 100).toLong) - case "aj" if v != null => f = make(v, f, _.metrics.getCurrentActiveJobs) - case "cj" if v != null => f = make(v, f, _.metrics.getCurrentCancelledJobs) - case "tc" if v != null => f = make(v, f, _.metrics.getCurrentThreadCount) - case "ut" if v != null => f = make(v, f, _.metrics.getUpTime) - case "je" if v != null => f = make(v, f, _.metrics.getCurrentJobExecuteTime) - case "jw" if v != null => f = make(v, f, _.metrics.getCurrentJobWaitTime) - case "wj" if v != null => f = make(v, f, _.metrics.getCurrentWaitingJobs) - case "rj" if v != null => f = make(v, f, _.metrics.getCurrentRejectedJobs) - case "hu" if v != null => f = make(v, f, _.metrics.getHeapMemoryUsed) - case "hm" if v != null => f = make(v, f, _.metrics.getHeapMemoryMaximum) - case _ => () - } - }) - - show(n => f(n), hosts, all) - } - catch { - case e: NumberFormatException => scold(e.getMessage) - case e: IgniteCheckedException => scold(e.getMessage) - } - } - } - - /** - * @param exprStr Expression string. - * @param f Node filter - * @param v Value generator. - */ - private def make(exprStr: String, f: NodeFilter, v: ClusterNode => Long): NodeFilter = { - assert(exprStr != null) - assert(f != null) - assert(v != null) - - val expr = makeExpression(exprStr) - - // Note that if 'f(n)' is false - 'value' won't be evaluated. - if (expr.isDefined) - (n: ClusterNode) => f(n) && expr.get.apply(v(n)) - else - throw new IgniteCheckedException("Invalid expression: " + exprStr) - } - - /** - * Prints topology. - * - * @param f Node filtering predicate. - * @param hosts Set of hosts to take nodes from. - * @param all Whether to show full information. - */ - private def show(f: NodeFilter, hosts: Set[String], all: Boolean) = breakable { - assert(f != null) - assert(hosts != null) - - var nodes = grid.forPredicate(new IgnitePredicate[ClusterNode] { - override def apply(e: ClusterNode) = f(e) - }).nodes() - - if (hosts.nonEmpty) - nodes = nodes.filter(n => { - val ips = n.addresses.toSet - - ips.intersect(hosts).nonEmpty - }) - - if (nodes.isEmpty) - println("Empty topology.").^^ - - if (all) { - val nodesT = VisorTextTable() - - nodesT #= ("Node ID8(@), IP", "Start Time", "Up Time", - //"Idle Time", - "CPUs", "CPU Load", "Free Heap") - - nodes foreach ((n: ClusterNode) => { - val m = n.metrics - - val usdMem = m.getHeapMemoryUsed - val maxMem = m.getHeapMemoryMaximum - - val freeHeapPct = (maxMem - usdMem) * 100 / maxMem - val cpuLoadPct = m.getCurrentCpuLoad * 100 - - // Add row. - nodesT += ( - nodeId8Addr(n.id), - formatDateTime(m.getStartTime), - X.timeSpan2HMS(m.getUpTime), - n.metrics.getTotalCpus, - safePercent(cpuLoadPct), - formatDouble(freeHeapPct) + " %" - ) - }) - - println("Nodes: " + nodes.size) - - nodesT.render() - - nl() - } - - val neighborhood = GridUtils.neighborhood(nodes) - - val hostsT = VisorTextTable() - - hostsT #= ("Int./Ext. IPs", "Node ID8(@)", "OS", "CPUs", "MACs", "CPU Load") - - neighborhood.foreach { - case (_, neighbors) => - var ips = Set.empty[String] - var id8s = List.empty[String] - var macs = Set.empty[String] - var cpuLoadSum = 0.0 - - val n1 = neighbors.head - - assert(n1 != null) - - val cpus = n1.metrics.getTotalCpus - val os = "" + - n1.attribute("os.name") + " " + - n1.attribute("os.arch") + " " + - n1.attribute("os.version") - - var i = 1 - - neighbors.foreach(n => { - id8s = id8s :+ (i.toString + ": " + nodeId8(n.id)) - - i += 1 - - ips = ips ++ n.addresses() - - cpuLoadSum += n.metrics().getCurrentCpuLoad - - macs = macs ++ n.attribute[String](ATTR_MACS).split(", ").map(_.grouped(2).mkString(":")) - }) - - // Add row. - hostsT += ( - ips.toSeq, - id8s, - os, - cpus, - macs.toSeq, - safePercent(cpuLoadSum / neighbors.size() * 100) - ) - } - - println("Hosts: " + neighborhood.size) - - hostsT.render() - - nl() - - val m = grid.forNodes(nodes).metrics() - - val freeHeap = (m.getAverageHeapMemoryMaximum - m.getAverageHeapMemoryUsed) * 100 / - m.getAverageHeapMemoryMaximum - - val sumT = VisorTextTable() - - sumT += ("Total hosts", m.getTotalHosts) - sumT += ("Total nodes", m.getTotalNodes) - sumT += ("Total CPUs", m.getTotalCpus) - sumT += ("Avg. CPU load", safePercent(m.getAverageCpuLoad * 100)) - sumT += ("Avg. free heap", formatDouble(freeHeap) + " %") - sumT += ("Avg. Up time", X.timeSpan2HMS(m.getAverageUpTime.toLong)) - sumT += ("Snapshot time", formatDateTime(System.currentTimeMillis)) - - println("Summary:") - - sumT.render() - } -} - -/** - * Companion object that does initialization of the command. - */ -object VisorTopologyCommand { - // Adds command's help to visor. - addHelp( - name = "top", - shortInfo = "Prints current topology.", - spec = List( - "top {-c1=e1<num> -c2=e2<num> ... -ck=ek<num>} {-h=<host1> ... -h=<hostk>} {-a}" - ), - args = List( - "-ck=ek<num>" -> List( - "This defines a mnemonic for node filter:", - " -cc Number of available CPUs on the node.", - " -cl Average CPU load (in %) on the node.", - " -aj Active jobs on the node.", - " -cj Cancelled jobs on the node.", - " -tc Thread count on the node.", -// " -it Idle time on the node.", -// " Note: <num> can have 's', 'm', or 'h' suffix indicating", -// " seconds, minutes, and hours. By default (no suffix provided)", -// " value is assumed to be in milliseconds.", - " -ut Up time on the node.", - " Note: <num> can have 's', 'm', or 'h' suffix indicating", - " seconds, minutes, and hours. By default (no suffix provided)", - " value is assumed to be in milliseconds.", - " -je Job execute time on the node.", - " -jw Job wait time on the node.", - " -wj Waiting jobs count on the node.", - " -rj Rejected jobs count on the node.", - " -hu Heap memory used (in MB) on the node.", - " -hm Heap memory maximum (in MB) on the node.", - "", - "Comparison part of the mnemonic predicate:", - " =eq<num> Equal '=' to '<num>' number.", - " =neq<num> Not equal '!=' to '<num>' number.", - " =gt<num> Greater than '>' to '<num>' number.", - " =gte<num> Greater than or equal '>=' to '<num>' number.", - " =lt<num> Less than '<' to '<num>' number.", - " =lte<num> Less than or equal '<=' to '<num>' number." - ), - "-h=<host>" -> List( - "This defines a host to show nodes from.", - "Multiple hosts can be provided." - ), - "-a" -> List( - "This defines whether to show a separate table of nodes", - "with detail per-node information." - ) - ), - examples = List( - "top -cc=eq2" -> - "Prints topology for all nodes with two CPUs.", - "top -cc=eq2 -a" -> - "Prints full information for all nodes with two CPUs.", - "top -h=10.34.2.122 -h=10.65.3.11" -> - "Prints topology for provided hosts.", - "top" -> - "Prints full topology." - ), - ref = VisorConsoleCommand(cmd.top, cmd.top) - ) - - /** Singleton command. */ - private val cmd = new VisorTopologyCommand - - /** - * Singleton. - */ - def apply() = cmd - - /** - * Implicit converter from visor to commands "pimp". - * - * @param vs Visor tagging trait. - */ - implicit def fromTop2Visor(vs: VisorTag) = cmd -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e1c3c8ce/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/Packet.scala ---------------------------------------------------------------------- diff --git a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/Packet.scala b/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/Packet.scala deleted file mode 100644 index fef2724..0000000 --- a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/Packet.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.gridgain.visor.commands - -/** - * ==Overview== - * Contains Visor command `vvm` implementation. - * - * ==Help== - * {{{ - * +-----------------------+ - * | vvm | Opens VisualVM. | - * +-----------------------+ - * }}} - * - * ====Specification==== - * {{{ - * vvm "{-home=dir} {-id8=<node-id8>} {-id=<node-id>}" - * }}} - * - * ====Arguments==== - * {{{ - * -home=dir - * VisualVM home directory. - * If not specified, PATH and JAVA_HOME will be searched - * -id8=<node-id8> - * ID8 of node. - * Either '-id8' or '-id' can be specified. - * -id=<node-id> - * Full ID of node. - * Either '-id8' or '-id' can be specified. - * }}} - * - * ====Examples==== - * {{{ - * vvm "-id8=12345678" - * Opens VisualVM connected to JVM for node with '12345678' ID8. - * vvm "-id=5B923966-85ED-4C90-A14C-96068470E94D" - * Opens VisualVM connected to JVM for node with given full node ID. - * vvm "-home=C:\VisualVM -id8=12345678" - * Opens VisualVM installed in 'C:\VisualVM' directory for specified node. - * vvm - * Opens VisualVM connected to all nodes. - * }}} - */ -package object vvm http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e1c3c8ce/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/VisorVvmCommand.scala ---------------------------------------------------------------------- diff --git a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/VisorVvmCommand.scala b/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/VisorVvmCommand.scala deleted file mode 100644 index 0345b84..0000000 --- a/modules/visor-console/src/main/scala/org/gridgain/visor/commands/vvm/VisorVvmCommand.scala +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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.gridgain.visor.commands.vvm - -import org.apache.ignite.internal.GridNodeAttributes -import org.apache.ignite.internal.util.GridUtils -import org.apache.ignite.internal.util.typedef.internal.U -import GridNodeAttributes._ -import org.apache.ignite.internal.visor.util.{VisorTaskUtils => TU} - -import org.apache.ignite.IgniteSystemProperties -import org.apache.ignite.cluster.ClusterNode -import org.jetbrains.annotations.Nullable - -import java.io.File -import java.net._ - -import org.gridgain.visor._ -import org.gridgain.visor.commands.VisorConsoleCommand -import org.gridgain.visor.visor._ - -import scala.collection.JavaConversions._ -import scala.language.{implicitConversions, reflectiveCalls} -import scala.util.control.Breaks._ - -/** - * ==Overview== - * Contains Visor command `vvm` implementation. - * - * ==Help== - * {{{ - * +-----------------------+ - * | vvm | Opens VisualVM. | - * +-----------------------+ - * }}} - * - * ====Specification==== - * {{{ - * vvm "{-home=dir} {-id8=<node-id8>} {-id=<node-id>}" - * }}} - * - * ====Arguments==== - * {{{ - * -home=dir - * VisualVM home directory. - * If not specified, PATH and JAVA_HOME will be searched. - * -id8=<node-id8> - * ID8 of node. - * Either '-id8' or '-id' can be specified. - * -id=<node-id> - * Full ID of node. - * Either '-id8' or '-id' can be specified. - * }}} - * - * ====Examples==== - * {{{ - * vvm "-id8=12345678" - * Opens VisualVM connected to JVM for node with '12345678' ID8. - * vvm "-id=5B923966-85ED-4C90-A14C-96068470E94D" - * Opens VisualVM connected to JVM for node with given full node ID. - * vvm "-home=C:\VisualVM -id8=12345678" - * Opens VisualVM installed in 'C:\VisualVM' directory for specified node. - * vvm - * Opens VisualVM connected to all nodes. - * }}} - */ -class VisorVvmCommand { - /** - * Prints error message and advise. - * - * @param errMsgs Error messages. - */ - private def scold(errMsgs: Any*) { - assert(errMsgs != null) - - warn(errMsgs: _*) - warn("Type 'help vvm' to see how to use this command.") - } - - /** - * ===Command=== - * Opens VisualVM connected to JVM indicated by the node id. - * - * ===Examples=== - * <ex>vvm "-id8=12345678"</ex> - * Opens VisualVM connected to JVM for node with '12345678' ID8. - * - * <ex>vvm "-id=5B923966-85ED-4C90-A14C-96068470E94D"</ex> - * Opens VisualVM connected to JVM for node with given full node ID. - * - * <ex>vvm "-home=C:\VisualVM -id8=12345678"</ex> - * Opens VisualVM installed in 'C:\Visual\VM' directory for specified node. - * - * @param args Command parameters. - */ - def vvm(@Nullable args: String) = breakable { - if (!isConnected) - adviseToConnect() - else { - val argLst = parseArgs(args) - - val vvmHome = argValue("home", argLst) getOrElse IgniteSystemProperties.getString("VVM_HOME") - val id8 = argValue("id8", argLst).orNull - val id = argValue("id", argLst).orNull - - var vvmCmd: String = null - - val ext = if (GridUtils.isWindows) ".exe" else "" - - val fs = File.separator - - if (vvmHome != null && !vvmHome.isEmpty) { - vvmCmd = vvmHome + fs + "bin" + fs + "visualvm" + ext - - if (!new File(vvmCmd).exists) - vvmCmd = vvmHome + fs + "bin" + fs + "jvisualvm" + ext - } - - if (vvmCmd == null || vvmCmd.isEmpty) { - breakable { - for (p <- System.getenv("PATH").split(System.getProperty("path.separator"))) { - val f1 = p + fs + "visualvm" + ext - val f2 = p + fs + "jvisualvm" + ext - - if (new File(f1).exists) { - vvmCmd = f1 - - break() - } - else if (new File(f2).exists) { - vvmCmd = f2 - - break() - } - } - } - } - - if (vvmCmd == null || vvmCmd.isEmpty) - vvmCmd = IgniteSystemProperties.getString("JAVA_HOME") + fs + "bin" + fs + "jvisualvm" + ext - - if (!new File(vvmCmd).exists) - warn( - "Can't find Visual VM", - "Specify '-home' parameter or VVM_HOME environment property to provide " + - "Visual VM installation folder." - ).^^ - - var nodes: scala.collection.Seq[ClusterNode] = null - - if (id8 != null && id != null) - scold("Only one of '-id8' or '-id' is allowed.").^^ - else if (id8 == null && id == null) - nodes = grid.forRemotes().nodes().toSeq - else - if (id8 != null) { - val ns = nodeById8(id8) - - if (ns.isEmpty) - scold("Unknown 'id8' value: " + id8).^^ - else if (ns.size != 1) - scold("'id8' resolves to more than one node (use full 'id' instead): " + id8).^^ - else - nodes = Seq(ns.head) - } - else if (id != null) - try { - val node = grid.node(java.util.UUID.fromString(id)) - - if (node == null) - scold("'id' does not match any node: " + id).^^ - - nodes = Seq(node) - } - catch { - case e: IllegalArgumentException => scold("Invalid node 'id': " + id).^^ - } - - var started = false - - val neighbors = grid.forHost(grid.localNode).nodes() - - if (GridUtils.isWindows) - vvmCmd = "cmd /c \"%s\"".format(vvmCmd) - - for (node <- nodes if !neighbors.contains(node)) { - val port = node.attribute[java.lang.Integer](ATTR_JMX_PORT) - - if (port == null) - warn("JMX is not enabled for node (skipping): " + nid8(node)) - else { - val addrs = node.addresses.filter(addr => { - try - !InetAddress.getByName(addr).isLoopbackAddress - catch { - case _: Throwable => false - } - }) - - addrs.find(a => TU.reachableByPing(InetAddress.getByName(a), 2000)) match { - case Some(addr) => - // Sequential calls to VisualVM will not start separate processes - // but will add new JMX connection to it. - TU.openInConsole(vvmCmd + " --openjmx " + addr + ":" + port) - - started = true - case None => - scold("Visor failed to get reachable address for node (skipping): " + nid8(node)) - } - } - } - - if (!started) - TU.openInConsole(vvmCmd) - } - } - - /** - * Returns VisualVM command array specific for a particular platform. - * - * @param vvmCmd VisualVM command. - */ - private def vvmCommandArray(vvmCmd: String): Array[String] = { - if (GridUtils.isWindows) Array("cmd", "/c", vvmCmd) else Array(vvmCmd) - } - - /** - * ===Command=== - * Opens VisualVM connected to all nodes. - * - * ==Examples== - * <ex>vvm</ex> - * Opens VisualVM with all nodes. - */ - def vvm() { - vvm(null) - } -} - -/** - * Companion object that does initialization of the command. - */ -object VisorVvmCommand { - // Adds command's help to visor. - addHelp( - name = "vvm", - shortInfo = "Opens VisualVM for nodes in topology.", - spec = List("vvm {-home=dir} {-id8=<node-id8>} {-id=<node-id>}"), - args = List( - "-home=dir" -> List( - "VisualVM home folder.", - "If not specified, PATH and JAVA_HOME will be searched" - ), - "-id8=<node-id8>" -> List( - "ID8 of node.", - "Note that either '-id8' or '-id' can be specified and " + - "you can also use '@n0' ... '@nn' variables as shortcut to <node-id8>." - ), - "-id=<node-id>" -> List( - "Full ID of node.", - "Either '-id8' or '-id' can be specified." - ) - ), - examples = List( - "vvm -id8=12345678" -> - "Opens VisualVM connected to JVM for node with '12345678' ID8.", - "vvm -id8=@n0" -> - "Opens VisualVM connected to JVM for node with given node ID8 taken from 'n0' memory variable.", - "vvm -id=5B923966-85ED-4C90-A14C-96068470E94D" -> - "Opens VisualVM connected to JVM for node with given full node ID.", - "vvm -home=C:\\VisualVM -id8=12345678" -> - "Opens VisualVM installed in 'C:\\VisualVM' folder for specified node.", - "vvm" -> - "Opens VisualVM connected to all nodes." - ), - ref = VisorConsoleCommand(cmd.vvm, cmd.vvm) - ) - - /** Singleton command. */ - private val cmd = new VisorVvmCommand - - /** - * Singleton. - */ - def apply() = cmd - - /** - * Implicit converter from visor to commands "pimp". - * - * @param vs Visor tagging trait. - */ - implicit def fromVvm2Visor(vs: VisorTag) = cmd -}