From 405eb969c14fc498aa8f46a56e70c6e39512532d Mon Sep 17 00:00:00 2001 From: Atri Sharma Date: Fri, 6 Mar 2020 15:31:39 +0530 Subject: [PATCH] ARTEMIS-2636: Introduce Disk Usage Metrics ARTEMIS-2636: This commit introduces metrics to publish the amount of disk used currently --- .../activemq/artemis/logs/AuditLogger.java | 16 +++++++ .../management/ActiveMQServerControl.java | 15 ++++++- .../impl/ActiveMQServerControlImpl.java | 45 +++++++++++++++++++ .../core/server/impl/ActiveMQServerImpl.java | 1 + .../server/metrics/BrokerMetricNames.java | 2 +- .../ActiveMQServerControlUsingCoreTest.java | 20 +++++++++ 6 files changed, 97 insertions(+), 2 deletions(-) diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java index 70abebd562..b934c9e8dd 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java @@ -2284,4 +2284,20 @@ public interface AuditLogger extends BasicLogger { @LogMessage(level = Logger.Level.INFO) @Message(id = 601503, value = "User {0} is getting retroactiveResource property on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) void isRetroactiveResource(String user, Object source, Object... args); + + static void getDiskStoreUsage(Object source) { + LOGGER.getDiskStoreUsage(getCaller(), source); + } + + @LogMessage(level = Logger.Level.INFO) + @Message(id = 601504, value = "User {0} is getting disk store usage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) + void getDiskStoreUsage(String user, Object source, Object... args); + + static void getDiskStoreUsagePercentage(Object source) { + LOGGER.getDiskStoreUsagePercentage(getCaller(), source); + } + + @LogMessage(level = Logger.Level.INFO) + @Message(id = 601505, value = "User {0} is getting disk store usage percentage on target resource: {1} {2}", format = Message.Format.MESSAGE_FORMAT) + void getDiskStoreUsagePercentage(String user, Object source, Object... args); } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java index 63ee0330e7..29ed3d7e5b 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java @@ -27,7 +27,8 @@ import org.apache.activemq.artemis.api.core.ActiveMQAddressDoesNotExistException public interface ActiveMQServerControl { String CONNECTION_COUNT_DESCRIPTION = "Number of clients connected to this server"; String TOTAL_CONNECTION_COUNT_DESCRIPTION = "Number of clients which have connected to this server since it was started"; - String ADDRESS_MEMORY_USAGE_DESCRIPTION = "Memory used by all the addresses on broker for in-memory messages"; + String ADDRESS_MEMORY_USAGE_DESCRIPTION = "Bytes used by all the addresses on broker for in-memory messages"; + String DISK_STORE_USAGE_DESCRIPTION = "Memory used by the disk store"; /** * Returns this server's version. @@ -442,12 +443,24 @@ public interface ActiveMQServerControl { @Attribute(desc = ADDRESS_MEMORY_USAGE_DESCRIPTION) long getAddressMemoryUsage(); + /** + * Returns the bytes used by the disk store + */ + @Attribute(desc = DISK_STORE_USAGE_DESCRIPTION) + long getDiskStoreUsage(); + /** * Returns the memory used by all the addresses on broker as a percentage of global maximum limit */ @Attribute(desc = "Memory used by all the addresses on broker as a percentage of global maximum limit") int getAddressMemoryUsagePercentage(); + /** + * Returns the storage used by disk store + */ + @Attribute(desc = "Memory used by the disk store") + int getDiskStoreUsagePercentage(); + // Operations ---------------------------------------------------- @Operation(desc = "Isolate the broker", impact = MBeanOperationInfo.ACTION) boolean freezeReplication(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java index a63f523e48..4431d706b9 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java @@ -107,6 +107,7 @@ import org.apache.activemq.artemis.core.server.cluster.ha.HAPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.LiveOnlyPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.ScaleDownPolicy; import org.apache.activemq.artemis.core.server.cluster.ha.SharedStoreSlavePolicy; +import org.apache.activemq.artemis.core.server.files.FileStoreMonitor; import org.apache.activemq.artemis.core.server.group.GroupingHandler; import org.apache.activemq.artemis.core.server.impl.Activation; import org.apache.activemq.artemis.core.server.impl.AddressInfo; @@ -131,6 +132,8 @@ import org.apache.activemq.artemis.utils.SecurityFormatter; import org.apache.activemq.artemis.utils.collections.TypedProperties; import org.jboss.logging.Logger; +import static org.apache.activemq.artemis.core.server.files.FileStoreMonitor.calculateUsage; + public class ActiveMQServerControlImpl extends AbstractControl implements ActiveMQServerControl, NotificationEmitter, org.apache.activemq.artemis.core.server.management.NotificationListener { // Constants ----------------------------------------------------- private static final Logger logger = Logger.getLogger(ActiveMQServerControlImpl.class); @@ -707,6 +710,28 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active } } + @Override + public long getDiskStoreUsage() { + if (AuditLogger.isEnabled()) { + AuditLogger.getDiskStoreUsage(this.server); + } + checkStarted(); + clearIO(); + try { + //this should not happen but if it does, return -1 to highlight it is not working + if (server.getPagingManager() == null) { + return -1L; + } + + long usableSpace = server.getPagingManager().getDiskUsableSpace(); + long totalSpace = server.getPagingManager().getDiskTotalSpace(); + + return (long) FileStoreMonitor.calculateUsage(usableSpace, totalSpace); + } finally { + blockOnIO(); + } + } + @Override public int getAddressMemoryUsagePercentage() { if (AuditLogger.isEnabled()) { @@ -726,6 +751,26 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active return (int) result; } + @Override + public int getDiskStoreUsagePercentage() { + if (AuditLogger.isEnabled()) { + AuditLogger.getDiskStoreUsagePercentage(this.server); + } + long globalMaxSize = getGlobalMaxSize(); + // no max size set implies 0% used + if (globalMaxSize <= 0) { + return 0; + } + + long diskUsed = getDiskStoreUsage(); + if (diskUsed <= 0) { + return 0; + } + + double result = 100 * calculateUsage(diskUsed, globalMaxSize); + return (int) result; + } + @Override public boolean freezeReplication() { if (AuditLogger.isEnabled()) { diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index f7a6fc928f..a46ad559eb 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -2996,6 +2996,7 @@ public class ActiveMQServerImpl implements ActiveMQServer { builder.register(BrokerMetricNames.CONNECTION_COUNT, this, metrics -> Double.valueOf(getConnectionCount()), ActiveMQServerControl.CONNECTION_COUNT_DESCRIPTION); builder.register(BrokerMetricNames.TOTAL_CONNECTION_COUNT, this, metrics -> Double.valueOf(getTotalConnectionCount()), ActiveMQServerControl.TOTAL_CONNECTION_COUNT_DESCRIPTION); builder.register(BrokerMetricNames.ADDRESS_MEMORY_USAGE, this, metrics -> Double.valueOf(getPagingManager().getGlobalSize()), ActiveMQServerControl.ADDRESS_MEMORY_USAGE_DESCRIPTION); + builder.register(BrokerMetricNames.DISK_STORE_USAGE, this, metrics -> Double.valueOf(getPagingManager().getDiskTotalSpace() - getPagingManager().getDiskUsableSpace()), ActiveMQServerControl.DISK_STORE_USAGE_DESCRIPTION); }); } } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/BrokerMetricNames.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/BrokerMetricNames.java index f487eecc7c..47ef5cff48 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/BrokerMetricNames.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/BrokerMetricNames.java @@ -22,5 +22,5 @@ public class BrokerMetricNames { public static final String CONNECTION_COUNT = "connection.count"; public static final String TOTAL_CONNECTION_COUNT = "total.connection.count"; public static final String ADDRESS_MEMORY_USAGE = "address.memory.usage"; - + public static final String DISK_STORE_USAGE = "disk.store.usage"; } diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java index cc3dcb3598..0418a4e294 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java @@ -741,6 +741,26 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes return 0; } + @Override + public long getDiskStoreUsage() { + try { + return (Long) proxy.invokeOperation("getDiskStoreUsage"); + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + + @Override + public int getDiskStoreUsagePercentage() { + try { + return (Integer) proxy.invokeOperation(Integer.TYPE, "getDiskUseStorePercentage"); + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + @Override public boolean freezeReplication() {