You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2019/01/07 14:35:14 UTC

[incubator-skywalking] 01/01: Finish the basic codes of telemetry.

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

wusheng pushed a commit to branch prometheus
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git

commit 2107b3a3f42e3dfcad5a247bfbadadf2af2eac09
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Mon Jan 7 22:34:54 2019 +0800

    Finish the basic codes of telemetry.
---
 .../cluster/plugin/consul/ConsulCoordinator.java   | 19 ++----
 .../plugin/kubernetes/KubernetesCoordinator.java   |  2 +
 .../plugin/standalone/StandaloneManager.java       |  2 +
 .../plugin/zookeeper/ZookeeperCoordinator.java     |  2 +
 .../core/remote/client/RemoteClientManager.java    | 34 ++++++----
 oap-server/server-starter/pom.xml                  |  7 ++
 .../src/main/resources/application.yml             |  2 +-
 .../oap/server/telemetry/api/CounterMetric.java    |  2 +-
 .../oap/server/telemetry/api/GaugeMetric.java      | 17 +++--
 .../oap/server/telemetry/api/HistogramMetric.java  |  4 +-
 .../oap/server/telemetry/api/MetricCreator.java    | 12 ++--
 .../oap/server/telemetry/api/MetricTag.java        |  7 +-
 .../telemetry/api/TelemetryRelatedContext.java     | 10 +--
 .../server/telemetry/none/MetricCreatorNoop.java   | 47 +++++++++++--
 .../server-telemetry/telemetry-prometheus/pom.xml  |  5 ++
 .../server/telemetry/prometheus/BaseMetric.java    | 79 ++++++++++++++++++++++
 .../telemetry/prometheus/PrometheusConfig.java}    | 14 ++--
 .../prometheus/PrometheusCounterMetric.java        | 54 +++++++++++++++
 .../prometheus/PrometheusGaugeMetric.java          | 75 ++++++++++++++++++++
 .../prometheus/PrometheusHistogramMetric.java      | 58 ++++++++++++++++
 .../prometheus/PrometheusMetricCreator.java}       | 21 +++---
 .../prometheus/PrometheusTelemetryProvider.java    | 70 +++++++++++++++++++
 ...alking.oap.server.library.module.ModuleProvider | 20 ++++++
 23 files changed, 495 insertions(+), 68 deletions(-)

diff --git a/oap-server/server-cluster-plugin/cluster-consul-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/consul/ConsulCoordinator.java b/oap-server/server-cluster-plugin/cluster-consul-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/consul/ConsulCoordinator.java
index 7cf732c..5584a62 100644
--- a/oap-server/server-cluster-plugin/cluster-consul-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/consul/ConsulCoordinator.java
+++ b/oap-server/server-cluster-plugin/cluster-consul-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/consul/ConsulCoordinator.java
@@ -19,22 +19,14 @@
 package org.apache.skywalking.oap.server.cluster.plugin.consul;
 
 import com.google.common.base.Strings;
-import com.orbitz.consul.AgentClient;
-import com.orbitz.consul.Consul;
-import com.orbitz.consul.HealthClient;
-import com.orbitz.consul.model.agent.ImmutableRegistration;
-import com.orbitz.consul.model.agent.Registration;
+import com.orbitz.consul.*;
+import com.orbitz.consul.model.agent.*;
 import com.orbitz.consul.model.health.ServiceHealth;
