Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id DD7AD200CEF for ; Mon, 4 Sep 2017 20:45:26 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id DBE5A165371; Mon, 4 Sep 2017 18:45:26 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0829A16536C for ; Mon, 4 Sep 2017 20:45:25 +0200 (CEST) Received: (qmail 23554 invoked by uid 500); 4 Sep 2017 18:45:24 -0000 Mailing-List: contact dev-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list dev@activemq.apache.org Received: (qmail 23543 invoked by uid 99); 4 Sep 2017 18:45:24 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 04 Sep 2017 18:45:24 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8E6F3F32A4; Mon, 4 Sep 2017 18:45:23 +0000 (UTC) From: michaelandrepearce To: dev@activemq.apache.org Reply-To: dev@activemq.apache.org References: In-Reply-To: Subject: [GitHub] activemq-artemis pull request #1506: ARTEMIS-1384 adding CLI command (qstat)... Content-Type: text/plain Message-Id: <20170904184523.8E6F3F32A4@git1-us-west.apache.org> Date: Mon, 4 Sep 2017 18:45:23 +0000 (UTC) archived-at: Mon, 04 Sep 2017 18:45:27 -0000 Github user michaelandrepearce commented on a diff in the pull request: https://github.com/apache/activemq-artemis/pull/1506#discussion_r136861961 --- Diff: artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/QueueStats.java --- @@ -0,0 +1,195 @@ +/* + * 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.activemq.artemis.cli.commands; + +import io.airlift.airline.Command; +import io.airlift.airline.Option; +import org.apache.activemq.artemis.api.core.JsonUtil; +import org.apache.activemq.artemis.api.core.client.ClientMessage; +import org.apache.activemq.artemis.api.core.management.ManagementHelper; + +import javax.json.JsonArray; +import javax.json.JsonObject; +import java.util.HashMap; + +@Command(name = "qstat", description = "prints out basic stats associated with queues. Output includes " + "CONSUMERS (number of consumers), " + "MESSAGES (current message count on the queue, including scheduled, paged and in-delivery messages), " + "ADDED (messages added to the queue), " + "DELIVERING (messages broker is currently delivering to consumer(s)), " + "ACKED (messages acknowledged from the consumer(s))." + +) +public class QueueStats extends AbstractAction { + + public static final String NAME_FIELD = "name"; + public static final String ADDRESS_FIELD = "address"; + public static final String CONSUMER_COUNT_FIELD = "consumerCount"; + public static final String MESSAGE_COUNT_FIELD = "messageCount"; + public static final String MESSAGES_ADDED_FIELD = "messagesAdded"; + public static final String DELIVERING_COUNT_FIELD = "deliveringCount"; + public static final String MESSAGES_ACKED_FIELD = "messagesAcked"; + + @Option(name = "--queueName", description = "display queue stats for queue(s) with names containing this string, " + "omitting this option will return stats for all queues (until maxRows are reached).") + private String queueName; + + @Option(name = "--exactMatch", description = "display queue stats for queue(s) with this exact name. " + "Default is false.") + private boolean exactMatch = false; + + @Option(name = "--maxRows", description = "max number of queues displayed. Default is 50") + private int maxRows = 50; + + //easier for testing + public void setQueueName(String queueName) { + this.queueName = queueName; + } + + public void setExactMatch(boolean exactMatch) { + this.exactMatch = exactMatch; + } + + public void setMaxRows(int maxRows) { + this.maxRows = maxRows; + } + + public void setUser(String user) { + this.user = user; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public Object execute(ActionContext context) throws Exception { + super.execute(context); + String filter = createFilter(queueName, exactMatch); + + if (verbose) { + context.out.println("queueName='" + queueName + "'"); + context.out.println("maxRows='" + maxRows + "'"); + context.out.println("exactMatch='" + exactMatch + "'"); + context.out.println("filter='" + filter + "'"); + } + + printStats(context, filter, maxRows); + return null; + } + + private void printStats(final ActionContext context, final String filter, int maxRows) throws Exception { + performCoreManagement(new ManagementCallback() { + @Override + public void setUpInvocation(ClientMessage message) throws Exception { + ManagementHelper.putOperationInvocation(message, "broker", "listQueues", filter, 1, maxRows); + } + + @Override + public void requestSuccessful(ClientMessage reply) throws Exception { + final String result = (String) ManagementHelper.getResult(reply, String.class); + printStats(result); + } + + @Override + public void requestFailed(ClientMessage reply) throws Exception { + String errMsg = (String) ManagementHelper.getResult(reply, String.class); + context.err.println("Failed to get Stats for Queues. Reason: " + errMsg); + } + }); + } + + private void printStats(String result) { + printHeadings(); + + //should not happen but... + if (result == null) { + if (verbose) { + context.out.println("printStats(): got NULL result string."); + } + } + + JsonObject queuesAsJsonObject = JsonUtil.readJsonObject(result); + JsonArray array = (JsonArray) queuesAsJsonObject.get("data"); + + for (int i = 0; i < array.size(); i++) { + printQueueStats(array.getJsonObject(i)); + } + } + + private void printHeadings() { + + StringBuilder stringBuilder = new StringBuilder(106).append('|').append(paddingString(new StringBuilder("QUEUE NAME "), 25)).append('|').append(paddingString(new StringBuilder("ADDRESS NAME "), 25)).append('|').append(paddingString(new StringBuilder("CONSUMERS "), 10)).append('|').append(paddingString(new StringBuilder("MESSAGES "), 9)).append('|').append(paddingString(new StringBuilder("ADDED "), 9)).append('|').append(paddingString(new StringBuilder("DELIVERING "), 11)).append('|').append(paddingString(new StringBuilder("ACKED "), 9)).append('|'); --- End diff -- Should headers not be the fieldNames? This then ties in with my comment about more generic filter support, to support ability to filter by any fieldName ---