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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0fedbdd  CLOUDSTACK-9998: Prometheus Exporter for CloudStack (#2287)
0fedbdd is described below

commit 0fedbdd7a90113b7a631b9a4e98fff6b37026627
Author: Rohit Yadav <[email protected]>
AuthorDate: Wed Oct 11 17:24:22 2017 +0530

    CLOUDSTACK-9998: Prometheus Exporter for CloudStack (#2287)
    
    This implements a CloudStack Prometheus exporter as a plugin, that serves
    metrics on a HTTP port.
    
    New global settings:
    
    1. prometheus.exporter.enable - (default: false), Enable the prometheus
    exporter plugin, management server restart needed.
    2. prometheus.exporter.port - (default: 9595), The prometheus exporter
    server port.
    3. prometheus.exporter.allowed.ips - (default: 127.0.0.1), List of comma
    separated prometheus server ips (with no spaces) that should be allowed to
    access the URLs.
    
    The following list  of  metrics are provided  per pop (zone)  with  the 
exporter:
    • Per host:
    o CPU cores:  used, total
    o CPU usage:  used, total (in MHz)
    o Memory  usage:  used, total (in MiBs)
    o Total VMs running on  the host
    • CPU cores:  allocated (per  zone)
    • CPU usage:  allocated (per  zone, in  MHz)
    • Memory  usage:  allocated (per  zone, in  MiBs)
    • Hosts:  online, offline,  total
    • VMs: in all states -- starting, running, stopping, stopped, destroyed,
           expunging, migrating,  error, unknown
    • Volumes:  ready,  destroyed,  total
    • Primary Storage Pool: (Disk size) used, allocated,  unallocated,  total 
(in GiBs)
    • Secondary Storage Pool: (Disk size) used, allocated,  unallocated,  total 
(in GiBs)
    • Private IPs:  allocated,  total
    • Public  IPs:  allocated,  total
    • Shared  Network IPs:  allocated,  total
    • VLANs:  allocated,  total
    
    Additional metrics for the environment:
    • Summed  domain  (level=1) limit for CPU cores
    • Summed  domain  (level=1) limit for memory/ram
    
    Signed-off-by: Rohit Yadav <[email protected]>
---
 api/src/com/cloud/storage/ImageStore.java          |   7 +
 client/pom.xml                                     |   5 +
 .../schema/src/com/cloud/vm/dao/VMInstanceDao.java |   2 +
 .../src/com/cloud/vm/dao/VMInstanceDaoImpl.java    |  15 +
 .../storage/image/store/ImageStoreImpl.java        |   5 +
 plugins/integrations/prometheus/pom.xml            |  48 ++
 .../cloudstack/prometheus/module.properties        |  18 +
 .../prometheus/spring-prometheus-context.xml       |  27 +
 .../cloudstack/metrics/PrometheusExporter.java     |  28 +-
 .../cloudstack/metrics/PrometheusExporterImpl.java | 612 +++++++++++++++++++++
 .../metrics/PrometheusExporterServer.java          |  33 ++
 .../metrics/PrometheusExporterServerImpl.java      | 118 ++++
 plugins/pom.xml                                    |   1 +
 13 files changed, 895 insertions(+), 24 deletions(-)

diff --git a/api/src/com/cloud/storage/ImageStore.java 
b/api/src/com/cloud/storage/ImageStore.java
index ec693c4..c019b17 100644
--- a/api/src/com/cloud/storage/ImageStore.java
+++ b/api/src/com/cloud/storage/ImageStore.java
@@ -41,4 +41,11 @@ public interface ImageStore extends Identity, 
InternalIdentity {
      * @return data store protocol
      */
     String getProtocol();
+
+    /**
+     *
+     * @return uri
+     */
+    String getUrl();
+
 }
diff --git a/client/pom.xml b/client/pom.xml
index 3a0c5a5..ae0fcaa 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -414,6 +414,11 @@
       <artifactId>cloud-plugin-database-quota</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-integrations-prometheus-exporter</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java 
b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java
index 8d457fa..3c5024b 100644
--- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java
+++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java
@@ -116,6 +116,8 @@ public interface VMInstanceDao extends 
GenericDao<VMInstanceVO, Long>, StateDao<
 
     Long countRunningByAccount(long accountId);
 
+    Long countByZoneAndState(long zoneId, State state);
+
     List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long networkId, 
VirtualMachine.Type... types);
 
     /**
diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java 
b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
index df5e60e..7065350 100644
--- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
+++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
@@ -87,6 +87,7 @@ public class VMInstanceDaoImpl extends 
GenericDaoBase<VMInstanceVO, Long> implem
     protected GenericSearchBuilder<VMInstanceVO, Long> 
FindIdsOfVirtualRoutersByAccount;
     protected GenericSearchBuilder<VMInstanceVO, Long> CountActiveByHost;
     protected GenericSearchBuilder<VMInstanceVO, Long> CountRunningByAccount;
+    protected GenericSearchBuilder<VMInstanceVO, Long> CountByZoneAndState;
     protected SearchBuilder<VMInstanceVO> NetworkTypeSearch;
     protected GenericSearchBuilder<VMInstanceVO, String> 
DistinctHostNameSearch;
     protected SearchBuilder<VMInstanceVO> HostAndStateSearch;
@@ -242,6 +243,12 @@ public class VMInstanceDaoImpl extends 
GenericDaoBase<VMInstanceVO, Long> implem
         CountRunningByAccount.and("state", 
CountRunningByAccount.entity().getState(), SearchCriteria.Op.EQ);
         CountRunningByAccount.done();
 
+        CountByZoneAndState = createSearchBuilder(Long.class);
+        CountByZoneAndState.select(null, Func.COUNT, null);
+        CountByZoneAndState.and("zone", 
CountByZoneAndState.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        CountByZoneAndState.and("state", 
CountByZoneAndState.entity().getState(), SearchCriteria.Op.EQ);
+        CountByZoneAndState.done();
+
         HostAndStateSearch = createSearchBuilder();
         HostAndStateSearch.and("host", 
HostAndStateSearch.entity().getHostId(), Op.EQ);
         HostAndStateSearch.and("states", 
HostAndStateSearch.entity().getState(), Op.IN);
@@ -719,6 +726,14 @@ public class VMInstanceDaoImpl extends 
GenericDaoBase<VMInstanceVO, Long> implem
     }
 
     @Override
+    public Long countByZoneAndState(long zoneId, State state) {
+        SearchCriteria<Long> sc = CountByZoneAndState.create();
+        sc.setParameters("zone", zoneId);
+        sc.setParameters("state", state);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
     public List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long 
networkId, VirtualMachine.Type... types) {
         if (NetworkTypeSearch == null) {
 
diff --git 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index 182a8ec..41ce5a2 100644
--- 
a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ 
b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -181,6 +181,11 @@ public class ImageStoreImpl implements ImageStoreEntity {
     }
 
     @Override
+    public String getUrl() {
+        return imageDataStoreVO.getUrl();
+    }
+
+    @Override
     public DataStoreTO getTO() {
         DataStoreTO to = getDriver().getStoreTO(this);
         if (to == null) {
diff --git a/plugins/integrations/prometheus/pom.xml 
b/plugins/integrations/prometheus/pom.xml
new file mode 100644
index 0000000..66dbebb
--- /dev/null
+++ b/plugins/integrations/prometheus/pom.xml
@@ -0,0 +1,48 @@
+<!--
+  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>cloud-plugin-integrations-prometheus-exporter</artifactId>
+  <name>Apache CloudStack Plugin - Prometheus Exporter</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.11.0.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-schema</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git 
a/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/module.properties
 
b/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/module.properties
new file mode 100644
index 0000000..cb70ec8
--- /dev/null
+++ 
b/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/module.properties
@@ -0,0 +1,18 @@
+# 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.
+name=prometheus
+parent=api
diff --git 
a/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
 
b/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
new file mode 100644
index 0000000..06fb92c
--- /dev/null
+++ 
b/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
@@ -0,0 +1,27 @@
+<!--
+  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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd";>
+
+    <bean id="prometheusExporterServer" 
class="org.apache.cloudstack.metrics.PrometheusExporterServerImpl" />
+    <bean id="prometheusExporter" 
class="org.apache.cloudstack.metrics.PrometheusExporterImpl" />
+
+</beans>
diff --git a/api/src/com/cloud/storage/ImageStore.java 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporter.java
similarity index 60%
copy from api/src/com/cloud/storage/ImageStore.java
copy to 
plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporter.java
index ec693c4..6361f0e 100644
--- a/api/src/com/cloud/storage/ImageStore.java
+++ 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporter.java
@@ -14,31 +14,11 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-package com.cloud.storage;
+package org.apache.cloudstack.metrics;
 
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
+public interface PrometheusExporter {
 
-public interface ImageStore extends Identity, InternalIdentity {
+    void updateMetrics();
 
-    /**
-     * @return name of the object store.
-     */
-    String getName();
-
-    /**
-     * @return availability zone.
-     */
-    Long getDataCenterId();
-
-    /**
-     * @return object store provider name
-     */
-    String getProviderName();
-
-    /**
-     *
-     * @return data store protocol
-     */
-    String getProtocol();
+    String getMetrics();
 }