-import org.apache.skywalking.oap.server.core.cluster.ClusterNodesQuery;
-import org.apache.skywalking.oap.server.core.cluster.ClusterRegister;
-import org.apache.skywalking.oap.server.core.cluster.RemoteInstance;
-import org.apache.skywalking.oap.server.core.cluster.ServiceRegisterException;
+import java.util.*;
+import org.apache.skywalking.oap.server.core.cluster.*;
 import org.apache.skywalking.oap.server.core.remote.client.Address;
 import org.apache.skywalking.oap.server.library.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+import org.apache.skywalking.oap.server.telemetry.api.TelemetryRelatedContext;
 
 /**
  * @author peng-yongsheng
@@ -77,6 +69,7 @@ public class ConsulCoordinator implements ClusterRegister, ClusterNodesQuery {
         AgentClient agentClient = client.agentClient();
 
         this.selfAddress = remoteInstance.getAddress();
+        TelemetryRelatedContext.INSTANCE.setId(selfAddress.toString());
 
         Registration registration = ImmutableRegistration.builder()
             .id(remoteInstance.getAddress().toString())
diff --git a/oap-server/server-cluster-plugin/cluster-kubernetes-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/kubernetes/KubernetesCoordinator.java b/oap-server/server-cluster-plugin/cluster-kubernetes-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/kubernetes/KubernetesCoordinator.java
index 8fdc5f8..730f4b2 100644
--- a/oap-server/server-cluster-plugin/cluster-kubernetes-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/kubernetes/KubernetesCoordinator.java
+++ b/oap-server/server-cluster-plugin/cluster-kubernetes-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/kubernetes/KubernetesCoordinator.java
@@ -26,6 +26,7 @@ import java.util.function.Supplier;
 import javax.annotation.Nullable;
 import org.apache.skywalking.oap.server.core.cluster.*;
 import org.apache.skywalking.oap.server.core.remote.client.Address;
+import org.apache.skywalking.oap.server.telemetry.api.TelemetryRelatedContext;
 import org.slf4j.*;
 
 /**
@@ -49,6 +50,7 @@ public class KubernetesCoordinator implements ClusterRegister, ClusterNodesQuery
     KubernetesCoordinator(final ReusableWatch<Event> watch, final Supplier<String> uidSupplier) {
         this.watch = watch;
         this.uid = uidSupplier.get();
+        TelemetryRelatedContext.INSTANCE.setId(uid);
     }
 
     @Override public void registerRemote(RemoteInstance remoteInstance) throws ServiceRegisterException {
diff --git a/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/StandaloneManager.java b/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/StandaloneManager.java
index ef30870..b70873f 100644
--- a/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/StandaloneManager.java
+++ b/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/StandaloneManager.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.cluster.plugin.standalone;
 
 import java.util.*;
 import org.apache.skywalking.oap.server.core.cluster.*;
+import org.apache.skywalking.oap.server.telemetry.api.TelemetryRelatedContext;
 
 /**
  * A cluster manager simulator. Work in memory only. Also return the current instance.
@@ -33,6 +34,7 @@ public class StandaloneManager implements ClusterNodesQuery, ClusterRegister {
     @Override public void registerRemote(RemoteInstance remoteInstance) {
         this.remoteInstance = remoteInstance;
         this.remoteInstance.getAddress().setSelf(true);
+        TelemetryRelatedContext.INSTANCE.setId("standalone");
     }
 
     @Override
diff --git a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ZookeeperCoordinator.java b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ZookeeperCoordinator.java
index 826bdbb..837f3f3 100644
--- a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ZookeeperCoordinator.java
+++ b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ZookeeperCoordinator.java
@@ -22,6 +22,7 @@ import java.util.*;
 import org.apache.curator.x.discovery.*;
 import org.apache.skywalking.oap.server.core.cluster.*;
 import org.apache.skywalking.oap.server.core.remote.client.Address;
+import org.apache.skywalking.oap.server.telemetry.api.TelemetryRelatedContext;
 import org.slf4j.*;
 
 /**
@@ -59,6 +60,7 @@ public class ZookeeperCoordinator implements ClusterRegister, ClusterNodesQuery
             serviceCache.start();
 
             this.selfAddress = remoteInstance.getAddress();
+            TelemetryRelatedContext.INSTANCE.setId(selfAddress.toString());
         } catch (Exception e) {
             throw new ServiceRegisterException(e.getMessage());
         }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/RemoteClientManager.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/RemoteClientManager.java
index 2510a11..5978772 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/RemoteClientManager.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/RemoteClientManager.java
@@ -24,12 +24,13 @@ import org.apache.skywalking.oap.server.core.CoreModule;
 import org.apache.skywalking.oap.server.core.cluster.*;
 import org.apache.skywalking.oap.server.core.remote.annotation.StreamDataClassGetter;
 import org.apache.skywalking.oap.server.library.module.*;
+import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
+import org.apache.skywalking.oap.server.telemetry.api.*;
 import org.slf4j.*;
 
 /**
- * This class manages the connections between OAP servers. There is a task schedule that will
- * automatically query a server list from the cluster module. Such as Zookeeper cluster module
- * or Kubernetes cluster module.
+ * This class manages the connections between OAP servers. There is a task schedule that will automatically query a
+ * server list from the cluster module. Such as Zookeeper cluster module or Kubernetes cluster module.
  *
  * @author peng-yongsheng
  */
