You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by sh...@apache.org on 2020/06/02 09:15:37 UTC

[incubator-ratis] branch master updated: RATIS-935. Fix memory leak by ungister metrics (#97)

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

shashikant pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ratis.git


The following commit(s) were added to refs/heads/master by this push:
     new 20c86cd  RATIS-935. Fix memory leak by ungister metrics (#97)
20c86cd is described below

commit 20c86cd00b718a9bb4686bcff11bf44ee3e10112
Author: runzhiwang <51...@users.noreply.github.com>
AuthorDate: Tue Jun 2 17:15:29 2020 +0800

    RATIS-935. Fix memory leak by ungister metrics (#97)
---
 .../ratis/grpc/metrics/GrpcServerMetrics.java      | 18 +++---
 .../apache/ratis/grpc/server/GrpcLogAppender.java  |  1 +
 .../metrics/LogServiceMetaDataMetrics.java         | 47 ++++++++++++++++
 .../logservice/metrics/LogServiceMetrics.java      | 45 +++++++++++++++
 .../metrics/LogServiceMetricsRegistry.java         | 65 ----------------------
 .../ratis/logservice/server/LogStateMachine.java   | 32 +++++------
 .../ratis/logservice/server/MetaStateMachine.java  | 15 +++--
 .../ratis/logservice/LogServiceReadWriteBase.java  |  9 ++-
 .../ratis/logservice/server/TestMetaServer.java    |  7 ++-
 .../org/apache/ratis}/metrics/RatisMetrics.java    |  5 +-
 .../org/apache/ratis/server/impl/LeaderState.java  |  1 +
 .../ratis/server/impl/RaftServerMetrics.java       |  2 +-
 .../ratis/server/impl/StateMachineMetrics.java     |  2 +-
 .../server/metrics/LeaderElectionMetrics.java      |  1 +
 .../ratis/server/metrics/LogAppenderMetrics.java   |  1 +
 .../ratis/server/metrics/RaftLogMetrics.java       |  1 +
 .../test/java/org/apache/ratis/RaftBasicTests.java |  2 +-
 .../ratis/server/storage/RaftStorageTestUtils.java |  2 +-
 .../ratis/statemachine/RaftSnapshotBaseTest.java   |  2 +-
 .../ratis/server/raftlog/TestRaftLogMetrics.java   |  3 +-
 20 files changed, 145 insertions(+), 116 deletions(-)

diff --git a/ratis-grpc/src/main/java/org/apache/ratis/grpc/metrics/GrpcServerMetrics.java b/ratis-grpc/src/main/java/org/apache/ratis/grpc/metrics/GrpcServerMetrics.java
index 1bb87e6..01859c2 100644
--- a/ratis-grpc/src/main/java/org/apache/ratis/grpc/metrics/GrpcServerMetrics.java
+++ b/ratis-grpc/src/main/java/org/apache/ratis/grpc/metrics/GrpcServerMetrics.java
@@ -17,19 +17,15 @@
  */
 package org.apache.ratis.grpc.metrics;
 
-import java.util.Optional;
-
 import com.codahale.metrics.Gauge;
-import org.apache.ratis.metrics.MetricRegistries;
 import org.apache.ratis.metrics.MetricRegistryInfo;
 import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.thirdparty.com.google.common.annotations.VisibleForTesting;
 
 import com.codahale.metrics.Timer;
 
-public class GrpcServerMetrics {
-  private final RatisMetricRegistry registry;
-
+public class GrpcServerMetrics extends RatisMetrics {
   private static final String RATIS_GRPC_METRICS_APP_NAME = "ratis_grpc";
   private static final String RATIS_GRPC_METRICS_COMP_NAME = "log_appender";
   private static final String RATIS_GRPC_METRICS_DESC = "Metrics for Ratis Grpc Log Appender";
@@ -52,11 +48,13 @@ public class GrpcServerMetrics {
   public static final String RATIS_GRPC_INSTALL_SNAPSHOT_COUNT = "num_install_snapshot";
 
   public GrpcServerMetrics(String serverId) {
-    MetricRegistryInfo info = new MetricRegistryInfo(serverId, RATIS_GRPC_METRICS_APP_NAME,
-        RATIS_GRPC_METRICS_COMP_NAME, RATIS_GRPC_METRICS_DESC);
-    Optional<RatisMetricRegistry> metricRegistry = MetricRegistries.global().get(info);
+    registry = getMetricRegistryForGrpcServer(serverId);
+  }
 
-    registry = metricRegistry.orElseGet(() -> MetricRegistries.global().create(info));
+  private RatisMetricRegistry getMetricRegistryForGrpcServer(String serverId) {
+    return create(new MetricRegistryInfo(serverId,
+        RATIS_GRPC_METRICS_APP_NAME,
+        RATIS_GRPC_METRICS_COMP_NAME, RATIS_GRPC_METRICS_DESC));
   }
 
   public Timer getGrpcLogAppenderLatencyTimer(String follower,
diff --git a/ratis-grpc/src/main/java/org/apache/ratis/grpc/server/GrpcLogAppender.java b/ratis-grpc/src/main/java/org/apache/ratis/grpc/server/GrpcLogAppender.java
index a7c6284..439ffe8 100644
--- a/ratis-grpc/src/main/java/org/apache/ratis/grpc/server/GrpcLogAppender.java
+++ b/ratis-grpc/src/main/java/org/apache/ratis/grpc/server/GrpcLogAppender.java
@@ -127,6 +127,7 @@ public class GrpcLogAppender extends LogAppender {
     }
 
     Optional.ofNullable(appendLogRequestObserver).ifPresent(StreamObserver::onCompleted);
+    grpcServerMetrics.unregister();
   }
 
   private long getWaitTimeMs() {
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetaDataMetrics.java b/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetaDataMetrics.java
new file mode 100644
index 0000000..eeb274c
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetaDataMetrics.java
@@ -0,0 +1,47 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ratis.logservice.metrics;
+
+import org.apache.ratis.metrics.MetricRegistryInfo;
+import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
+
+import com.codahale.metrics.Timer;
+
+import static org.apache.ratis.logservice.metrics.LogServiceMetrics.RATIS_LOG_SERVICE_METRICS;
+
+public final class LogServiceMetaDataMetrics extends RatisMetrics {
+  public static final String RATIS_LOG_SERVICE_META_DATA_METRICS = "metadata_statemachine";
+  public static final String RATIS_LOG_SERVICE_META_DATA_METRICS_DESC =
+      "Ratis log service metadata metrics";
+
+  public LogServiceMetaDataMetrics(String serverId) {
+    registry = getMetricRegistryForLogServiceMetaData(serverId);
+  }
+
+  private RatisMetricRegistry getMetricRegistryForLogServiceMetaData(String serverId) {
+    return create(new MetricRegistryInfo(serverId,
+        RATIS_LOG_SERVICE_METRICS,
+        RATIS_LOG_SERVICE_META_DATA_METRICS, RATIS_LOG_SERVICE_META_DATA_METRICS_DESC));
+  }
+
+  public Timer getTimer(String name) {
+    return registry.timer(name);
+  }
+}
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetrics.java b/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetrics.java
new file mode 100644
index 0000000..b92655b
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetrics.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ratis.logservice.metrics;
+
+import org.apache.ratis.metrics.MetricRegistryInfo;
+import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
+
+import com.codahale.metrics.Timer;
+
+public final class LogServiceMetrics extends RatisMetrics {
+  public static final String RATIS_LOG_STATEMACHINE_METRICS = "log_statemachine";
+  public static final String RATIS_LOG_SERVICE_METRICS = "ratis_log_service";
+  public static final String RATIS_LOG_SERVICE_METRICS_DESC = "Ratis log service metrics";
+
+  public LogServiceMetrics(String logName, String serverId) {
+    registry = getMetricRegistryForLogService(logName, serverId);
+  }
+
+  private RatisMetricRegistry getMetricRegistryForLogService(String logName, String serverId) {
+    return create(new MetricRegistryInfo(logName + "." + serverId,
+        RATIS_LOG_SERVICE_METRICS,
+        RATIS_LOG_STATEMACHINE_METRICS, RATIS_LOG_SERVICE_METRICS_DESC));
+  }
+
+  public Timer getTimer(String name) {
+    return registry.timer(name);
+  }
+}
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetricsRegistry.java b/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetricsRegistry.java
deleted file mode 100644
index 1d2940b..0000000
--- a/ratis-logservice/src/main/java/org/apache/ratis/logservice/metrics/LogServiceMetricsRegistry.java
+++ /dev/null
@@ -1,65 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.ratis.logservice.metrics;
-
-import org.apache.ratis.metrics.MetricRegistries;
-import org.apache.ratis.metrics.MetricRegistryInfo;
-import org.apache.ratis.metrics.RatisMetricRegistry;
-
-public final class LogServiceMetricsRegistry {
-  public static final String RATIS_LOG_STATEMACHINE_METRICS = "log_statemachine";
-  public static final String RATIS_LOG_SERVICE_METRICS = "ratis_log_service";
-  public static final String RATIS_LOG_SERVICE_METRICS_DESC = "Ratis log service metrics";
-  public static final String RATIS_LOG_SERVICE_META_DATA_METRICS = "metadata_statemachine";
-  public static final String RATIS_LOG_SERVICE_META_DATA_METRICS_DESC =
-      "Ratis log service metadata metrics";
-
-  public static RatisMetricRegistry createMetricRegistryForLogService(String logName,
-      String serverId) {
-    return create(new MetricRegistryInfo(logName + "." + serverId, RATIS_LOG_SERVICE_METRICS,
-        RATIS_LOG_STATEMACHINE_METRICS, RATIS_LOG_SERVICE_METRICS_DESC));
-  }
-
-  public static RatisMetricRegistry getMetricRegistryForLogService(String logName,
-      String serverId) {
-    return MetricRegistries.global().get(
-        new MetricRegistryInfo(logName + "." + serverId, RATIS_LOG_SERVICE_METRICS,
-            RATIS_LOG_STATEMACHINE_METRICS, RATIS_LOG_SERVICE_METRICS_DESC)).get();
-  }
-
-  public static RatisMetricRegistry createMetricRegistryForLogServiceMetaData(String serverId) {
-    return create(new MetricRegistryInfo(serverId, RATIS_LOG_SERVICE_METRICS,
-        RATIS_LOG_SERVICE_META_DATA_METRICS, RATIS_LOG_SERVICE_META_DATA_METRICS_DESC));
-  }
-
-  public static RatisMetricRegistry getMetricRegistryForLogServiceMetaData(String serverId) {
-    return MetricRegistries.global().get(new MetricRegistryInfo(serverId, RATIS_LOG_SERVICE_METRICS,
-        RATIS_LOG_SERVICE_META_DATA_METRICS, RATIS_LOG_SERVICE_META_DATA_METRICS_DESC)).get();
-  }
-
-  private static RatisMetricRegistry create(MetricRegistryInfo info) {
-    RatisMetricRegistry registry = MetricRegistries.global().create(info);
-    return registry;
-  }
-
-  private LogServiceMetricsRegistry() {
-    throw new UnsupportedOperationException("no instances");
-  }
-
-}
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/LogStateMachine.java b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/LogStateMachine.java
index 1d13457..3a0d779 100644
--- a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/LogStateMachine.java
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/LogStateMachine.java
@@ -50,7 +50,7 @@ import org.apache.ratis.logservice.api.LogName;
 import org.apache.ratis.logservice.common.Constants;
 import org.apache.ratis.logservice.impl.ArchiveHdfsLogReader;
 import org.apache.ratis.logservice.impl.ArchiveHdfsLogWriter;
-import org.apache.ratis.logservice.metrics.LogServiceMetricsRegistry;
+import org.apache.ratis.logservice.metrics.LogServiceMetrics;
 import org.apache.ratis.logservice.proto.LogServiceProtos;
 import org.apache.ratis.logservice.proto.LogServiceProtos.AppendLogEntryRequestProto;
 import org.apache.ratis.logservice.proto.LogServiceProtos.GetLogLengthRequestProto;
@@ -60,7 +60,6 @@ import org.apache.ratis.logservice.proto.LogServiceProtos.LogServiceRequestProto
 import org.apache.ratis.logservice.proto.LogServiceProtos.ReadLogRequestProto;
 import org.apache.ratis.logservice.util.LogServiceProtoUtil;
 import org.apache.ratis.logservice.util.LogServiceUtils;
-import org.apache.ratis.metrics.RatisMetricRegistry;
 import org.apache.ratis.proto.RaftProtos;
 import org.apache.ratis.proto.RaftProtos.LogEntryProto;
 import org.apache.ratis.protocol.ClientId;
@@ -90,7 +89,7 @@ public class LogStateMachine extends BaseStateMachine {
   public static final Logger LOG = LoggerFactory.getLogger(LogStateMachine.class);
   public static final long DEFAULT_ARCHIVE_THRESHOLD_PER_FILE = 1000000;
   private final RaftProperties properties;
-  private RatisMetricRegistry metricRegistry;
+  private LogServiceMetrics logServiceMetrics;
   private Timer sizeRequestTimer;
   private Timer readNextQueryTimer;
   private Timer getStateTimer;
@@ -158,20 +157,20 @@ public class LogStateMachine extends BaseStateMachine {
     this.storage.init(raftStorage);
     this.proxy = (RaftServerProxy) server;
     //TODO: using groupId for metric now but better to tag it with LogName
-    this.metricRegistry = LogServiceMetricsRegistry
-        .createMetricRegistryForLogService(groupId.toString(), server.getId().toString());
-    this.readNextQueryTimer = metricRegistry.timer("readNextQueryTime");
-    this.startIndexTimer= metricRegistry.timer("startIndexTime");
-    this.sizeRequestTimer = metricRegistry.timer("sizeRequestTime");
-    this.getStateTimer = metricRegistry.timer("getStateTime");
-    this.lastIndexQueryTimer = metricRegistry.timer("lastIndexQueryTime");
-    this.lengthQueryTimer = metricRegistry.timer("lengthQueryTime");
-    this.syncRequesTimer = metricRegistry.timer("syncRequesTime");
-    this.appendRequestTimer = metricRegistry.timer("appendRequestTime");
-    this.getCloseLogTimer = metricRegistry.timer("getCloseLogTime");
+    this.logServiceMetrics = new LogServiceMetrics(groupId.toString(),
+        server.getId().toString());
+    this.readNextQueryTimer = logServiceMetrics.getTimer("readNextQueryTime");
+    this.startIndexTimer= logServiceMetrics.getTimer("startIndexTime");
+    this.sizeRequestTimer = logServiceMetrics.getTimer("sizeRequestTime");
+    this.getStateTimer = logServiceMetrics.getTimer("getStateTime");
+    this.lastIndexQueryTimer = logServiceMetrics.getTimer("lastIndexQueryTime");
+    this.lengthQueryTimer = logServiceMetrics.getTimer("lengthQueryTime");
+    this.syncRequesTimer = logServiceMetrics.getTimer("syncRequesTime");
+    this.appendRequestTimer = logServiceMetrics.getTimer("appendRequestTime");
+    this.getCloseLogTimer = logServiceMetrics.getTimer("getCloseLogTime");
     //archiving request time not the actual archiving time
-    this.archiveLogRequestTimer = metricRegistry.timer("archiveLogRequestTime");
-    this.archiveLogTimer = metricRegistry.timer("archiveLogTime");
+    this.archiveLogRequestTimer = logServiceMetrics.getTimer("archiveLogRequestTime");
+    this.archiveLogTimer = logServiceMetrics.getTimer("archiveLogTime");
     loadSnapshot(storage.getLatestSnapshot());
     executorService = Executors.newSingleThreadExecutor();
     this.archivalInfo =
@@ -485,6 +484,7 @@ public class LogStateMachine extends BaseStateMachine {
   @Override
   public void close() {
     reset();
+    logServiceMetrics.unregister();
   }
 
   @Override
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/MetaStateMachine.java b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/MetaStateMachine.java
index ad1d7ee..87e7d13 100644
--- a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/MetaStateMachine.java
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/MetaStateMachine.java
@@ -38,7 +38,7 @@ import org.apache.ratis.logservice.common.Constants;
 import org.apache.ratis.logservice.common.LogAlreadyExistException;
 import org.apache.ratis.logservice.common.LogNotFoundException;
 import org.apache.ratis.logservice.common.NoEnoughWorkersException;
-import org.apache.ratis.logservice.metrics.LogServiceMetricsRegistry;
+import org.apache.ratis.logservice.metrics.LogServiceMetaDataMetrics;
 import org.apache.ratis.logservice.proto.LogServiceProtos;
 import org.apache.ratis.logservice.proto.MetaServiceProtos;
 import org.apache.ratis.logservice.proto.MetaServiceProtos.CreateLogRequestProto;
@@ -49,7 +49,6 @@ import org.apache.ratis.logservice.proto.MetaServiceProtos.LogServiceUnregisterL
 import org.apache.ratis.logservice.proto.MetaServiceProtos.MetaSMRequestProto;
 import org.apache.ratis.logservice.util.LogServiceProtoUtil;
 import org.apache.ratis.logservice.util.MetaServiceProtoUtil;
-import org.apache.ratis.metrics.RatisMetricRegistry;
 import org.apache.ratis.proto.RaftProtos;
 import org.apache.ratis.protocol.*;
 
@@ -103,7 +102,7 @@ public class MetaStateMachine extends BaseStateMachine {
 
     private RaftGroupId metadataGroupId;
     private RaftGroupId logServerGroupId;
-    private RatisMetricRegistry metricRegistry;
+    private LogServiceMetaDataMetrics logServiceMetaDataMetrics;
 
     public MetaStateMachine(RaftGroupId metadataGroupId, RaftGroupId logServerGroupId,
                             long failureDetectionPeriod) {
@@ -115,8 +114,7 @@ public class MetaStateMachine extends BaseStateMachine {
     @Override
     public void initialize(RaftServer server, RaftGroupId groupId, RaftStorage storage) throws IOException {
         this.raftServer = server;
-        this.metricRegistry = LogServiceMetricsRegistry
-            .createMetricRegistryForLogServiceMetaData(server.getId().toString());
+        this.logServiceMetaDataMetrics = new LogServiceMetaDataMetrics(server.getId().toString());
         super.initialize(server, groupId, storage);
         peerHealthChecker = new Daemon(new PeerHealthChecker(),"peer-Health-Checker");
         peerHealthChecker.start();
@@ -221,7 +219,7 @@ public class MetaStateMachine extends BaseStateMachine {
                 e.printStackTrace();
             }
             type = req.getTypeCase();
-            timerContext = metricRegistry.timer(type.name()).time();
+            timerContext = logServiceMetaDataMetrics.getTimer(type.name()).time();
             switch (type) {
 
             case CREATELOG:
@@ -518,4 +516,9 @@ public class MetaStateMachine extends BaseStateMachine {
         }
         return true;
     }
+
+    @Override
+    public void close() {
+      logServiceMetaDataMetrics.unregister();
+    }
 }
diff --git a/ratis-logservice/src/test/java/org/apache/ratis/logservice/LogServiceReadWriteBase.java b/ratis-logservice/src/test/java/org/apache/ratis/logservice/LogServiceReadWriteBase.java
index 2606c2c..c579990 100644
--- a/ratis-logservice/src/test/java/org/apache/ratis/logservice/LogServiceReadWriteBase.java
+++ b/ratis-logservice/src/test/java/org/apache/ratis/logservice/LogServiceReadWriteBase.java
@@ -44,7 +44,7 @@ import org.apache.ratis.logservice.api.LogStream;
 import org.apache.ratis.logservice.api.LogStream.State;
 import org.apache.ratis.logservice.api.LogWriter;
 import org.apache.ratis.logservice.impl.LogStreamImpl;
-import org.apache.ratis.logservice.metrics.LogServiceMetricsRegistry;
+import org.apache.ratis.logservice.metrics.LogServiceMetrics;
 import org.apache.ratis.logservice.server.LogStateMachine;
 import org.apache.ratis.logservice.util.TestUtils;
 import org.apache.ratis.metrics.JVMMetrics;
@@ -324,10 +324,9 @@ public abstract class LogServiceReadWriteBase<CLUSTER extends MiniRaftCluster>
   }
 
   private Long getJMXCount(String groupId, String metricName) throws Exception {
-    ObjectName oname = new ObjectName(LogServiceMetricsRegistry.RATIS_LOG_SERVICE_METRICS, "name",
-        LogServiceMetricsRegistry
-            .getMetricRegistryForLogService(groupId, cluster.getLeader().getId().toString())
-            .getMetricRegistryInfo().getName() + "." + metricName);
+    ObjectName oname = new ObjectName(LogServiceMetrics.RATIS_LOG_SERVICE_METRICS, "name",
+        new LogServiceMetrics(groupId, cluster.getLeader().getId().toString())
+            .getRegistry().getMetricRegistryInfo().getName() + "." + metricName);
     return (Long) ManagementFactory.getPlatformMBeanServer().getAttribute(oname, "Count");
   }
 }
diff --git a/ratis-logservice/src/test/java/org/apache/ratis/logservice/server/TestMetaServer.java b/ratis-logservice/src/test/java/org/apache/ratis/logservice/server/TestMetaServer.java
index 381c7ae..5fda82b 100644
--- a/ratis-logservice/src/test/java/org/apache/ratis/logservice/server/TestMetaServer.java
+++ b/ratis-logservice/src/test/java/org/apache/ratis/logservice/server/TestMetaServer.java
@@ -23,7 +23,8 @@ import org.apache.ratis.logservice.api.LogStream.State;
 import org.apache.ratis.logservice.api.LogServiceClient;
 import org.apache.ratis.logservice.common.LogAlreadyExistException;
 import org.apache.ratis.logservice.common.LogNotFoundException;
-import org.apache.ratis.logservice.metrics.LogServiceMetricsRegistry;
+import org.apache.ratis.logservice.metrics.LogServiceMetaDataMetrics;
+import org.apache.ratis.logservice.metrics.LogServiceMetrics;
 import org.apache.ratis.logservice.proto.MetaServiceProtos;
 import org.apache.ratis.logservice.util.LogServiceCluster;
 import org.apache.ratis.logservice.util.TestUtils;
@@ -342,8 +343,8 @@ public class TestMetaServer {
     private Long getJMXCount(String metricName) throws Exception {
         for (MetadataServer master : cluster.getMasters()) {
             ObjectName oname =
-                new ObjectName(LogServiceMetricsRegistry.RATIS_LOG_SERVICE_METRICS, "name",
-                    LogServiceMetricsRegistry.getMetricRegistryForLogServiceMetaData(master.getId())
+                new ObjectName(LogServiceMetrics.RATIS_LOG_SERVICE_METRICS, "name",
+                    new LogServiceMetaDataMetrics(master.getId()).getRegistry()
                         .getMetricRegistryInfo().getName() + "." + metricName);
             try {
                 return (Long) ManagementFactory.getPlatformMBeanServer()
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/metrics/RatisMetrics.java b/ratis-metrics/src/main/java/org/apache/ratis/metrics/RatisMetrics.java
similarity index 90%
rename from ratis-server/src/main/java/org/apache/ratis/server/metrics/RatisMetrics.java
rename to ratis-metrics/src/main/java/org/apache/ratis/metrics/RatisMetrics.java
index 0ca63ba..4806547 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/metrics/RatisMetrics.java
+++ b/ratis-metrics/src/main/java/org/apache/ratis/metrics/RatisMetrics.java
@@ -16,13 +16,10 @@
  * limitations under the License.
  */
 
-package org.apache.ratis.server.metrics;
+package org.apache.ratis.metrics;
 
 import java.util.Optional;
 
-import org.apache.ratis.metrics.MetricRegistries;
-import org.apache.ratis.metrics.MetricRegistryInfo;
-import org.apache.ratis.metrics.RatisMetricRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderState.java
index c794ed5..745a11a 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/LeaderState.java
@@ -276,6 +276,7 @@ public class LeaderState {
     streamRequests.clear();
     server.getServerRpc().notifyNotLeader(server.getMemberId().getGroupId());
     logAppenderMetrics.unregister();
+    raftServerMetrics.unregister();
   }
 
   void notifySenders() {
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerMetrics.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerMetrics.java
index 0098627..a0ab45c 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerMetrics.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerMetrics.java
@@ -36,7 +36,7 @@ import org.apache.ratis.proto.RaftProtos.RaftClientRequestProto.TypeCase;
 import org.apache.ratis.protocol.RaftClientRequest;
 import org.apache.ratis.protocol.RaftPeer;
 import org.apache.ratis.protocol.RaftPeerId;
-import org.apache.ratis.server.metrics.RatisMetrics;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.thirdparty.com.google.common.annotations.VisibleForTesting;
 import org.apache.ratis.util.Preconditions;
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineMetrics.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineMetrics.java
index ad0a44c..02aaefa 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineMetrics.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/StateMachineMetrics.java
@@ -20,7 +20,7 @@ package org.apache.ratis.server.impl;
 
 import org.apache.ratis.metrics.MetricRegistryInfo;
 import org.apache.ratis.metrics.RatisMetricRegistry;
-import org.apache.ratis.server.metrics.RatisMetrics;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.server.raftlog.RaftLogIndex;
 import org.apache.ratis.statemachine.StateMachine;
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/metrics/LeaderElectionMetrics.java b/ratis-server/src/main/java/org/apache/ratis/server/metrics/LeaderElectionMetrics.java
index c9a90e1..f803ccd 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/metrics/LeaderElectionMetrics.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/metrics/LeaderElectionMetrics.java
@@ -20,6 +20,7 @@ package org.apache.ratis.server.metrics;
 
 import org.apache.ratis.metrics.MetricRegistryInfo;
 import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.server.impl.RaftServerImpl;
 
 /**
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/metrics/LogAppenderMetrics.java b/ratis-server/src/main/java/org/apache/ratis/server/metrics/LogAppenderMetrics.java
index 9fc44be..e4213c0 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/metrics/LogAppenderMetrics.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/metrics/LogAppenderMetrics.java
@@ -23,6 +23,7 @@ import static org.apache.ratis.server.metrics.RaftLogMetrics.FOLLOWER_RPC_RESP_T
 
 import org.apache.ratis.metrics.MetricRegistryInfo;
 import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.protocol.RaftGroupMemberId;
 import org.apache.ratis.server.impl.FollowerInfo;
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/metrics/RaftLogMetrics.java b/ratis-server/src/main/java/org/apache/ratis/server/metrics/RaftLogMetrics.java
index 5eb2a85..51bb67b 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/metrics/RaftLogMetrics.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/metrics/RaftLogMetrics.java
@@ -22,6 +22,7 @@ import java.util.Queue;
 
 import org.apache.ratis.metrics.MetricRegistryInfo;
 import org.apache.ratis.metrics.RatisMetricRegistry;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.util.DataQueue;
 
 import com.codahale.metrics.Gauge;
diff --git a/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java b/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
index a550df7..d253b2b 100644
--- a/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
+++ b/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
@@ -62,7 +62,7 @@ import static org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHIN
 import static org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS_DESC;
 import static org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLIED_INDEX_GAUGE;
 import static org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLY_COMPLETED_GAUGE;
-import static org.apache.ratis.server.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
+import static org.apache.ratis.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
 
 public abstract class RaftBasicTests<CLUSTER extends MiniRaftCluster>
     extends BaseTest
diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
index 5bebde3..74ed663 100644
--- a/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
+++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/RaftStorageTestUtils.java
@@ -22,7 +22,7 @@ import static org.apache.ratis.server.metrics.RaftLogMetrics.RATIS_LOG_WORKER_ME
 
 import org.apache.ratis.protocol.RaftPeerId;
 import org.apache.ratis.server.impl.ServerProtoUtils;
-import org.apache.ratis.server.metrics.RatisMetrics;
+import org.apache.ratis.metrics.RatisMetrics;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.apache.ratis.server.raftlog.RaftLog;
 import org.apache.ratis.server.raftlog.RaftLogIOException;
diff --git a/ratis-server/src/test/java/org/apache/ratis/statemachine/RaftSnapshotBaseTest.java b/ratis-server/src/test/java/org/apache/ratis/statemachine/RaftSnapshotBaseTest.java
index 3e2c752..f29c98b 100644
--- a/ratis-server/src/test/java/org/apache/ratis/statemachine/RaftSnapshotBaseTest.java
+++ b/ratis-server/src/test/java/org/apache/ratis/statemachine/RaftSnapshotBaseTest.java
@@ -21,7 +21,7 @@ import static org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHIN
 import static org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS_DESC;
 import static org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_TAKE_SNAPSHOT_TIMER;
 import static org.apache.ratis.server.metrics.RaftLogMetrics.LOG_APPENDER_INSTALL_SNAPSHOT_METRIC;
-import static org.apache.ratis.server.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
+import static org.apache.ratis.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
 
 import org.apache.log4j.Level;
 import org.apache.ratis.BaseTest;
diff --git a/ratis-test/src/test/java/org/apache/ratis/server/raftlog/TestRaftLogMetrics.java b/ratis-test/src/test/java/org/apache/ratis/server/raftlog/TestRaftLogMetrics.java
index f1c8156..f72b706 100644
--- a/ratis-test/src/test/java/org/apache/ratis/server/raftlog/TestRaftLogMetrics.java
+++ b/ratis-test/src/test/java/org/apache/ratis/server/raftlog/TestRaftLogMetrics.java
@@ -30,7 +30,7 @@ import static org.apache.ratis.server.metrics.RaftLogMetrics.RAFT_LOG_TASK_ENQUE
 import static org.apache.ratis.server.metrics.RaftLogMetrics.RAFT_LOG_TASK_EXECUTION_TIME;
 import static org.apache.ratis.server.metrics.RaftLogMetrics.RAFT_LOG_TASK_QUEUE_TIME;
 import static org.apache.ratis.server.metrics.RaftLogMetrics.RAFT_LOG_WORKER_QUEUE_SIZE;
-import static org.apache.ratis.server.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
+import static org.apache.ratis.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS;
 
 import com.codahale.metrics.Timer;
 import org.apache.ratis.BaseTest;
@@ -46,7 +46,6 @@ import org.apache.ratis.server.storage.RaftStorageTestUtils;
 import org.apache.ratis.statemachine.StateMachine;
 import org.apache.ratis.statemachine.impl.BaseStateMachine;
 import org.apache.ratis.util.JavaUtils;
-import org.apache.ratis.util.LogUtils;
 import org.apache.ratis.util.TimeDuration;
 import org.junit.Assert;
 import org.junit.Test;