diff --git 
a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
new file mode 100644
index 0000000..a51b296
--- /dev/null
+++ 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
@@ -0,0 +1,612 @@
+// 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.cloudstack.metrics;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.DomainJoinDao;
+import com.cloud.api.query.dao.HostJoinDao;
+import com.cloud.api.query.dao.StoragePoolJoinDao;
+import com.cloud.api.query.vo.DomainJoinVO;
+import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.StoragePoolJoinVO;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.capacity.dao.CapacityDaoImpl;
+import com.cloud.configuration.Resource;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.storage.ImageStore;
+import com.cloud.storage.StorageStats;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.common.base.Strings;
+
+public class PrometheusExporterImpl extends ManagerBase implements 
PrometheusExporter, Manager {
+    private static final Logger LOG = 
Logger.getLogger(PrometheusExporterImpl.class);
+
+    private static final String USED = "used";
+    private static final String ALLOCATED = "allocated";
+    private static final String UNALLOCATED = "unallocated";
+    private static final String TOTAL = "total";
+    private static final String ONLINE = "online";
+    private static final String OFFLINE = "offline";
+
+    private static List<Item> metricsItems = new ArrayList<>();
+
+    @Inject
+    private DataCenterDao dcDao;
+    @Inject
+    private HostJoinDao hostJoinDao;
+    @Inject
+    private VMInstanceDao vmDao;
+    @Inject
+    private VolumeDao volumeDao;
+    @Inject
+    private IPAddressDao publicIpAddressDao;
+    @Inject
+    private DataCenterIpAddressDao privateIpAddressDao;
+    @Inject
+    private CapacityDao capacityDao;
+    @Inject
+    private StoragePoolJoinDao storagePoolJoinDao;
+    @Inject
+    private ImageStoreDao imageStoreDao;
+    @Inject
+    private DomainJoinDao domainDao;
+    @Inject
+    private AlertManager alertManager;
+
+    public PrometheusExporterImpl() {
+        super();
+    }
+
+    private void addHostMetrics(final List<Item> metricsList, final long dcId, 
final String zoneName, final String zoneUuid) {
+        int total = 0;
+        int up = 0;
+        int down = 0;
+        for (final HostJoinVO host : hostJoinDao.listAll()) {
+            if (host == null || host.getType() != Host.Type.Routing || 
host.getZoneId() != dcId) {
+                continue;
+            }
+            total++;
+            if (host.getStatus() == Status.Up) {
+                up++;
+            } else if (host.getStatus() == Status.Disconnected || 
host.getStatus() == Status.Down) {
+                down++;
+            }
+
+            final String cpuFactor = 
String.valueOf(CapacityManager.CpuOverprovisioningFactor.valueIn(host.getClusterId()));
+            final CapacityVO cpuCapacity = 
capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU);
+            metricsList.add(new ItemHostCpu(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, USED, 
cpuCapacity.getUsedCapacity()));
+            metricsList.add(new ItemHostCpu(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, TOTAL, 
cpuCapacity.getTotalCapacity()));
+
+            final String memoryFactor = 
String.valueOf(CapacityManager.MemOverprovisioningFactor.valueIn(host.getClusterId()));
+            final CapacityVO memCapacity = 
capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
+            metricsList.add(new ItemHostMemory(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, USED, 
memCapacity.getUsedCapacity()));
+            metricsList.add(new ItemHostMemory(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, 
TOTAL, memCapacity.getTotalCapacity()));
+
+            metricsList.add(new ItemHostVM(zoneName, zoneUuid, host.getName(), 
host.getUuid(), host.getPrivateIpAddress(), 
vmDao.listByHostId(host.getId()).size()));
+
+            final CapacityVO coreCapacity = 
capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU_CORE);
+            if (coreCapacity != null) {
+                metricsList.add(new ItemVMCore(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), USED, 
coreCapacity.getUsedCapacity()));
+                metricsList.add(new ItemVMCore(zoneName, zoneUuid, 
host.getName(), host.getUuid(), host.getPrivateIpAddress(), TOTAL, 
coreCapacity.getTotalCapacity()));
+            }
+        }
+
+        final List<CapacityDaoImpl.SummedCapacity> cpuCapacity = 
capacityDao.findCapacityBy((int) Capacity.CAPACITY_TYPE_CPU, dcId, null, null);
+        if (cpuCapacity != null && cpuCapacity.size() > 0) {
+            metricsList.add(new ItemHostCpu(zoneName, zoneUuid, null, null, 
null, null, ALLOCATED, cpuCapacity.get(0).getAllocatedCapacity() != null ? 
cpuCapacity.get(0).getAllocatedCapacity() : 0));
+        }
+
+        final List<CapacityDaoImpl.SummedCapacity> memCapacity = 
capacityDao.findCapacityBy((int) Capacity.CAPACITY_TYPE_MEMORY, dcId, null, 
null);
+        if (memCapacity != null && memCapacity.size() > 0) {
+            metricsList.add(new ItemHostMemory(zoneName, zoneUuid, null, null, 
null, null, ALLOCATED, memCapacity.get(0).getAllocatedCapacity() != null ? 
memCapacity.get(0).getAllocatedCapacity() : 0));
+        }
+
+        final List<CapacityDaoImpl.SummedCapacity> coreCapacity = 
capacityDao.findCapacityBy((int) Capacity.CAPACITY_TYPE_CPU_CORE, dcId, null, 
null);
+        if (coreCapacity != null && coreCapacity.size() > 0) {
+            metricsList.add(new ItemVMCore(zoneName, zoneUuid, null, null, 
null, ALLOCATED, coreCapacity.get(0).getAllocatedCapacity() != null ? 
coreCapacity.get(0).getAllocatedCapacity() : 0));
+        }
+
+        metricsList.add(new ItemHost(zoneName, zoneUuid, ONLINE, up));
+        metricsList.add(new ItemHost(zoneName, zoneUuid, OFFLINE, down));
+        metricsList.add(new ItemHost(zoneName, zoneUuid, TOTAL, total));
+    }
+
+    private void addVMMetrics(final List<Item> metricsList, final long dcId, 
final String zoneName, final String zoneUuid) {
+        for (final State state : State.values()) {
+            final Long count = vmDao.countByZoneAndState(dcId, state);
+            if (count == null) {
+                continue;
+            }
+            metricsList.add(new ItemVM(zoneName, zoneUuid, 
state.name().toLowerCase(), count));
+        }
+    }
+
+    private void addVolumeMetrics(final List<Item> metricsList, final long 
dcId, final String zoneName, final String zoneUuid) {
+        int total = 0;
+        int ready = 0;
+        int destroyed = 0;
+        for (final VolumeVO volume : volumeDao.findByDc(dcId)) {
+            if (volume == null) {
+                continue;
+            }
+            total++;
+            if (volume.getState() == Volume.State.Ready) {
+                ready++;
+            } else if (volume.getState() == Volume.State.Destroy) {
+                destroyed++;
+            }
+        }
+        metricsList.add(new ItemVolume(zoneName, zoneUuid, 
Volume.State.Ready.name().toLowerCase(), ready));
+        metricsList.add(new ItemVolume(zoneName, zoneUuid, 
Volume.State.Destroy.name().toLowerCase(), destroyed));
+        metricsList.add(new ItemVolume(zoneName, zoneUuid, TOTAL, total));
+    }
+
+    private void addStorageMetrics(final List<Item> metricsList, final long 
dcId, final String zoneName, final String zoneUuid) {
+        for (final StoragePoolJoinVO pool: storagePoolJoinDao.listAll()) {
+            if (pool == null || pool.getZoneId() != dcId) {
+                continue;
+            }
+            final String poolName = pool.getName();
+            final String poolPath = pool.getHostAddress() + ":" + 
pool.getPath();
+
+            long usedCapacity = 0L;
+            long allocatedCapacity = pool.getUsedCapacity() + 
pool.getReservedCapacity();
+            final long totalCapacity = pool.getCapacityBytes();
+
+            final StorageStats stats = 
ApiDBUtils.getStoragePoolStatistics(pool.getId());
+            if (stats != null) {
+                usedCapacity = stats.getByteUsed();
+            }
+
+            final BigDecimal poolOverProvisioningFactor = 
BigDecimal.valueOf(CapacityManager.StorageOverprovisioningFactor.valueIn(pool.getId()));
+            final String poolFactor = poolOverProvisioningFactor.toString();
+
+            metricsList.add(new ItemPool(zoneName, zoneUuid, poolName, 
poolPath, "primary", poolFactor, USED, usedCapacity));
+            metricsList.add(new ItemPool(zoneName, zoneUuid, poolName, 
poolPath, "primary", poolFactor, ALLOCATED, allocatedCapacity));
+            metricsList.add(new ItemPool(zoneName, zoneUuid, poolName, 
poolPath, "primary", poolFactor, UNALLOCATED, 
poolOverProvisioningFactor.multiply(BigDecimal.valueOf(totalCapacity)).longValue()
 - allocatedCapacity));
+            metricsList.add(new ItemPool(zoneName, zoneUuid, poolName, 
poolPath, "primary", poolFactor, TOTAL, totalCapacity));
+        }
+
+        for (final ImageStore imageStore : imageStoreDao.findByScope(new 
ZoneScope(dcId))) {
+            final StorageStats stats = 
ApiDBUtils.getSecondaryStorageStatistics(imageStore.getId());
+            metricsList.add(new ItemPool(zoneName, zoneUuid, 
imageStore.getName(), imageStore.getUrl(), "secondary", null, USED, stats != 
null ? stats.getByteUsed() : 0));
+            metricsList.add(new ItemPool(zoneName, zoneUuid, 
imageStore.getName(), imageStore.getUrl(), "secondary", null, TOTAL, stats != 
null ? stats.getCapacityBytes() : 0));
+        }
+    }
+
+    private void addIpAddressMetrics(final List<Item> metricsList, final long 
dcId, final String zoneName, final String zoneUuid) {
+        metricsList.add(new ItemPrivateIp(zoneName, zoneUuid, ALLOCATED, 
privateIpAddressDao.countIPs(dcId, true)));
+        metricsList.add(new ItemPrivateIp(zoneName, zoneUuid, TOTAL, 
privateIpAddressDao.countIPs(dcId, false)));
+        metricsList.add(new ItemPublicIp(zoneName, zoneUuid, ALLOCATED, 
publicIpAddressDao.countIPsForNetwork(dcId, true, 
Vlan.VlanType.VirtualNetwork)));
+        metricsList.add(new ItemPublicIp(zoneName, zoneUuid, TOTAL, 
publicIpAddressDao.countIPsForNetwork(dcId, false, 
Vlan.VlanType.VirtualNetwork)));
+        metricsList.add(new ItemSharedNetworkIp(zoneName, zoneUuid, ALLOCATED, 
publicIpAddressDao.countIPsForNetwork(dcId, true, 
Vlan.VlanType.DirectAttached)));
+        metricsList.add(new ItemSharedNetworkIp(zoneName, zoneUuid, TOTAL, 
publicIpAddressDao.countIPsForNetwork(dcId, false, 
Vlan.VlanType.DirectAttached)));
+    }
+
+    private void addVlanMetrics(final List<Item> metricsList, final long dcId, 
final String zoneName, final String zoneUuid) {
+        metricsList.add(new ItemVlan(zoneName, zoneUuid, ALLOCATED, 
dcDao.countZoneVlans(dcId, true)));
+        metricsList.add(new ItemVlan(zoneName, zoneUuid, TOTAL, 
dcDao.countZoneVlans(dcId, false)));
+    }
+
+    private void addDomainLimits(final List<Item> metricsList) {
+        Long totalCpuLimit = 0L;
+        Long totalMemoryLimit = 0L;
+
+        for (final DomainJoinVO domain: domainDao.listAll()) {
+            if (domain == null || domain.getLevel() != 1) {
+                continue;
+            }
+            long cpuLimit = 
ApiDBUtils.findCorrectResourceLimitForDomain(domain.getCpuLimit(), false,
+                    Resource.ResourceType.cpu, domain.getId());
+            if (cpuLimit > 0) {
+                totalCpuLimit += cpuLimit;
+            }
+
+            long memoryLimit = 
ApiDBUtils.findCorrectResourceLimitForDomain(domain.getMemoryLimit(), false,
+                    Resource.ResourceType.memory, domain.getId());
+            if (memoryLimit > 0) {
+                totalMemoryLimit += memoryLimit;
+            }
+        }
+        metricsList.add(new ItemDomainLimitCpu(totalCpuLimit));
+        metricsList.add(new ItemDomainLimitMemory(totalMemoryLimit));
+    }
+
+    @Override
+    public void updateMetrics() {
+        final List<Item> latestMetricsItems = new ArrayList<Item>();
+        try {
+            for (final DataCenterVO dc : dcDao.listAll()) {
+                final String zoneName = dc.getName();
+                final String zoneUuid = dc.getUuid();
+                alertManager.recalculateCapacity();
+                addHostMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+                addVMMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+                addVolumeMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+                addStorageMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+                addIpAddressMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+                addVlanMetrics(latestMetricsItems, dc.getId(), zoneName, 
zoneUuid);
+            }
+            addDomainLimits(latestMetricsItems);
+        } catch (Exception e) {
+            LOG.warn("Getting metrics failed ", e);
+        }
+        metricsItems = latestMetricsItems;
+    }
+
+    @Override
+    public String getMetrics() {
+        final StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("# Cloudstack Prometheus Metrics\n");
+        for (final Item item : metricsItems) {
+            stringBuilder.append(item.toMetricsString()).append("\n");
+        }
+        return stringBuilder.toString();
+    }
+
+    private abstract class Item {
+        String name;
+
+        public Item(final String nm) {
+            name = nm;
+        }
+
+        public abstract String toMetricsString();
+    }
+
+    class ItemVM extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        long total;
+
+        public ItemVM(final String zn, final String zu, final String st, long 
cnt) {
+            super("cloudstack_vms_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = st;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemVolume extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        int total;
+
+        public ItemVolume(final String zn, final String zu, final String st, 
int cnt) {
+            super("cloudstack_volumes_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = st;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemHost extends Item {
+        String zoneName;
+        String zoneUuid;
+        String state;
+        int total;
+
+        public ItemHost(final String zn, final String zu, final String st, int 
cnt) {
+            super("cloudstack_hosts_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            state = st;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, state, total);
+        }
+    }
+
+    class ItemVMCore extends Item {
+        String zoneName;
+        String zoneUuid;
+        String hostName;
+        String uuid;
+        String ip;
+        String filter;
+        long core = 0;
+
+        public ItemVMCore(final String zn, final String zu, final String hn, 
final String hu, final String hip, final String fl, final Long cr) {
+            super("cloudstack_host_vms_cores_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            hostName = hn;
+            uuid = hu;
+            ip = hip;
+            filter = fl;
+            if (cr != null) {
+                core = cr;
+            }
+        }
+
+        @Override
+        public String toMetricsString() {
+            if (Strings.isNullOrEmpty(hostName) && Strings.isNullOrEmpty(ip)) {
+                return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, core);
+            }
+            return 
String.format("%s{zone=\"%s\",hostname=\"%s\",ip=\"%s\",filter=\"%s\"} %d", 
name, zoneName, hostName, ip, filter, core);
+        }
+    }
+
+    class ItemHostCpu extends Item {
+        String zoneName;
+        String zoneUuid;
+        String hostName;
+        String uuid;
+        String ip;
+        String overProvisioningFactor;
+        String filter;
+        double mhertz;
+
+        public ItemHostCpu(final String zn, final String zu, final String hn, 
final String hu, final String hip, final String of, final String fl, final 
double mh) {
+            super("cloudstack_host_cpu_usage_mhz_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            hostName = hn;
+            uuid = hu;
+            ip = hip;
+            overProvisioningFactor = of;
+            filter = fl;
+            mhertz = mh;
+        }
+
+        @Override
+        public String toMetricsString() {
+            if (Strings.isNullOrEmpty(hostName) && Strings.isNullOrEmpty(ip)) {
+                return String.format("%s{zone=\"%s\",filter=\"%s\"} %.2f", 
name, zoneName, filter, mhertz);
+            }
+            return 
String.format("%s{zone=\"%s\",hostname=\"%s\",ip=\"%s\",overprovisioningfactor=\"%s\",filter=\"%s\"}
 %.2f", name, zoneName, hostName, ip, overProvisioningFactor, filter, mhertz);
+        }
+    }
+
+    class ItemHostMemory extends Item {
+        String zoneName;
+        String zoneUuid;
+        String hostName;
+        String uuid;
+        String ip;
+        String overProvisioningFactor;
+        String filter;
+        double miBytes;
+
+        public ItemHostMemory(final String zn, final String zu, final String 
hn, final String hu, final String hip, final String of, final String fl, final 
double membytes) {
+            super("cloudstack_host_memory_usage_mibs_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            hostName = hn;
+            uuid = hu;
+            ip = hip;
+            overProvisioningFactor = of;
+            filter = fl;
+            miBytes = membytes / (1024.0 * 1024.0);
+        }
+
+        @Override
+        public String toMetricsString() {
+            if (Strings.isNullOrEmpty(hostName) && Strings.isNullOrEmpty(ip)) {
+                return String.format("%s{zone=\"%s\",filter=\"%s\"} %.2f", 
name, zoneName, filter, miBytes);
+            }
+            return 
String.format("%s{zone=\"%s\",hostname=\"%s\",ip=\"%s\",overprovisioningfactor=\"%s\",filter=\"%s\"}
 %.2f", name, zoneName, hostName, ip, overProvisioningFactor, filter, miBytes);
+        }
+    }
+
+    class ItemHostVM extends Item {
+        String zoneName;
+        String zoneUuid;
+        String hostName;
+        String hostUuid;
+        String hostIp;
+        int total;
+
+        public ItemHostVM(final String zoneName, final String zoneUuid, final 
String hostName, final String hostUuid, final String hostIp, final int total) {
+            super("cloudstack_host_vms_total");
+            this.zoneName = zoneName;
+            this.zoneUuid = zoneUuid;
+            this.hostName = hostName;
+            this.hostUuid = hostUuid;
+            this.hostIp = hostIp;
+            this.total = total;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return 
String.format("%s{zone=\"%s\",hostname=\"%s\",address=\"%s\"} %d", name, 
zoneName, hostName, hostIp, total);
+        }
+    }
+
+    class ItemPool extends Item {
+        String zoneName;
+        String zoneUuid;
+        String type;
+        String overProvisioningFactor;
+        String filter;
+        String pname;
+        String address;
+        double total;
+
+        public ItemPool(final String zn, final String zu, final String pn, 
final String pa, final String typ, final String of, final String fl, double 
cnt) {
+            super("cloudstack_storage_pool_gibs_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            pname = pn;
+            address = pa;
+            type = typ;
+            overProvisioningFactor = of;
+            filter = fl;
+            total = cnt / (1024.0 * 1024.0 * 1024.0);
+        }
+
+        @Override
+        public String toMetricsString() {
+            if (Strings.isNullOrEmpty(overProvisioningFactor)) {
+                return 
String.format("%s{zone=\"%s\",name=\"%s\",address=\"%s\",type=\"%s\",filter=\"%s\"}
 %.2f", name, zoneName, pname, address, type, filter, total);
+            }
+            return 
String.format("%s{zone=\"%s\",name=\"%s\",address=\"%s\",type=\"%s\",overprovisioningfactor=\"%s\",filter=\"%s\"}
 %.2f", name, zoneName, pname, address, type, overProvisioningFactor, filter, 
total);
+        }
+    }
+
+    class ItemPrivateIp extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        int total;
+
+        public ItemPrivateIp(final String zn, final String zu, final String 
fl, int cnt) {
+            super("cloudstack_private_ips_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = fl;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemPublicIp extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        int total;
+
+        public ItemPublicIp(final String zn, final String zu, final String fl, 
int cnt) {
+            super("cloudstack_public_ips_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = fl;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemSharedNetworkIp extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        int total;
+
+        public ItemSharedNetworkIp(final String zn, final String zu, final 
String fl, int cnt) {
+            super("cloudstack_shared_network_ips_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = fl;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemVlan extends Item {
+        String zoneName;
+        String zoneUuid;
+        String filter;
+        int total;
+
+        public ItemVlan(final String zn, final String zu, final String fl, int 
cnt) {
+            super("cloudstack_vlans_total");
+            zoneName = zn;
+            zoneUuid = zu;
+            filter = fl;
+            total = cnt;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s{zone=\"%s\",filter=\"%s\"} %d", name, 
zoneName, filter, total);
+        }
+    }
+
+    class ItemDomainLimitCpu extends Item {
+        long cores;
+
+        public ItemDomainLimitCpu(final long c) {
+            super("cloudstack_domain_limit_cpu_cores_total");
+            cores = c;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s %d", name, cores);
+        }
+    }
+
+    class ItemDomainLimitMemory extends Item {
+        long miBytes;
+
+        public ItemDomainLimitMemory(final long mb) {
+            super("cloudstack_domain_limit_memory_mibs_total");
+            miBytes = mb;
+        }
+
+        @Override
+        public String toMetricsString() {
+            return String.format("%s %d", name, miBytes);
+        }
+    }
+}
diff --git 
a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServer.java
 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServer.java
new file mode 100644
index 0000000..e030352
--- /dev/null
+++ 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServer.java
@@ -0,0 +1,33 @@
+// 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.cloudstack.metrics;
+
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.utils.component.Manager;
+
+public interface PrometheusExporterServer extends Manager {
+
+    ConfigKey<Boolean> EnablePrometheusExporter = new ConfigKey<>("Advanced", 
Boolean.class, "prometheus.exporter.enable", "false",
+            "Enable the prometheus exporter plugin, management server restart 
needed.", true);
+
+    ConfigKey<Integer> PrometheusExporterServerPort = new 
ConfigKey<>("Advanced", Integer.class, "prometheus.exporter.port", "9595",
+            "The prometheus exporter server port", true);
+
+    ConfigKey<String> PrometheusExporterAllowedAddresses = new 
ConfigKey<>("Advanced", String.class, "prometheus.exporter.allowed.ips", 
"127.0.0.1",
+            "List of comma separated prometheus server ips (with no spaces) 
that should be allowed to access the URLs", true);
+}
diff --git 
a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
new file mode 100644
index 0000000..a615c65
--- /dev/null
+++ 
b/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
@@ -0,0 +1,118 @@
+// 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.cloudstack.metrics;
+
+import com.cloud.utils.component.ManagerBase;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+
+public class PrometheusExporterServerImpl extends ManagerBase implements 
PrometheusExporterServer, Configurable {
+    private static final Logger LOG = 
Logger.getLogger(PrometheusExporterServerImpl.class);
+
+    private static HttpServer httpServer;
+
+    @Inject
+    private PrometheusExporter prometheusExporter;
+
+    private final static class ExporterHandler implements HttpHandler {
+        private PrometheusExporter prometheusExporter;
+
+        ExporterHandler(final PrometheusExporter prometheusExporter) {
+            super();
+            this.prometheusExporter = prometheusExporter;
+        }
+
+        @Override
+        public void handle(final HttpExchange httpExchange) throws IOException 
{
+            final String remoteClientAddress = 
httpExchange.getRemoteAddress().getAddress().toString().replace("/", "");
+            LOG.debug("Prometheus exporter received client request from: " + 
remoteClientAddress);
+            String response = "Forbidden";
+            int responseCode = 403;
+            if 
(Arrays.asList(PrometheusExporterAllowedAddresses.value().split(",")).contains(remoteClientAddress))
 {
+                prometheusExporter.updateMetrics();
+                response = prometheusExporter.getMetrics();
+                responseCode = 200;
+            }
+            httpExchange.getResponseHeaders().set("Content-Type", 
"text/plain");
+            httpExchange.sendResponseHeaders(responseCode, response.length());
+            final OutputStream os = httpExchange.getResponseBody();
+            os.write(response.getBytes());
+            os.close();
+        }
+    }
+
+    @Override
+    public boolean start() {
+        if (EnablePrometheusExporter.value()) {
+            try {
+                httpServer = HttpServer.create(new 
InetSocketAddress(PrometheusExporterServerPort.value()), 0);
+                httpServer.createContext("/metrics", new 
ExporterHandler(prometheusExporter));
+                httpServer.createContext("/", new HttpHandler() {
+                    @Override
+                    public void handle(HttpExchange httpExchange) throws 
IOException {
+                        final String response = "<html><head><title>CloudStack 
Exporter</title></head>" +
+                                "<body><h1>CloudStack Exporter</h1>" +
+                                "<p><a href=\"/metrics\">Metrics</a></p>" +
+                                "</body></html>";
+                        httpExchange.sendResponseHeaders(200, 
response.length());
+                        final OutputStream os = httpExchange.getResponseBody();
+                        os.write(response.getBytes());
+                        os.close();
+                    }
+                });
+                httpServer.start();
+                LOG.debug("Started prometheus exporter http server");
+            } catch (final IOException e) {
+                LOG.info("Failed to start prometheus exporter http server due 
to: ", e);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        if (httpServer != null) {
+            httpServer.stop(0);
+            LOG.debug("Stopped Prometheus exporter http server");
+        }
+        return true;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return PrometheusExporter.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {
+                EnablePrometheusExporter,
+                PrometheusExporterServerPort,
+                PrometheusExporterAllowedAddresses
+        };
+    }
+}
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 28104b4..1ee7af5 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -107,6 +107,7 @@
     <module>network-elements/vxlan</module>
     <module>network-elements/globodns</module>
     <module>database/quota</module>
+    <module>integrations/prometheus</module>
   </modules>
 
   <dependencies>

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to