@@ -43,6 +44,7 @@ public class RemoteClientManager implements Service {
     private final List<RemoteClient> clientsA;
     private final List<RemoteClient> clientsB;
     private volatile List<RemoteClient> usingClients;
+    private GaugeMetric gauge;
 
     public RemoteClientManager(ModuleDefineHolder moduleDefineHolder) {
         this.moduleDefineHolder = moduleDefineHolder;
@@ -56,11 +58,15 @@ public class RemoteClientManager implements Service {
     }
 
     /**
-     * Query OAP server list from the cluster module and create a new connection
-     * for the new node. Make the OAP server orderly because of each of the server
-     * will send stream data to each other by hash code.
+     * Query OAP server list from the cluster module and create a new connection for the new node. Make the OAP server
+     * orderly because of each of the server will send stream data to each other by hash code.
      */
     void refresh() {
+        if (gauge == null) {
+            gauge = moduleDefineHolder.find(TelemetryModule.NAME).provider().getService(MetricCreator.class)
+                .createGauge("cluster_size", "Cluster size of current oap node",
+                    MetricTag.EMPTY_KEY, MetricTag.EMPTY_VALUE);
+        }
         try {
             if (Objects.isNull(clusterNodesQuery)) {
                 synchronized (RemoteClientManager.class) {
@@ -86,6 +92,8 @@ public class RemoteClientManager implements Service {
             instanceList = distinct(instanceList);
             Collections.sort(instanceList);
 
+            gauge.setValue(instanceList.size());
+
             if (logger.isDebugEnabled()) {
                 instanceList.forEach(instance -> logger.debug("Cluster instance: {}", instance.toString()));
             }
@@ -115,11 +123,10 @@ public class RemoteClientManager implements Service {
     }
 
     /**
-     * Because of OAP server register by the UUID which one-to-one mapping with process number.
-     * The register information not delete immediately after process shutdown because of there
-     * is always happened network fault, not really process shutdown. So, cluster module must
-     * wait a few seconds to confirm it. Then there are more than one register information in
-     * the cluster.
+     * Because of OAP server register by the UUID which one-to-one mapping with process number. The register information
+     * not delete immediately after process shutdown because of there is always happened network fault, not really
+     * process shutdown. So, cluster module must wait a few seconds to confirm it. Then there are more than one register
+     * information in the cluster.
      *
      * @param instanceList the instances query from cluster module.
      * @return distinct remote instances
@@ -156,9 +163,8 @@ public class RemoteClientManager implements Service {
     }
 
     /**
-     * Compare clients between exist clients and remote instance collection. Move
-     * the clients into new client collection which are alive to avoid create a
-     * new channel. Shutdown the clients which could not find in cluster config.
+     * Compare clients between exist clients and remote instance collection. Move the clients into new client collection
+     * which are alive to avoid create a new channel. Shutdown the clients which could not find in cluster config.
      *
      * Create a gRPC client for remote instance except for self-instance.
      *
diff --git a/oap-server/server-starter/pom.xml b/oap-server/server-starter/pom.xml
index d02bf15..88f5272 100644
--- a/oap-server/server-starter/pom.xml
+++ b/oap-server/server-starter/pom.xml
@@ -133,6 +133,13 @@
             <artifactId>server-alarm-plugin</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <!-- telemetry -->
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>telemetry-prometheus</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
     <build>
         <finalName>skywalking-oap</finalName>
diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml
index d352526..5b53d73 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -96,4 +96,4 @@ query:
 alarm:
   default:
 telemetry:
-  none:
+  prometheus:
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/CounterMetric.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/CounterMetric.java
index 944872a..3cd47fd 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/CounterMetric.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/CounterMetric.java
@@ -25,7 +25,7 @@ package org.apache.skywalking.oap.server.telemetry.api;
  *
  * @author wusheng
  */
-public interface CounterMetric extends TaggableMetric {
+public interface CounterMetric {
     /**
      * Increase 1 to counter
      */
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/GaugeMetric.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/GaugeMetric.java
index 4fd9bfb..8a3cf45 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/GaugeMetric.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/GaugeMetric.java
@@ -23,28 +23,35 @@ package org.apache.skywalking.oap.server.telemetry.api;
  *
  * @author wusheng
  */
-public interface GaugeMetric extends TaggableMetric {
+public interface GaugeMetric {
     /**
-     * Increase 1 to counter
+     * Increase 1 to gauge
      */
     void inc();
 
     /**
-     * Increase the given value to the counter
+     * Increase the given value to the gauge
      *
      * @param value
      */
     void inc(double value);
 
     /**
-     * Decrease 1 to counter
+     * Decrease 1 to gauge
      */
     void dec();
 
     /**
-     * Decrease the given value to the counter
+     * Decrease the given value to the gauge
      *
      * @param value
      */
     void dec(double value);
+
+    /**
+     * Set the given value to the gauge
+     *
+     * @param value
+     */
+    void setValue(double value);
 }
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/HistogramMetric.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/HistogramMetric.java
index 240a318..f5670e4 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/HistogramMetric.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/HistogramMetric.java
@@ -26,7 +26,7 @@ import java.io.*;
  *
  * @author wusheng
  */
-public abstract class HistogramMetric implements TaggableMetric {
+public abstract class HistogramMetric {
     public Timer createTimer() {
         return new Timer(this);
     }
@@ -38,7 +38,7 @@ public abstract class HistogramMetric implements TaggableMetric {
      */
     public abstract void observe(double value);
 
-    class Timer implements Closeable {
+    public class Timer implements Closeable {
         private final HistogramMetric metric;
         private final long startNanos;
         private double duration;
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricCreator.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricCreator.java
index 591d67b..8dcb8cd 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricCreator.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricCreator.java
@@ -32,29 +32,29 @@ public interface MetricCreator extends Service {
      *
      * @param name
      * @param tips
-     * @param labels
+     * @param tagKeys
      * @return
      */
-    CounterMetric createCounter(String name, String tips, MetricTag.Keys labels);
+    CounterMetric createCounter(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues);
 
     /**
      * Create a gauge type metric instance.
      *
      * @param name
      * @param tips
-     * @param labels
+     * @param tagKeys
      * @return
      */
-    GaugeMetric createGauge(String name, String tips, MetricTag.Keys labels);
+    GaugeMetric createGauge(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues);
 
     /**
      * Create a Histogram type metric instance.
      *
      * @param name
      * @param tips
-     * @param labels
+     * @param tagKeys
      * @param buckets Time bucket for duration.
      * @return
      */
-    HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys labels, double... buckets);
+    HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues, double... buckets);
 }
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricTag.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricTag.java
index cd5b6b4..1e8beb6 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricTag.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/MetricTag.java
@@ -24,7 +24,10 @@ package org.apache.skywalking.oap.server.telemetry.api;
  * The tag values should be set in putting value phase.
  */
 public class MetricTag {
-    public class Keys {
+    public static final Keys EMPTY_KEY = new Keys();
+    public static final Values EMPTY_VALUE = new Values();
+
+    public static class Keys {
         private String[] keys;
 
         public Keys() {
@@ -40,7 +43,7 @@ public class MetricTag {
         }
     }
 
-    public class Values {
+    public static class Values {
         private String[] values;
 
         public Values(Keys keys) {
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TelemetryRelatedContext.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TelemetryRelatedContext.java
index a37e647..0ed338a 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TelemetryRelatedContext.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TelemetryRelatedContext.java
@@ -23,10 +23,10 @@ package org.apache.skywalking.oap.server.telemetry.api;
  * @author wusheng
  */
 public enum TelemetryRelatedContext {
-    INTANCE;
+    INSTANCE;
 
-    private volatile String id = "default";
-    private TelemetryRelatedContext(){}
+    private volatile String id = null;
+    TelemetryRelatedContext(){}
 
     /**
      * Set a global ID to represent the current oap instance
@@ -36,9 +36,9 @@ public enum TelemetryRelatedContext {
     }
 
     /**
-     * Get the oap instance ID, if be set before, otherwise, return `default` string.
+     * Get the oap instance ID, if be set before.
      *
-     * @return id
+     * @return id or null.
      */
     public String getId() {
         return id;
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java
index c33dda7..10d3ba2 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java
+++ b/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java
@@ -26,16 +26,51 @@ import org.apache.skywalking.oap.server.telemetry.api.*;
  * @author wusheng
  */
 public class MetricCreatorNoop implements MetricCreator {
-    @Override public CounterMetric createCounter(String name, String tips, MetricTag.Keys labels) {
-        return null;
+    @Override
+    public CounterMetric createCounter(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues) {
+        return new CounterMetric() {
+            @Override public void inc() {
+
+            }
+
+            @Override public void inc(double value) {
+
+            }
+        };
     }
 
-    @Override public GaugeMetric createGauge(String name, String tips, MetricTag.Keys labels) {
-        return null;
+    @Override
+    public GaugeMetric createGauge(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues) {
+        return new GaugeMetric() {
+            @Override public void inc() {
+
+            }
+
+            @Override public void inc(double value) {
+
+            }
+
+            @Override public void dec() {
+
+            }
+
+            @Override public void dec(double value) {
+
+            }
+
+            @Override public void setValue(double value) {
+
+            }
+        };
     }
 
     @Override
-    public HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys labels, double... buckets) {
-        return null;
+    public HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys tagKeys,
+        MetricTag.Values tagValues, double... buckets) {
+        return new HistogramMetric() {
+            @Override public void observe(double value) {
+
+            }
+        };
     }
 }
diff --git a/oap-server/server-telemetry/telemetry-prometheus/pom.xml b/oap-server/server-telemetry/telemetry-prometheus/pom.xml
index 7885f9b..4514c16 100644
--- a/oap-server/server-telemetry/telemetry-prometheus/pom.xml
+++ b/oap-server/server-telemetry/telemetry-prometheus/pom.xml
@@ -31,6 +31,11 @@
     <packaging>jar</packaging>
 
     <dependencies>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>telemetry-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <!-- The client -->
         <dependency>
             <groupId>io.prometheus</groupId>
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/BaseMetric.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/BaseMetric.java
new file mode 100644
index 0000000..dff3cc7
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/BaseMetric.java
@@ -0,0 +1,79 @@
+/*
+ * 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.skywalking.oap.server.telemetry.prometheus;
+
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.skywalking.oap.server.telemetry.api.*;
+
+/**
+ * BaseMetric parent class represents the me
+ *
+ * @author wusheng
+ */
+public abstract class BaseMetric<T> {
+    private volatile T metricInstance;
+    protected final String name;
+    protected final String tips;
+    protected final MetricTag.Keys labels;
+    protected final MetricTag.Values values;
+    private ReentrantLock lock = new ReentrantLock();
+
+    public BaseMetric(String name, String tips, MetricTag.Keys labels,
+        MetricTag.Values values) {
+        this.name = name;
+        this.tips = tips;
+        this.labels = labels;
+        this.values = values;
+    }
+
+    protected boolean isIDReady() {
+        return TelemetryRelatedContext.INSTANCE.getId() != null;
+    }
+
+    protected T getMetric() {
+        if (metricInstance == null) {
+            if (isIDReady()) {
+                lock.lock();
+                try {
+                    if (metricInstance == null) {
+                        String[] labelNames = new String[labels.getKeys().length + 1];
+                        labelNames[0] = "instance";
+                        for (int i = 0; i < labels.getKeys().length; i++) {
+                            labelNames[i + 1] = labels.getKeys()[i];
+                        }
+
+                        String[] labelValues = new String[values.getValues().length + 1];
+                        labelValues[0] = TelemetryRelatedContext.INSTANCE.getId();
+                        for (int i = 0; i < values.getValues().length; i++) {
+                            labelValues[i + 1] = values.getValues()[i];
+                        }
+
+                        metricInstance = create(labelNames, labelValues);
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
+        }
+
+        return metricInstance;
+    }
+
+    protected abstract T create(String[] labelNames, String[] labelValues);
+}
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TaggableMetric.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusConfig.java
similarity index 71%
rename from oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TaggableMetric.java
rename to oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusConfig.java
index ade3ff5..670fb6e 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/api/TaggableMetric.java
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusConfig.java
@@ -16,13 +16,19 @@
  *
  */
 
-package org.apache.skywalking.oap.server.telemetry.api;
+package org.apache.skywalking.oap.server.telemetry.prometheus;
+
+import lombok.*;
+import org.apache.skywalking.oap.server.library.module.ModuleConfig;
 
 /**
- * Set tag values to this metric instance.
+ * The Prometheus telemetry implementor settings.
  *
  * @author wusheng
  */
-public interface TaggableMetric {
-    void setTagValues(MetricTag.Values values);
+@Setter
+@Getter
+public class PrometheusConfig extends ModuleConfig {
+    private String host = "0.0.0.0";
+    private int port = 1234;
 }
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusCounterMetric.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusCounterMetric.java
new file mode 100644
index 0000000..beb0e88
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusCounterMetric.java
@@ -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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.telemetry.prometheus;
+
+import io.prometheus.client.Counter;
+import org.apache.skywalking.oap.server.telemetry.api.*;
+
+/**
+ * Counter metric in Prometheus implementor.
+ *
+ * @author wusheng
+ */
+public class PrometheusCounterMetric extends BaseMetric<Counter.Child> implements CounterMetric {
+
+    public PrometheusCounterMetric(String name, String tips,
+        MetricTag.Keys labels, MetricTag.Values values) {
+        super(name, tips, labels, values);
+    }
+
+    @Override public void inc() {
+        Counter.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.inc();
+        }
+    }
+
+    @Override public void inc(double value) {
+        Counter.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.inc(value);
+        }
+    }
+
+    @Override protected Counter.Child create(String[] labelNames, String[] labelValues) {
+        return Counter.build()
+            .name(name).help(tips).labelNames(labelNames).register().labels(labelValues);
+    }
+}
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusGaugeMetric.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusGaugeMetric.java
new file mode 100644
index 0000000..ad0f947
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusGaugeMetric.java
@@ -0,0 +1,75 @@
+/*
+ * 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.skywalking.oap.server.telemetry.prometheus;
+
+import io.prometheus.client.Gauge;
+import org.apache.skywalking.oap.server.telemetry.api.*;
+
+/**
+ * Gauge metric in Prometheus implementor.
+ *
+ * @author wusheng
+ */
+public class PrometheusGaugeMetric extends BaseMetric<Gauge.Child> implements GaugeMetric {
+    public PrometheusGaugeMetric(String name, String tips,
+        MetricTag.Keys labels,
+        MetricTag.Values values) {
+        super(name, tips, labels, values);
+    }
+
+    @Override public void inc() {
+        Gauge.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.inc();
+        }
+    }
+
+    @Override public void inc(double value) {
+        Gauge.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.inc(value);
+        }
+    }
+
+    @Override public void dec() {
+        Gauge.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.dec();
+        }
+    }
+
+    @Override public void dec(double value) {
+        Gauge.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.dec(value);
+        }
+    }
+
+    @Override public void setValue(double value) {
+        Gauge.Child metric = this.getMetric();
+        if (metric != null) {
+            metric.set(value);
+        }
+    }
+
+    @Override protected Gauge.Child create(String[] labelNames, String[] labelValues) {
+        return Gauge.build()
+            .name(name).help(tips).labelNames(labelNames).register().labels(labelValues);
+    }
+}
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusHistogramMetric.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusHistogramMetric.java
new file mode 100644
index 0000000..f3fdf07
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusHistogramMetric.java
@@ -0,0 +1,58 @@
+/*
+ * 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.skywalking.oap.server.telemetry.prometheus;
+
+import io.prometheus.client.Histogram;
+import org.apache.skywalking.oap.server.telemetry.api.*;
+
+/**
+ * HistogramMetric metric in Prometheus implementor.
+ *
+ * @author wusheng
+ */
+public class PrometheusHistogramMetric extends HistogramMetric {
+    private InnerMetricObject inner;
+    private final double[] buckets;
+
+    public PrometheusHistogramMetric(String name, String tips, MetricTag.Keys labels,
+        MetricTag.Values values, double... buckets) {
+        inner = new InnerMetricObject(name, tips, labels, values);
+        this.buckets = buckets;
+    }
+
+    @Override public void observe(double value) {
+
+    }
+
+    class InnerMetricObject extends BaseMetric<Histogram.Child> {
+        public InnerMetricObject(String name, String tips, MetricTag.Keys labels,
+            MetricTag.Values values) {
+            super(name, tips, labels, values);
+        }
+
+        @Override protected Histogram.Child create(String[] labelNames, String[] labelValues) {
+            Histogram.Builder builder = Histogram.build()
+                .name(name).help(tips);
+            if(builder != null){
+                builder = builder.buckets(buckets);
+            }
+            return builder.labelNames(labelNames).register().labels(labelValues);
+        }
+    }
+}
diff --git a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusMetricCreator.java
similarity index 56%
copy from oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java
copy to oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusMetricCreator.java
index c33dda7..966a9ce 100644
--- a/oap-server/server-telemetry/telemetry-api/src/main/java/org/apache/skywalking/oap/server/telemetry/none/MetricCreatorNoop.java
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusMetricCreator.java
@@ -16,26 +16,29 @@
  *
  */
 
-package org.apache.skywalking.oap.server.telemetry.none;
+package org.apache.skywalking.oap.server.telemetry.prometheus;
 
 import org.apache.skywalking.oap.server.telemetry.api.*;
 
 /**
- * A no-op metric create, just create nut shell metric instance.
+ * Create metric instance for Prometheus exporter.
  *
  * @author wusheng
  */
-public class MetricCreatorNoop implements MetricCreator {
-    @Override public CounterMetric createCounter(String name, String tips, MetricTag.Keys labels) {
-        return null;
+public class PrometheusMetricCreator implements MetricCreator {
+    @Override
+    public CounterMetric createCounter(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues) {
+        return new PrometheusCounterMetric(name, tips, tagKeys, tagValues);
     }
 
-    @Override public GaugeMetric createGauge(String name, String tips, MetricTag.Keys labels) {
-        return null;
+    @Override
+    public GaugeMetric createGauge(String name, String tips, MetricTag.Keys tagKeys, MetricTag.Values tagValues) {
+        return new PrometheusGaugeMetric(name, tips, tagKeys, tagValues);
     }
 
     @Override
-    public HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys labels, double... buckets) {
-        return null;
+    public HistogramMetric createHistogramMetric(String name, String tips, MetricTag.Keys tagKeys,
+        MetricTag.Values tagValues, double... buckets) {
+        return new PrometheusHistogramMetric(name, tips, tagKeys, tagValues, buckets);
     }
 }
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusTelemetryProvider.java b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusTelemetryProvider.java
new file mode 100644
index 0000000..26890d9
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/java/org/apache/skywalking/oap/server/telemetry/prometheus/PrometheusTelemetryProvider.java
@@ -0,0 +1,70 @@
+/*
+ * 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.skywalking.oap.server.telemetry.prometheus;
+
+import io.prometheus.client.exporter.HTTPServer;
+import java.io.IOException;
+import org.apache.skywalking.oap.server.library.module.*;
+import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
+import org.apache.skywalking.oap.server.telemetry.api.MetricCreator;
+
+/**
+ * Start the Prometheus
+ *
+ * @author wusheng
+ */
+public class PrometheusTelemetryProvider extends ModuleProvider {
+    private PrometheusConfig config;
+
+    public PrometheusTelemetryProvider() {
+        config = new PrometheusConfig();
+    }
+
+    @Override public String name() {
+        return "prometheus";
+    }
+
+    @Override public Class<? extends ModuleDefine> module() {
+        return TelemetryModule.class;
+    }
+
+    @Override public ModuleConfig createConfigBeanIfAbsent() {
+        return config;
+    }
+
+    @Override public void prepare() throws ServiceNotProvidedException, ModuleStartException {
+        this.registerServiceImplementation(MetricCreator.class, new PrometheusMetricCreator());
+        try {
+            HTTPServer server = new HTTPServer(config.getHost(), config.getPort());
+        } catch (IOException e) {
+            throw new ModuleStartException(e.getMessage(), e);
+        }
+    }
+
+    @Override public void start() throws ServiceNotProvidedException, ModuleStartException {
+
+    }
+
+    @Override public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
+    }
+
+    @Override public String[] requiredModules() {
+        return new String[0];
+    }
+}
diff --git a/oap-server/server-telemetry/telemetry-prometheus/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-telemetry/telemetry-prometheus/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
new file mode 100644
index 0000000..1e72991
--- /dev/null
+++ b/oap-server/server-telemetry/telemetry-prometheus/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+#
+
+
+org.apache.skywalking.oap.server.telemetry.prometheus.PrometheusTelemetryProvider