You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ki...@apache.org on 2023/04/11 13:32:04 UTC

[ranger] branch master updated: RANGER-4152: Create common module for metrics and add metrics in Admin

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 932bc3404 RANGER-4152: Create common module for metrics and add metrics in Admin
932bc3404 is described below

commit 932bc3404eb760148e4458071faba1c29baa7dcc
Author: Kishor Gollapalliwar <ki...@gmail.com>
AuthorDate: Mon Mar 27 20:40:30 2023 +0530

    RANGER-4152: Create common module for metrics and add metrics in Admin
---
 pom.xml                                            |   2 +
 ranger-metrics/.gitignore                          |   1 +
 ranger-metrics/pom.xml                             |  55 +++++++++
 .../apache/ranger/metrics/RangerMetricsInfo.java   |  42 +++++++
 .../ranger/metrics/RangerMetricsSystemWrapper.java |  99 ++++++++++++++++
 .../ranger/metrics/sink/RangerMetricsJsonSink.java |  85 ++++++++++++++
 .../metrics/sink/RangerMetricsPrometheusSink.java  | 114 +++++++++++++++++++
 .../metrics/source/RangerMetricsJvmSource.java     | 125 +++++++++++++++++++++
 .../ranger/metrics/source/RangerMetricsSource.java |  44 ++++++++
 .../metrics/wrapper/RangerMetricsSinkWrapper.java  |  46 ++++++++
 .../wrapper/RangerMetricsSourceWrapper.java        |  53 +++++++++
 security-admin/pom.xml                             |   5 +
 .../java/org/apache/ranger/biz/ServiceDBStore.java |  28 +++++
 .../main/java/org/apache/ranger/biz/XUserMgr.java  |   4 +
 .../java/org/apache/ranger/db/XXPortalUserDao.java |  19 ++++
 .../java/org/apache/ranger/db/XXServiceDao.java    |   1 -
 .../java/org/apache/ranger/db/XXServiceDefDao.java |  71 ++++++++++++
 .../main/java/org/apache/ranger/db/XXUserDao.java  |   1 -
 .../ranger/metrics/RangerAdminMetricsWrapper.java  | 109 ++++++++++++++++++
 .../ranger/metrics/RangerMetricsFetcher.java       | 124 ++++++++++++++++++++
 .../source/RangerAdminMetricsSourceBase.java       |  72 ++++++++++++
 .../RangerAdminMetricsSourceContextEnricher.java   |  43 +++++++
 .../RangerAdminMetricsSourceDenyConditions.java    |  43 +++++++
 .../RangerAdminMetricsSourcePolicyMasking.java     |  44 ++++++++
 ...ngerAdminMetricsSourcePolicyResourceAccess.java |  45 ++++++++
 ...RangerAdminMetricsSourcePolicyRowFiltering.java |  44 ++++++++
 .../source/RangerAdminMetricsSourceService.java    |  43 +++++++
 .../source/RangerAdminMetricsSourceUserGroup.java  |  44 ++++++++
 .../java/org/apache/ranger/rest/MetricsREST.java   |  46 ++++++++
 .../org/apache/ranger/service/XGroupService.java   |   4 +
 .../main/resources/META-INF/jpa_named_queries.xml  |  25 ++++-
 .../conf.dist/security-applicationContext.xml      |   2 +-
 .../src/main/resources/hadoop-metrics2.properties  |  54 +++++++++
 33 files changed, 1531 insertions(+), 6 deletions(-)

diff --git a/pom.xml b/pom.xml
index df83bf5ce..31f18cbba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -393,6 +393,7 @@
                 <module>plugin-elasticsearch</module>
                 <module>ranger-elasticsearch-plugin-shim</module>
                 <module>ranger-authn</module>
+                <module>ranger-metrics</module>
                 <!--
                    'distro' should be the last module. If a module gets inserted after
                    ranger-elasticsearch-plugin-shim, make sure to update dependency in distro/pom.xml
@@ -718,6 +719,7 @@
                 <module>plugin-elasticsearch</module>
                 <module>ranger-elasticsearch-plugin-shim</module>
                 <module>ranger-authn</module>
+                <module>ranger-metrics</module>
                 <!--
                    'distro' should be the last module. If a module gets inserted after
                    ranger-elasticsearch-plugin-shim, make sure to update dependency in distro/pom.xml
diff --git a/ranger-metrics/.gitignore b/ranger-metrics/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/ranger-metrics/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/ranger-metrics/pom.xml b/ranger-metrics/pom.xml
new file mode 100644
index 000000000..44602c3b8
--- /dev/null
+++ b/ranger-metrics/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ranger-metrics</artifactId>
+    <name>ranger-metrics</name>
+
+    <description>Ranger Metrics module</description>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <parent>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-common</artifactId>
+            <version>${hadoop.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>io.netty</groupId>
+                    <artifactId>netty-all</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- Test -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsInfo.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsInfo.java
new file mode 100644
index 000000000..4f12a339e
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsInfo.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ranger.metrics;
+
+import org.apache.hadoop.metrics2.MetricsInfo;
+
+public class RangerMetricsInfo implements MetricsInfo {
+    private final String name;
+    private final String description;
+
+    public RangerMetricsInfo(String name, String description) {
+        this.name        = name;
+        this.description = description;
+    }
+
+    @Override
+    public String name() {
+        return this.name;
+    }
+
+    @Override
+    public String description() {
+        return this.description;
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsSystemWrapper.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsSystemWrapper.java
new file mode 100644
index 000000000..cd806574d
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/RangerMetricsSystemWrapper.java
@@ -0,0 +1,99 @@
+/*
+ * 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.ranger.metrics;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.hadoop.metrics2.MetricsSystem;
+import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
+import org.apache.ranger.metrics.sink.RangerMetricsJsonSink;
+import org.apache.ranger.metrics.sink.RangerMetricsPrometheusSink;
+import org.apache.ranger.metrics.source.RangerMetricsJvmSource;
+import org.apache.ranger.metrics.wrapper.RangerMetricsSinkWrapper;
+import org.apache.ranger.metrics.wrapper.RangerMetricsSourceWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RangerMetricsSystemWrapper {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerMetricsSystemWrapper.class);
+
+    private RangerMetricsPrometheusSink rangerMetricsPrometheusSink;
+    private RangerMetricsJsonSink rangerMetricsJsonSink;
+
+    /**
+     * Initialized metric system.
+     * @param serviceName
+     * @param sourceWrappers
+     * @param sinkWrappers
+     */
+    public void init(String serviceName, List<RangerMetricsSourceWrapper> sourceWrappers, List<RangerMetricsSinkWrapper> sinkWrappers) {
+        // Initialize metrics system
+        MetricsSystem metricsSystem = DefaultMetricsSystem.initialize(serviceName);
+        Set<String> sourceContexts = new HashSet<String>();
+        sourceContexts.add(serviceName);
+
+        // Ranger Source
+        if (Objects.isNull(sourceWrappers) || sourceWrappers.isEmpty()) {
+            sourceWrappers = new ArrayList<RangerMetricsSourceWrapper>();
+        }
+        sourceWrappers.add(new RangerMetricsSourceWrapper("RangerJVM", "Ranger common metric source (RangerMetricsJvmSource)", serviceName, new RangerMetricsJvmSource(serviceName)));
+
+        for (RangerMetricsSourceWrapper sourceWrapper: sourceWrappers) {
+            metricsSystem.register(sourceWrapper.getName(), sourceWrapper.getDescription(), sourceWrapper.getSource());
+            sourceContexts.add(sourceWrapper.getContext());
+        }
+
+        // Ranger Sink
+        if (Objects.isNull(sinkWrappers) || sinkWrappers.isEmpty()) {
+            sinkWrappers = new ArrayList<RangerMetricsSinkWrapper>();
+        }
+
+        // Prometheus
+        rangerMetricsPrometheusSink = new RangerMetricsPrometheusSink(sourceContexts);
+        sinkWrappers.add(new RangerMetricsSinkWrapper("Prometheus", "Ranger common metric sink (RangerMetricsPrometheusSink)", rangerMetricsPrometheusSink));
+
+        // JSON
+        rangerMetricsJsonSink = new RangerMetricsJsonSink(sourceContexts);
+        sinkWrappers.add(new RangerMetricsSinkWrapper("Json", "Ranger common metric sink (RangerMetricsJsonSink)", rangerMetricsJsonSink));
+
+        for (RangerMetricsSinkWrapper sinkWrapper: sinkWrappers) {
+            metricsSystem.register(sinkWrapper.getName(), sinkWrapper.getDescription(), sinkWrapper.getSink());
+        }
+
+        LOG.info("===>> Ranger Metric system initialized successfully.");
+    }
+
+    public String getRangerMetricsInPrometheusFormat() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        rangerMetricsPrometheusSink.writeMetrics(stringWriter);
+        return stringWriter.toString();
+    }
+
+    public Map<String, Map<String, Object>> getRangerMetrics() {
+        return rangerMetricsJsonSink.getMetrics();
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsJsonSink.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsJsonSink.java
new file mode 100644
index 000000000..4e23120dd
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsJsonSink.java
@@ -0,0 +1,85 @@
+/*
+ * 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.ranger.metrics.sink;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.commons.configuration2.SubsetConfiguration;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricType;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsSink;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RangerMetricsJsonSink implements MetricsSink {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerMetricsJsonSink.class);
+
+    private final Set<String> contexts;
+    private final Map<String, Map<String, Object>> metricsJson = new HashMap<>();
+
+    public RangerMetricsJsonSink(Set<String> contexts) {
+        this.contexts = contexts;
+    }
+
+    @Override
+    public void init(SubsetConfiguration conf) {
+     // Implementation not needed
+    }
+
+    @Override
+    public void putMetrics(MetricsRecord metricsRecord) {
+        try {
+            if (contexts.contains(metricsRecord.context())) {
+                for (AbstractMetric metrics : metricsRecord.metrics()) {
+                    if (metrics.type() == MetricType.COUNTER || metrics.type() == MetricType.GAUGE) {
+                        String recordName =  metricsRecord.name();
+                        Map<String, Object> record = metricsJson.get(recordName);
+
+                        if (Objects.isNull(record)) {
+                            record = new HashMap<> ();
+                        }
+
+                        record.put(metrics.name(), metrics.value());
+                        metricsJson.put(recordName, record);
+                    }
+                }
+            } else {
+                if (LOG.isDebugEnabled()) {
+		    LOG.debug("=== RangerMetricsJsonSink:putMetrics(): skipping... "+ metricsRecord.context());
+		}
+            }
+        } catch (Exception e) {
+            LOG.error("Exception occured while converting metrics into json.", e);
+        }
+    }
+
+    @Override
+    public void flush() {
+     // Implementation not needed
+    }
+
+    public Map<String, Map<String, Object>> getMetrics() {
+        return metricsJson;
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsPrometheusSink.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsPrometheusSink.java
new file mode 100644
index 000000000..141fa372a
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/sink/RangerMetricsPrometheusSink.java
@@ -0,0 +1,114 @@
+/*
+ * 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.ranger.metrics.sink;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+import org.apache.commons.configuration2.SubsetConfiguration;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.metrics2.AbstractMetric;
+import org.apache.hadoop.metrics2.MetricType;
+import org.apache.hadoop.metrics2.MetricsRecord;
+import org.apache.hadoop.metrics2.MetricsSink;
+import org.apache.hadoop.metrics2.MetricsTag;
+
+public class RangerMetricsPrometheusSink implements MetricsSink {
+    private static final Pattern SPLIT_PATTERN = Pattern.compile("(?<!(^|[A-Z_]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
+    private static final Pattern DELIMITERS    = Pattern.compile("[^a-zA-Z0-9]+");
+
+    /**
+     * Cached output lines for each metrics.
+     */
+    private final Map<String, String> metricLines = new ConcurrentHashMap<>();
+    private final Set<String> contexts;
+
+    public RangerMetricsPrometheusSink(Set<String> metricsContexts) {
+        if (Objects.isNull(metricsContexts)) {
+            this.contexts = Collections.emptySet();
+        } else {
+            this.contexts = metricsContexts;
+        }
+    }
+
+    @Override
+    public void init(SubsetConfiguration conf) {
+        // Implementation not needed
+    }
+
+    @Override
+    public void putMetrics(MetricsRecord metricsRecord) {
+        if (contexts.contains(metricsRecord.context())) {
+            for (AbstractMetric metrics : metricsRecord.metrics()) {
+                if (metrics.type() == MetricType.COUNTER || metrics.type() == MetricType.GAUGE) {
+
+                    String key = prometheusName(metricsRecord.name(), metrics.name());
+
+                    StringBuilder builder = new StringBuilder();
+                    builder.append("# TYPE ").append(key).append(" ").append(metrics.type().toString().toLowerCase()).append("\n").append(key).append("{");
+                    String sep = "";
+
+                    // add tags
+                    for (MetricsTag tag : metricsRecord.tags()) {
+                        String tagName = tag.name().toLowerCase();
+
+                        // ignore specific tag which includes sub-hierarchy
+                        if (!tagName.equals("numopenconnectionsperuser")) {
+                            builder.append(sep).append(tagName).append("=\"").append(tag.value()).append("\"");
+                            sep = ",";
+                        }
+                    }
+                    builder.append("} ");
+                    builder.append(metrics.value());
+                    builder.append("\n");
+                    metricLines.put(key, builder.toString());
+                }
+            }
+        } 
+    }
+
+    /**
+     * Convert CamelCase based names to lower-case names where the separator is the
+     * underscore, to follow prometheus naming conventions.
+     */
+    public String prometheusName(String recordName, String metricName) {
+        String   baseName = StringUtils.capitalize(recordName) + StringUtils.capitalize(metricName);
+        String[] parts    = SPLIT_PATTERN.split(baseName);
+        String   joined   = String.join("_", parts).toLowerCase();
+        return DELIMITERS.matcher(joined).replaceAll("_");
+    }
+
+    @Override
+    public void flush() {
+        // Implementation not needed
+    }
+
+    public void writeMetrics(Writer writer) throws IOException {
+        for (String line : metricLines.values()) {
+            writer.write(line);
+        }
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsJvmSource.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsJvmSource.java
new file mode 100644
index 000000000..2ea27c411
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsJvmSource.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.ThreadMXBean;
+import java.lang.management.ThreadInfo;
+import java.util.Objects;
+
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.ranger.metrics.RangerMetricsInfo;
+
+public class RangerMetricsJvmSource extends RangerMetricsSource {
+    private long  memoryCurrent;
+    private long  memoryMaximum;
+    private long  gcCountTotal;
+    private long  gcTimeTotal;
+    private long  gcTimeMax;
+    private int   threadsBusy;
+    private int   threadsBlocked;
+    private int   threadsWaiting;
+    private int   threadsRemaining;
+    private int   processorsAvailable;
+    private float systemLoadAverage;
+
+    private final String context;
+
+    public RangerMetricsJvmSource(String context) {
+        this.context = context;
+    }
+
+    @Override
+    protected void refresh() {
+        // Memory
+        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+        memoryCurrent = memoryMXBean.getHeapMemoryUsage().getUsed();
+        memoryMaximum = memoryMXBean.getHeapMemoryUsage().getCommitted();
+
+        // Threads
+        // reset
+        threadsBusy = threadsBlocked = threadsWaiting = threadsRemaining = 0;
+
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        for (Long threadID : threadMXBean.getAllThreadIds()) {
+            ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadID, 0);
+            if (Objects.nonNull(threadInfo)) {
+                switch(threadInfo.getThreadState().toString()) {
+                    case "RUNNABLE": threadsBusy++;    break;
+                    case "BLOCKED" : threadsBlocked++; break;
+                    case "WAITING" : threadsWaiting++; break;
+
+                    default        : threadsRemaining++; break;
+                }
+            }
+        }
+
+        // Load
+        OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
+        systemLoadAverage = (float) osMXBean.getSystemLoadAverage();
+        processorsAvailable = osMXBean.getAvailableProcessors();
+
+        // GC
+        long totalGarbageCollections = 0;
+        long garbageCollectionTime = 0;
+
+        for(GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
+
+            long count = gc.getCollectionCount();
+
+            if(count >= 0) {
+                totalGarbageCollections += count;
+            }
+
+            long time = gc.getCollectionTime();
+
+            if(time >= 0) {
+                garbageCollectionTime += time;
+            }
+
+            if (time > gcTimeMax) {
+                gcTimeMax = time;
+            }
+        }
+
+        gcCountTotal = totalGarbageCollections;
+        gcTimeTotal = garbageCollectionTime;
+    }
+
+    @Override
+    protected void update(MetricsCollector collector, boolean all) {
+        collector.addRecord("RangerJvm")
+        .setContext(this.context)
+        .addGauge(new RangerMetricsInfo("MemoryCurrent", "Ranger current memory utilization"), memoryCurrent)
+        .addGauge(new RangerMetricsInfo("MemoryMax", "Ranger max memory utilization"), memoryMaximum)
+        .addGauge(new RangerMetricsInfo("GcCountTotal", "Ranger app total GCs"), gcCountTotal)
+        .addGauge(new RangerMetricsInfo("GcTimeTotal", "Ranger app total GC time"), gcTimeTotal)
+        .addGauge(new RangerMetricsInfo("GcTimeMax", "Ranger app MAX GC time"), gcTimeMax)
+        .addGauge(new RangerMetricsInfo("ThreadsBusy", "Ranger busy threads"), threadsBusy)
+        .addGauge(new RangerMetricsInfo("ThreadsBlocked", "Ranger blocked threads"), threadsBlocked)
+        .addGauge(new RangerMetricsInfo("ThreadsWaiting", "Ranger waiting threads"), threadsWaiting)
+        .addGauge(new RangerMetricsInfo("ThreadsRemaining", "Ranger remaining threads"), threadsRemaining)
+        .addGauge(new RangerMetricsInfo("ProcessorsAvailable", "Ranger Processors available"), processorsAvailable)
+        .addGauge(new RangerMetricsInfo("SystemLoadAvg", "Ranger System Load Average"), systemLoadAverage);
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsSource.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsSource.java
new file mode 100644
index 000000000..8bf051eba
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/source/RangerMetricsSource.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ranger.metrics.source;
+
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsSource;
+
+public abstract class RangerMetricsSource implements MetricsSource {
+
+    @Override
+    public void getMetrics(MetricsCollector collector, boolean all) {
+        refresh();
+        update(collector, all);
+    }
+
+    /**
+     * Responsibility of this method is to refresh metrics hold by this class.
+     */
+    abstract protected void refresh();
+
+    /**
+     * Responsibility of this method is to update metrics system with latest values of ranger metrics.
+     * @param collector
+     * @param all
+     */
+    abstract protected void update(MetricsCollector collector, boolean all);
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSinkWrapper.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSinkWrapper.java
new file mode 100644
index 000000000..db1923d39
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSinkWrapper.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ranger.metrics.wrapper;
+
+import org.apache.hadoop.metrics2.MetricsSink;
+
+public class RangerMetricsSinkWrapper {
+    private final String name;
+    private final String description;
+    private final MetricsSink sink;
+
+    public RangerMetricsSinkWrapper(String name, String description, MetricsSink sink) {
+        this.name = name;
+        this.description = description;
+        this.sink=sink;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public MetricsSink getSink() {
+        return sink;
+    }
+}
diff --git a/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSourceWrapper.java b/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSourceWrapper.java
new file mode 100644
index 000000000..34dd6e502
--- /dev/null
+++ b/ranger-metrics/src/main/java/org/apache/ranger/metrics/wrapper/RangerMetricsSourceWrapper.java
@@ -0,0 +1,53 @@
+/*
+ * 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.ranger.metrics.wrapper;
+
+import org.apache.hadoop.metrics2.MetricsSource;
+import org.apache.ranger.metrics.source.RangerMetricsSource;
+
+public class RangerMetricsSourceWrapper {
+    private final String              name;
+    private final String              description;
+    private final String              context;
+    private final RangerMetricsSource source;
+
+    public RangerMetricsSourceWrapper(String name, String description, String context, RangerMetricsSource source) {
+        this.name        = name;
+        this.description = description;
+        this.context     = context;
+        this.source      = source;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public MetricsSource getSource() {
+        return source;
+    }
+
+    public String getContext() {
+        return context;
+    }
+}
diff --git a/security-admin/pom.xml b/security-admin/pom.xml
index 2e5e21950..25aaa0e58 100644
--- a/security-admin/pom.xml
+++ b/security-admin/pom.xml
@@ -772,6 +772,11 @@
             <artifactId>ranger-authn</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-metrics</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
     <build>
         <pluginManagement>
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 562467e80..14f937bee 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -38,6 +38,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
@@ -1474,6 +1475,9 @@ public class ServiceDBStore extends AbstractServiceStore {
 				svcDefList.getResultSize(), svcDefList.getSortType(), svcDefList.getSortBy());
 
 	}
+	public List<String> findAllServiceDefNamesHavingContextEnrichers() {
+		return daoMgr.getXXServiceDef().findAllHavingEnrichers();
+	}
 
 	@Override
 	public RangerService createService(RangerService service) throws Exception {
@@ -5268,6 +5272,30 @@ public class ServiceDBStore extends AbstractServiceStore {
         return result;
     }
 
+	/**
+	 * This method returns {@linkplain  java.util.Map map} representing policy count for each service Definition,
+	 * filtered by policy type, if policy type is not valid (null or less than zero) default policy type will
+	 * be used (ie Resource Access)
+	 *
+	 * @param policyType
+	 * @return {@linkplain  java.util.Map map} representing policy count for each service Definition
+	 */
+	public Map<String, Long> getPolicyCountByTypeAndServiceType(Integer policyType) {
+		int type = 0;
+		if ((!Objects.isNull(policyType)) && policyType >= 0) {
+			type = policyType;
+		}
+		return daoMgr.getXXServiceDef().getPolicyCountByType(type);
+	}
+
+	public Map<String, Long> getPolicyCountByDenyConditionsAndServiceDef() {
+		return daoMgr.getXXServiceDef().getPolicyCountByDenyItems();
+	}
+
+	public Map<String, Long> getServiceCountByType() {
+		return daoMgr.getXXServiceDef().getServiceCount();
+	}
+
     public enum METRIC_TYPE {
         USER_GROUP {
             @Override
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index 455ae0bc4..e3790c0f5 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -3171,6 +3171,10 @@ public class XUserMgr extends XUserMgrBase {
 		return vXUserList;
 	}
 
+	public Map<String, Long> getUserCountByRole() {
+		return daoManager.getXXPortalUser().getCountByUserRole();
+	}
+
 	private class ExternalUserCreator implements Runnable {
 		private String userName;
 
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java
index 1787eeae6..18ef22cc7 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java
@@ -20,6 +20,10 @@
 package org.apache.ranger.db;
 
 import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Objects;
 
 import javax.persistence.NoResultException;
 
@@ -149,4 +153,19 @@ public class XXPortalUserDao extends BaseDao<XXPortalUser> {
 		}
 		return xXPortalUser;
 	}
+
+	public Map<String, Long> getCountByUserRole() {
+		Map<String, Long> ret = Collections.emptyMap();
+		List<Object[]> rows = (List<Object[]>) getEntityManager().createNamedQuery("XXPortalUser.getCountByUserRole").getResultList();
+		if (rows != null) {
+			ret = new HashMap<>();
+			for (Object[] row : rows) {
+				if (Objects.nonNull(row) && Objects.nonNull(row[0]) && Objects.nonNull(row[1]) && (!row[0].toString().isEmpty())) {
+					// since group by query will not return empty count field, no need to check
+					ret.put((String) row[0], (Long) row[1]);
+				}
+			}
+		}
+		return ret;
+	}
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXServiceDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXServiceDao.java
index 111c30d0d..ba92c7340 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXServiceDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXServiceDao.java
@@ -148,5 +148,4 @@ public class XXServiceDao extends BaseDao<XXService> {
 			return new ArrayList<>();
 		}
 	}
-
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXServiceDefDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXServiceDefDao.java
index ddf28f2e2..13642417d 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXServiceDefDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXServiceDefDao.java
@@ -24,6 +24,10 @@ import org.apache.ranger.common.db.BaseDao;
 import org.apache.ranger.entity.XXServiceDef;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
 import java.util.Objects;
 
 @Service
@@ -107,4 +111,71 @@ public class XXServiceDefDao extends BaseDao<XXServiceDef> {
 		}
 		return serviceType;
 	}
+
+	/**
+	 * Fetch and return names of service type/ def which are using context enrichers.
+	 * @return {@link java.util.List list} of {@link java.lang.String strings} representing service type/ def
+	 */
+	public List<String> findAllHavingEnrichers() {
+		return getEntityManager().createNamedQuery("XXServiceDef.getNameByHasEnricher", String.class).getResultList();
+	}
+
+	/**
+	 * Fetch and return count of services for each service type/ def
+	 * @return {@link java.util.Map map} representing service type/ def as key and their respective service count as value
+	 */
+	public Map<String, Long> getServiceCount() {
+		Map<String, Long> ret = Collections.emptyMap();
+		List<Object[]> rows = (List<Object[]>) getEntityManager().createNamedQuery("XXServiceDef.getServiceCount").getResultList();
+		if (rows != null) {
+			ret = new HashMap<>();
+			for (Object[] row : rows) {
+				if (Objects.nonNull(row) && Objects.nonNull(row[0]) && Objects.nonNull(row[1]) && (!row[0].toString().isEmpty())) {
+					// since group by query will not return empty count field, no need to check
+					ret.put((String) row[0], (Long) row[1]);
+				}
+			}
+		}
+		return ret;
+	}
+
+	/**
+	 * Fetch and return count of policies for each service type/ def
+	 * @return {@link java.util.Map map} representing service type/ def as key and their respective policy count as value
+	 */
+	public Map<String, Long> getPolicyCountByType(int policyType) {
+		Map<String, Long> ret = Collections.emptyMap();
+		List<Object[]> rows = (List<Object[]>) getEntityManager().createNamedQuery("XXServiceDef.getPolicyCountByType")
+				.setParameter("policyType", policyType)
+				.getResultList();
+		if (rows != null) {
+			ret = new HashMap<>();
+			for (Object[] row : rows) {
+				if (Objects.nonNull(row) && Objects.nonNull(row[0]) && Objects.nonNull(row[1]) && (!row[0].toString().isEmpty())) {
+					// since group by query will not return empty count field, no need to check
+					ret.put((String) row[0], (Long) row[1]);
+				}
+			}
+		}
+		return ret;
+	}
+
+	/**
+	 * Fetch and return count of deny items (conditions) for each service type/ def
+	 * @return {@link java.util.Map map} representing service type/ def as key and their respective deny items (conditions) count as value
+	 */
+	public Map<String, Long> getPolicyCountByDenyItems() {
+		Map<String, Long> ret = Collections.emptyMap();
+		List<Object[]> rows = (List<Object[]>) getEntityManager().createNamedQuery("XXServiceDef.getPolicyCountByDenyItems").getResultList();
+		if (rows != null) {
+			ret = new HashMap<>();
+			for (Object[] row : rows) {
+				if (Objects.nonNull(row) && Objects.nonNull(row[0]) && Objects.nonNull(row[1]) && (!row[0].toString().isEmpty())) {
+					// since group by query will not return empty count field, no need to check
+					ret.put((String) row[0], (Long) row[1]);
+				}
+			}
+		}
+		return ret;
+	}
 }
\ No newline at end of file
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
index 97bc2680a..283d84fe1 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
@@ -122,5 +122,4 @@ public class XXUserDao extends BaseDao<XXUser> {
 		}
 		return users;
 	}
-
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/RangerAdminMetricsWrapper.java b/security-admin/src/main/java/org/apache/ranger/metrics/RangerAdminMetricsWrapper.java
new file mode 100644
index 000000000..b1f1dc8b9
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/RangerAdminMetricsWrapper.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.metrics;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourceContextEnricher;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourceDenyConditions;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourcePolicyMasking;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourcePolicyResourceAccess;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourcePolicyRowFiltering;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourceService;
+import org.apache.ranger.metrics.source.RangerAdminMetricsSourceUserGroup;
+import org.apache.ranger.metrics.wrapper.RangerMetricsSourceWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsWrapper {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerAdminMetricsWrapper.class);
+    private static final String context = "admin";
+
+    private final RangerMetricsSystemWrapper rangerMetricsSystemWrapper = new RangerMetricsSystemWrapper();
+
+    @Autowired
+    private RangerAdminMetricsSourceUserGroup userGroupSource;
+
+    @Autowired
+    private RangerAdminMetricsSourceService serviceSource;
+
+    @Autowired
+    private RangerAdminMetricsSourcePolicyResourceAccess policyResourceAccessSource;
+
+    @Autowired
+    private RangerAdminMetricsSourcePolicyRowFiltering policyRowFilteringSource;
+
+    @Autowired
+    private RangerAdminMetricsSourcePolicyMasking policyMaskingSource;
+
+    @Autowired
+    private RangerAdminMetricsSourceContextEnricher contextEnricherSource;
+
+    @Autowired
+    private RangerAdminMetricsSourceDenyConditions denyConditionSource;
+
+    @PostConstruct
+    public void init() {
+        LOG.info("===>> RangerAdminMetricsWrapper.init()");
+        try {
+            //Source
+            List<RangerMetricsSourceWrapper> sourceWrappers = new ArrayList<>();
+
+            //Source: UserGroup
+            sourceWrappers.add(new RangerMetricsSourceWrapper("UserGroup", "UserGroup metrics in Ranger Admin", context, userGroupSource));
+
+            //Source: Service
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourceService", "Service metrics in Ranger Admin", context, serviceSource));
+
+            //Source: Policy
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourcePolicyResourceAccess", "Resource Policy Access metrics in Ranger Admin", context, policyResourceAccessSource));
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourcePolicyRowFiltering", "Row Filtering Policy Access metrics in Ranger Admin", context, policyRowFilteringSource));
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourcePolicyMasking", "Masking Policy Access metrics in Ranger Admin", context, policyMaskingSource));
+
+            //Source: ContextEnricher
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourceContextEnricher", "Context Enricher metrics in Ranger Admin", context, contextEnricherSource));
+
+            //Source: DenyConditionService
+            sourceWrappers.add(new RangerMetricsSourceWrapper("RangerAdminMetricsSourceDenyConditionService", "Deny Condition in Ranger Admin", context, denyConditionSource));
+
+            rangerMetricsSystemWrapper.init(context, sourceWrappers, Collections.emptyList());
+        } catch (Exception e) {
+            LOG.error("RangerAdminMetricsWrapper: Exception occured while initializing Metric Starter:", e);
+        }
+
+        LOG.info("<<=== RangerAdminMetricsWrapper.init()");
+    }
+
+    public String getRangerMetricsInPrometheusFormat() throws Exception {
+        return rangerMetricsSystemWrapper.getRangerMetricsInPrometheusFormat();
+    }
+
+    public Map<String, Map<String, Object>> getRangerMetrics() {
+        return rangerMetricsSystemWrapper.getRangerMetrics();
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/RangerMetricsFetcher.java b/security-admin/src/main/java/org/apache/ranger/metrics/RangerMetricsFetcher.java
new file mode 100644
index 000000000..867b70e91
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/RangerMetricsFetcher.java
@@ -0,0 +1,124 @@
+/*
+ * 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.ranger.metrics;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.biz.XUserMgr;
+import org.apache.ranger.common.RangerConstants;
+import org.apache.ranger.service.XGroupService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional(propagation = Propagation.REQUIRES_NEW)
+public class RangerMetricsFetcher {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerMetricsFetcher.class);
+
+    @Autowired
+    private XUserMgr xUserMgr;
+
+    @Autowired
+    private ServiceDBStore svcStore;
+
+    @Autowired
+    private XGroupService groupService;
+
+    public Long getGroupCount() {
+        return groupService.getAllGroupCount();
+    }
+    public Map<String, Long> getUserMetrics() {
+
+        Map<String, Long> ret = new HashMap<>();
+        long total = 0l;
+        for (Map.Entry<String, Long> entry : xUserMgr.getUserCountByRole().entrySet()) {
+            String role = entry.getKey();
+            switch (role) {
+                case RangerConstants.ROLE_SYS_ADMIN:         ret.put("SysAdmin", entry.getValue());        break;
+                case RangerConstants.ROLE_ADMIN_AUDITOR:     ret.put("AdminAuditor", entry.getValue());    break;
+                case RangerConstants.ROLE_KEY_ADMIN:         ret.put("KeyAdmin", entry.getValue());        break;
+                case RangerConstants.ROLE_KEY_ADMIN_AUDITOR: ret.put("KeyAdminAuditor", entry.getValue()); break;
+                case RangerConstants.ROLE_USER:              ret.put("User", entry.getValue());            break;
+                default: LOG.warn("===>> RangerMetricsFetcher.getUserMetrics(): invalid role [{}] type.", role);break;
+            }
+            total += entry.getValue().longValue();
+        }
+        ret.put("Total", total);
+
+        return ret;
+    }
+
+    public Map<String, Long> getRangerServiceMetrics() {
+        Map<String, Long> ret = new HashMap<>();
+        long total = 0l;
+        for (Map.Entry<String, Long> entry : svcStore.getServiceCountByType().entrySet()) {
+            ret.put(entry.getKey(), entry.getValue());
+            total += entry.getValue().longValue();
+        }
+        ret.put("Total", total);
+
+        return ret;
+    }
+
+    public Map<String, Long> getPolicyMetrics(Integer policyType) {
+        Objects.requireNonNull(policyType, "Policy type must not be null to get policy metrics.");
+
+        Map<String, Long> ret = new HashMap<>();
+        long total = 0l;
+        for (Map.Entry<String, Long> entry : svcStore.getPolicyCountByTypeAndServiceType(policyType).entrySet()) {
+            ret.put(entry.getKey(), entry.getValue());
+            total += entry.getValue().longValue();
+        }
+        ret.put("Total", total);
+
+        return ret;
+    }
+
+    public Map<String, Long> getDenyConditionsMetrics() {
+        Map<String, Long> ret = new HashMap<>();
+        long total = 0l;
+        for (Map.Entry<String, Long> entry : svcStore.getPolicyCountByDenyConditionsAndServiceDef().entrySet()) {
+            ret.put(entry.getKey(), entry.getValue());
+            total += entry.getValue().longValue();
+        }
+        ret.put("Total", total);
+
+        return ret;
+    }
+
+    public Map<String, Long> getContextEnrichersMetrics() {
+        Map<String, Long> ret = new HashMap<>();
+        long total = 0l;
+        for (String serviceDef : svcStore.findAllServiceDefNamesHavingContextEnrichers()) {
+            ret.put(serviceDef, 1l);
+            total++;
+        }
+        ret.put("Total", total);
+
+        return ret;
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceBase.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceBase.java
new file mode 100644
index 000000000..effa98c0f
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceBase.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsRecordBuilder;
+import org.apache.ranger.metrics.RangerMetricsInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class RangerAdminMetricsSourceBase extends RangerMetricsSource {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerAdminMetricsSourceBase.class);
+
+    final Map<String, Long> metricsMap = new HashMap<>();
+
+    final String context;
+    final String record;
+
+    public RangerAdminMetricsSourceBase(String context, String record) {
+        this.context = context;
+        this.record  = record;
+    }
+
+    @Override
+    protected void update(MetricsCollector collector, boolean all) {
+        MetricsRecordBuilder builder = collector.addRecord(this.record)
+        .setContext(this.context);
+
+        for (String key: metricsMap.keySet() ) {
+            builder.addGauge(new RangerMetricsInfo(key, ""), metricsMap.get(key));
+        }
+    }
+
+    protected void addMetricEntry(String prefix, String suffix, Long value) {
+        if (Objects.nonNull(prefix)) {
+            if (Objects.isNull(suffix) || suffix.isEmpty() || suffix.equalsIgnoreCase("Total")) {
+                metricsMap.put(prefix, value);
+            } else {
+                metricsMap.put(prefix + (suffix).toUpperCase(), value);
+            }
+        } else {
+            LOG.warn("===>> RangerAdminMetricsSourceBase.addMetricEntry(): Metrics prefix can not be null.");
+        }
+    }
+
+    protected void addMetricEntries(String prefix, Map<String, Long> metrics) {
+        for (Map.Entry<String, Long> entry : metrics.entrySet()) {
+            addMetricEntry(prefix, entry.getKey(), entry.getValue());
+        }
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceContextEnricher.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceContextEnricher.java
new file mode 100644
index 000000000..69d54d64b
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceContextEnricher.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourceContextEnricher extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourceContextEnricher() {
+        super("admin", "ContextEnrichers");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> contextEnrichersMetrics = rangerMetricsFetcher.getContextEnrichersMetrics();
+        addMetricEntries("ContextEnricherCount", contextEnrichersMetrics);
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceDenyConditions.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceDenyConditions.java
new file mode 100644
index 000000000..22095f2f7
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceDenyConditions.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourceDenyConditions extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourceDenyConditions() {
+        super("admin", "DenyConditions");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> denyConditionsMetrics = rangerMetricsFetcher.getDenyConditionsMetrics();
+        addMetricEntries("DenyConditionCount", denyConditionsMetrics);
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyMasking.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyMasking.java
new file mode 100644
index 000000000..7df64c6f1
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyMasking.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourcePolicyMasking extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourcePolicyMasking() {
+        super("admin", "Policy");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> maskingPolicyMetrics = rangerMetricsFetcher.getPolicyMetrics(RangerPolicy.POLICY_TYPE_DATAMASK);
+        addMetricEntries("MaskingCount", maskingPolicyMetrics);
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyResourceAccess.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyResourceAccess.java
new file mode 100644
index 000000000..4a777f86d
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyResourceAccess.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourcePolicyResourceAccess extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourcePolicyResourceAccess() {
+        super("admin", "Policy");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> accessPolicyMetrics = rangerMetricsFetcher.getPolicyMetrics(RangerPolicy.POLICY_TYPE_ACCESS);
+        addMetricEntries("ResourceAccessCount", accessPolicyMetrics);
+    }
+
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyRowFiltering.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyRowFiltering.java
new file mode 100644
index 000000000..af6eb502a
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourcePolicyRowFiltering.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourcePolicyRowFiltering extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourcePolicyRowFiltering() {
+        super("admin", "Policy");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> rowFilteringPolicyMetrics = rangerMetricsFetcher.getPolicyMetrics(RangerPolicy.POLICY_TYPE_ROWFILTER);
+        addMetricEntries("RowFilteringCount", rowFilteringPolicyMetrics);
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceService.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceService.java
new file mode 100644
index 000000000..23750e672
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceService.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourceService extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+
+    public RangerAdminMetricsSourceService() {
+        super("admin", "Service");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> serviceMetrics = rangerMetricsFetcher.getRangerServiceMetrics();
+        addMetricEntries("ServiceCount", serviceMetrics);
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceUserGroup.java b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceUserGroup.java
new file mode 100644
index 000000000..2ed6f9db6
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/metrics/source/RangerAdminMetricsSourceUserGroup.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ranger.metrics.source;
+
+import java.util.Map;
+
+import org.apache.ranger.metrics.RangerMetricsFetcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RangerAdminMetricsSourceUserGroup extends RangerAdminMetricsSourceBase {
+
+    @Autowired
+    private RangerMetricsFetcher rangerMetricsFetcher;
+    public RangerAdminMetricsSourceUserGroup() {
+        super("admin", "UserGroup");
+    }
+
+    @Override
+    protected void refresh() {
+        Map<String, Long> userGroupMetrics = rangerMetricsFetcher.getUserMetrics();
+
+        addMetricEntries("UserCount", userGroupMetrics);
+        addMetricEntry("GroupCount", "", rangerMetricsFetcher.getGroupCount());
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/MetricsREST.java b/security-admin/src/main/java/org/apache/ranger/rest/MetricsREST.java
index e8e67c91d..5b3638b98 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/MetricsREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/MetricsREST.java
@@ -27,7 +27,9 @@ import java.util.Map;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 
+import org.apache.ranger.metrics.RangerAdminMetricsWrapper;
 import org.apache.ranger.plugin.model.RangerMetrics;
 import org.apache.ranger.util.RangerMetricsUtil;
 import org.slf4j.Logger;
@@ -53,6 +55,9 @@ public class MetricsREST {
     @Autowired
     RangerMetricsUtil jvmMetricUtil;
 
+    @Autowired
+    private RangerAdminMetricsWrapper rangerAdminMetricsWrapper;
+
     @GET
     @Path("/status")
     @Produces({ "application/json" })
@@ -77,4 +82,45 @@ public class MetricsREST {
 
         return new RangerMetrics(jvm);
     }
+
+    @GET
+    @Path("/prometheus")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String getMetricsPrometheus() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("MetricsREST.getMetricsPrometheus() ===>>");
+        }
+        String ret = "";
+        try {
+            ret = rangerAdminMetricsWrapper.getRangerMetricsInPrometheusFormat();
+        } catch (Exception e) {
+            LOG.error("MetricsREST.getMetricsPrometheus(): Exception occurred while getting metric.", e);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("MetricsREST.getMetricsPrometheus() <<=== {}", ret);
+        }
+        return ret;
+    }
+
+    @GET
+    @Path("/json")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Map<String, Map<String, Object>> getMetricsJson() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("MetricsREST.getMetricsJson() ===>>");
+        }
+
+        Map<String, Map<String, Object>> ret = null;
+        try {
+            ret = rangerAdminMetricsWrapper.getRangerMetrics();
+        } catch (Exception e) {
+            LOG.error("MetricsREST.getMetricsJson(): Exception occurred while getting metric.", e);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("MetricsREST.getMetricsJson() <<=== {}", ret);
+        }
+        return ret;
+    }
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java b/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
index 27651f312..650760304 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
@@ -281,4 +281,8 @@ public class XGroupService extends XGroupServiceBase<XXGroup, VXGroup> {
 	public Map<Long, String> getXXGroupIdNameMap() {
 		return daoManager.getXXGroup().getAllGroupIdNames();
 	}
+
+	public Long getAllGroupCount() {
+		return daoManager.getXXGroup().getAllCount();
+	}
 }
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index 1762d60c6..412d0b10a 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -455,13 +455,29 @@
 	</named-query>
 
     <named-query name="XXServiceDef.findServiceDefNameByServiceName">
-                <query>select obj.name from XXServiceDef obj, XXService serviceObj where obj.id = serviceObj.type and serviceObj.name = :name</query>
-        </named-query>
+        <query>select obj.name from XXServiceDef obj, XXService serviceObj where obj.id = serviceObj.type and serviceObj.name = :name</query>
+	</named-query>
 
 	<named-query name="XXServiceDef.findServiceDefNameByServiceId">
 		<query>select obj.name from XXServiceDef obj, XXService serviceObj where obj.id = serviceObj.type and serviceObj.id = :id</query>
 	</named-query>
 
+	<named-query name="XXServiceDef.getNameByHasEnricher">
+		<query>SELECT DISTINCT(xsd.name) FROM XXServiceDef xsd, XXContextEnricherDef xced WHERE xsd.id = xced.defId</query>
+	</named-query>
+
+	<named-query name="XXServiceDef.getServiceCount">
+		<query>SELECT xsd.name, COUNT(xs.id) FROM XXService xs, XXServiceDef xsd WHERE xs.type = xsd.id GROUP BY xsd.name</query>
+	</named-query>
+
+	<named-query name="XXServiceDef.getPolicyCountByType">
+		<query>SELECT xsd.name, COUNT(xp.id) FROM XXPolicy xp, XXService xs, XXServiceDef xsd WHERE xs.id = xp.service AND xs.type = xsd.id AND xp.policyType = :policyType GROUP BY xsd.name</query>
+	</named-query>
+
+	<named-query name="XXServiceDef.getPolicyCountByDenyItems">
+	    <query>SELECT xsd.name, COUNT(xp.id) FROM XXPolicy xp, XXService xs, XXServiceDef xsd WHERE xp.policyText LIKE '%denyPolicyItems":[{%' AND xp.service = xs.id AND xsd.id = xs.type GROUP by xsd.name</query>
+	</named-query>
+
 	<!-- XXResourceDef -->
 	<named-query name="XXResourceDef.findByNameAndDefId">
 		<query>select obj from XXResourceDef obj where obj.name = :name and obj.defId = :defId order by obj.level</query>
@@ -1210,6 +1226,10 @@
 		</query>
 	</named-query>
 
+	<named-query name="XXPortalUser.getCountByUserRole">
+		<query>SELECT xpur.userRole, COUNT(xpu.id) FROM XXPortalUser xpu, XXPortalUserRole xpur WHERE xpur.userId = xpu.id GROUP BY xpur.userRole</query>
+	</named-query>
+
 	<named-query name="XXPortalUser.findAllXPortalUser">
 		<query>SELECT xxPortalUser FROM XXPortalUser xxPortalUser
 		</query>
@@ -2015,5 +2035,4 @@
 	<named-query name="XXPolicy.findByZoneId">
 		<query>select obj from XXPolicy obj where obj.zoneId = :zoneId</query>
 	</named-query>
-
 </entity-mappings>
diff --git a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
index 646da9d8c..b92a2fc7e 100644
--- a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
+++ b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
@@ -49,7 +49,7 @@ http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
 	<security:http pattern="/service/tags/download/*" security="none"/>
 	<security:http pattern="/service/roles/download/*" security="none"/>
 	<security:http pattern="/service/xusers/download/*" security="none"/>
-	<security:http pattern="/service/metrics/status" security="none" />
+	<security:http pattern="/service/metrics/**" security="none" />
 	<security:http disable-url-rewriting="true" use-expressions="true" create-session="always" entry-point-ref="authenticationProcessingFilterEntryPoint">
 		<csrf disabled="true"/>
 		<security:headers>
diff --git a/security-admin/src/main/resources/hadoop-metrics2.properties b/security-admin/src/main/resources/hadoop-metrics2.properties
new file mode 100644
index 000000000..8e8eb9ae8
--- /dev/null
+++ b/security-admin/src/main/resources/hadoop-metrics2.properties
@@ -0,0 +1,54 @@
+#
+#   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.
+#
+# syntax: [prefix].[source|sink].[instance].[options]
+# See javadoc of package-info.java for org.apache.hadoop.metrics2 for details
+
+# syntax: [prefix].[source|sink].[instance].[options]
+# See javadoc of package-info.java for org.apache.hadoop.metrics2 for details
+
+# default sampling period, in seconds
+*.period=30
+#*.periodMillis=100
+
+####### File Sink >>>>>> CONF
+# prefix=* && context=*
+#*.sink.file.class=org.apache.hadoop.metrics2.sink.FileSink
+#*.sink.file.filename=${ranger.admin.log.dir}/${ranger.admin.metrics.file}-all-metrics.out
+
+# prefix=ranger && context=*
+#ranger.sink.file.filename=${ranger.admin.log.dir}/${ranger.admin.metrics.file}-metrics.out
+
+# prefix=ranger && context=admin
+#ranger.sink.file_auth.class=org.apache.hadoop.metrics2.sink.FileSink
+#ranger.sink.file_auth.context=admin
+#rangar.sink.file_auth.filename=${ranger.admin.log.dir}/${ranger.admin.metrics.file}-metrics.out
+
+####### Graphite Sink >>>>>> CONF
+## prefix=* && context=*
+#*.sink.graphite.class=org.apache.hadoop.metrics2.sink.GraphiteSink
+#*.sink.graphite.server_host=127.0.0.1
+#*.sink.graphite.server_port=2003
+#*.sink.graphite.metrics_prefix=ranger
+
+## prefix=raz && context=auth
+#raz.sink.graphite_razcntx.class=org.apache.hadoop.metrics2.sink.GraphiteSink
+#raz.sink.graphite_razcntx.server_host=127.0.0.1
+#raz.sink.graphite_razcntx.server_port=2003
+#raz.sink.graphite_razcntx.metrics_prefix=ranger
+#raz.sink.graphite_razcntx.context=admin
+####### Graphite Sink <<<<<< CONF
+