You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tubemq.apache.org by go...@apache.org on 2020/12/23 11:52:55 UTC

[incubator-tubemq] branch TUBEMQ-455 updated: [TUBEMQ-474] define metrics for agent

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

gosonzhang pushed a commit to branch TUBEMQ-455
in repository https://gitbox.apache.org/repos/asf/incubator-tubemq.git


The following commit(s) were added to refs/heads/TUBEMQ-455 by this push:
     new dec0143  [TUBEMQ-474] define metrics for agent
dec0143 is described below

commit dec014318d775cb9b9a107908a5022816e28740f
Author: yuanbo <yu...@apache.org>
AuthorDate: Wed Dec 23 17:43:35 2020 +0800

    [TUBEMQ-474] define metrics for agent
---
 .../org/apache/tubemq/agent/metrics/Metric.java    |  49 +++++++
 .../tubemq/agent/metrics/MetricException.java      |  25 ++++
 .../org/apache/tubemq/agent/metrics/Metrics.java   |  48 ++++++
 .../apache/tubemq/agent/metrics/MetricsMeta.java   | 163 +++++++++++++++++++++
 .../tubemq/agent/metrics/MetricsRegister.java      | 147 +++++++++++++++++++
 .../apache/tubemq/agent/metrics/MutableMetric.java |  24 +++
 .../tubemq/agent/metrics/counter/Counter.java      |  32 ++++
 .../tubemq/agent/metrics/counter/CounterInt.java   |  37 +++++
 .../tubemq/agent/metrics/counter/CounterLong.java  |  40 +++++
 .../apache/tubemq/agent/metrics/gauge/Gauge.java   |  44 ++++++
 .../tubemq/agent/metrics/gauge/GaugeInt.java       |  48 ++++++
 .../tubemq/agent/metrics/gauge/GaugeLong.java      |  48 ++++++
 12 files changed, 705 insertions(+)

diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metric.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metric.java
new file mode 100644
index 0000000..4f36a9f
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metric.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * metrics
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface Metric {
+
+    /**
+     * Type of metric
+     *
+     * @return metric type
+     */
+    Type type() default Type.DEFAULT;
+
+    /**
+     * Doc of metric
+     *
+     * @return metric doc
+     */
+    String desc() default "";
+
+    // metric
+    enum Type {
+        DEFAULT,
+        COUNTER,
+        GAUGE,
+        TAG
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricException.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricException.java
new file mode 100644
index 0000000..1fbaab9
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricException.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+public class MetricException extends RuntimeException {
+
+    public MetricException(String message, Exception ex) {
+        super(message, ex);
+    }
+
+    public MetricException(String message) {
+        super(message);
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metrics.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metrics.java
new file mode 100644
index 0000000..66a270b
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/Metrics.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * metric collections
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Metrics {
+
+    /**
+     * Metrics name
+     *
+     * @return metric name
+     */
+    String name() default "";
+
+    /**
+     * Metrics context
+     *
+     * @return metric context
+     */
+    String context() default "";
+
+    /**
+     * Metrics description
+     *
+     * @return metric desc
+     */
+    String desc() default "";
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsMeta.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsMeta.java
new file mode 100644
index 0000000..7b24503
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsMeta.java
@@ -0,0 +1,163 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.tubemq.agent.metrics.counter.Counter;
+import org.apache.tubemq.agent.metrics.gauge.Gauge;
+
+/**
+ * metric meta
+ */
+public class MetricsMeta {
+
+    private String name;
+    private String context;
+    private String desc;
+
+    // metric source
+    private Object source;
+
+    private List<FieldMetricMeta> fields;
+    private List<MethodMetricMeta> methods;
+
+    private MetricsMeta() {
+    }
+
+    public static MetricsMeta build(Object source, Metrics metrics,
+            List<FieldMetricMeta> fields,
+            List<MethodMetricMeta> methods) {
+        MetricsMeta metricsMeta = new MetricsMeta();
+        String name = metrics.name();
+        if (StringUtils.isEmpty(name)) {
+            name = source.getClass().getSimpleName();
+        }
+        metricsMeta.name = StringUtils.capitalize(name);
+        metricsMeta.context = metrics.context();
+        metricsMeta.desc = metrics.desc();
+
+        metricsMeta.source = source;
+        metricsMeta.fields = fields;
+        metricsMeta.methods = methods;
+        return metricsMeta;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public List<FieldMetricMeta> getFields() {
+        return fields;
+    }
+
+    public List<MethodMetricMeta> getMethods() {
+        return methods;
+    }
+
+    /**
+     * inner metric meta
+     */
+    private static class MetricMeta {
+
+        String name;
+        Metric.Type type;
+        String desc;
+
+        static Metric.Type getType(Class<?> clz, Metric.Type defaultType) {
+            if (clz.isAssignableFrom(Counter.class)) {
+                return Metric.Type.COUNTER;
+            } else if (clz.isAssignableFrom(Gauge.class)) {
+                return Metric.Type.GAUGE;
+            } else {
+                return defaultType;
+            }
+        }
+
+        public Metric.Type getType() {
+            return type;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getDesc() {
+            return desc;
+        }
+    }
+
+    /**
+     * field
+     */
+    public static class FieldMetricMeta extends MetricMeta {
+
+        private Field field;
+
+
+        public static FieldMetricMeta build(Metric annotation, Field field) {
+            FieldMetricMeta meta = new FieldMetricMeta();
+            meta.name = StringUtils.capitalize(field.getName());
+            meta.type = getType(field.getType(), annotation.type());
+            meta.desc = annotation.desc();
+
+            meta.field = field;
+            return meta;
+        }
+
+        public Field getField() {
+            return field;
+        }
+    }
+
+    /**
+     * metric meta
+     */
+    public static class MethodMetricMeta extends MetricMeta {
+
+        private Method method;
+
+
+        public static MethodMetricMeta build(Metric annotation, Method method) {
+            MethodMetricMeta meta = new MethodMetricMeta();
+            String methodName = method.getName();
+            if (methodName.startsWith("get")) {
+                methodName = methodName.substring(3);
+            }
+            meta.name = StringUtils.capitalize(methodName);
+            meta.type = getType(method.getReturnType(), annotation.type());
+            meta.desc = annotation.desc();
+            meta.method = method;
+            return meta;
+        }
+
+        public Method getMethod() {
+            return method;
+        }
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsRegister.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsRegister.java
new file mode 100644
index 0000000..364222a
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MetricsRegister.java
@@ -0,0 +1,147 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+import static org.apache.tubemq.agent.metrics.MetricsMeta.FieldMetricMeta;
+import static org.apache.tubemq.agent.metrics.MetricsMeta.MethodMetricMeta;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.tubemq.agent.metrics.counter.CounterInt;
+import org.apache.tubemq.agent.metrics.counter.CounterLong;
+import org.apache.tubemq.agent.metrics.gauge.GaugeInt;
+import org.apache.tubemq.agent.metrics.gauge.GaugeLong;
+import org.apache.tubemq.agent.utils.AgentUtils;
+
+/**
+ * metric register
+ */
+public class MetricsRegister {
+
+    private static ConcurrentHashMap<String, MetricsMeta> sources = new ConcurrentHashMap<>();
+
+    private MetricsRegister() {
+    }
+
+
+    /**
+     * register
+     *
+     * @param source metrics
+     */
+    public static void register(Object source) {
+
+        List<FieldMetricMeta> fields = handleFieldAnnotation(source);
+
+        List<MethodMetricMeta> methods = handleMethodAnnotation(source);
+
+        handleClassAnnotation(source, fields, methods);
+    }
+
+    /**
+     * class annotation
+     */
+    private static void handleClassAnnotation(Object source,
+            List<FieldMetricMeta> fields,
+            List<MethodMetricMeta> methods) {
+        for (Annotation annotation : source.getClass().getAnnotations()) {
+            if (annotation instanceof Metrics) {
+                MetricsMeta metricsMeta = MetricsMeta.build(source,
+                        (Metrics) annotation, fields, methods);
+                sources.putIfAbsent(metricsMeta.getName(), metricsMeta);
+                break;
+            }
+        }
+    }
+
+
+    private static boolean initFieldByType(Object source, Field field) {
+        try {
+            if (field.getType() == CounterInt.class) {
+                field.set(source, new CounterInt());
+                return true;
+            } else if (field.getType() == CounterLong.class) {
+                field.set(source, new CounterLong());
+                return true;
+            } else if (field.getType() == GaugeInt.class) {
+                field.set(source, new GaugeInt());
+                return true;
+            } else if (field.getType() == GaugeLong.class) {
+                field.set(source, new GaugeLong());
+                return true;
+            } else {
+                throw new MetricException("field type error " + field.getType().toString());
+            }
+        } catch (MetricException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new MetricException("Error setting field " + field
+                    + " annotated with metric", ex);
+        }
+    }
+
+    /**
+     * handle fields
+     */
+    private static List<FieldMetricMeta> handleFieldAnnotation(Object source) {
+        List<FieldMetricMeta> result = new ArrayList<>();
+        for (Field field : AgentUtils.getDeclaredFieldsIncludingInherited(source.getClass())) {
+
+            // metric accessible
+            field.setAccessible(true);
+            for (Annotation fieldAnnotation : field.getAnnotations()) {
+                if (fieldAnnotation instanceof Metric) {
+                    if (initFieldByType(source, field)) {
+                        result.add(FieldMetricMeta.build((Metric) fieldAnnotation, field));
+                    }
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * handle methods
+     *
+     * @throws MetricException npe
+     */
+    private static List<MethodMetricMeta> handleMethodAnnotation(Object source) {
+        List<MethodMetricMeta> result = new ArrayList<>();
+        for (Method method : AgentUtils.getDeclaredMethodsIncludingInherited(source.getClass())) {
+
+
+            if (method.isVarArgs()) {
+                throw new MetricException("Cannot declare on method with arguments");
+            }
+
+            method.setAccessible(true);
+            for (Annotation methodAnnotation : method.getAnnotations()) {
+                if (methodAnnotation instanceof Metric) {
+                    // TODO: handle method column
+                    result.add(MethodMetricMeta.build((Metric) methodAnnotation, method));
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+
+}
+
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MutableMetric.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MutableMetric.java
new file mode 100644
index 0000000..8ef29d8
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/MutableMetric.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed 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.tubemq.agent.metrics;
+
+public interface MutableMetric {
+
+    /**
+     * return snapshot
+     *
+     * @return
+     */
+    Number snapshot();
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/Counter.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/Counter.java
new file mode 100644
index 0000000..d1566ec
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/Counter.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.counter;
+
+import org.apache.tubemq.agent.metrics.MutableMetric;
+
+public interface Counter extends MutableMetric {
+
+    /**
+     * increments
+     */
+    void incr();
+
+    /**
+     * increments with delta
+     *
+     * @param delta  > 0
+     */
+    void incr(int delta);
+
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterInt.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterInt.java
new file mode 100644
index 0000000..2c0a33d
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterInt.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.counter;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CounterInt implements Counter {
+
+    private AtomicInteger value = new AtomicInteger(0);
+
+    @Override
+    public void incr() {
+        value.incrementAndGet();
+    }
+
+    @Override
+    public void incr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(delta);
+    }
+
+    @Override
+    public Integer snapshot() {
+        return value.get();
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterLong.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterLong.java
new file mode 100644
index 0000000..3b9b12b
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/counter/CounterLong.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.counter;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * atomic long
+ */
+public class CounterLong implements Counter {
+
+    private AtomicLong value = new AtomicLong();
+
+    @Override
+    public void incr() {
+        value.incrementAndGet();
+    }
+
+    @Override
+    public void incr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(delta);
+    }
+
+    @Override
+    public Long snapshot() {
+        return value.get();
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/Gauge.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/Gauge.java
new file mode 100644
index 0000000..f19e5a9
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/Gauge.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.gauge;
+
+
+import org.apache.tubemq.agent.metrics.MutableMetric;
+
+public interface Gauge extends MutableMetric {
+
+    /**
+     * increments
+     */
+    void incr();
+
+    /**
+     * increments with delta
+     *
+     * @param delta  > 0
+     */
+    void incr(int delta);
+
+    /**
+     * decrements
+     */
+    void decr();
+
+    /**
+     * decrements with delta
+     *
+     * @param delta > 0
+     */
+    void decr(int delta);
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeInt.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeInt.java
new file mode 100644
index 0000000..b464b59
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeInt.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.gauge;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class GaugeInt implements Gauge {
+
+    private AtomicInteger value = new AtomicInteger(0);
+
+    @Override
+    public void incr() {
+        value.incrementAndGet();
+    }
+
+    @Override
+    public void incr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(delta);
+    }
+
+    @Override
+    public void decr() {
+        value.decrementAndGet();
+    }
+
+    @Override
+    public void decr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(-delta);
+    }
+
+    @Override
+    public Integer snapshot() {
+        return value.get();
+    }
+}
diff --git a/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeLong.java b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeLong.java
new file mode 100644
index 0000000..5c8611a
--- /dev/null
+++ b/tubemq-agent/agent-common/src/main/java/org/apache/tubemq/agent/metrics/gauge/GaugeLong.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed 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.tubemq.agent.metrics.gauge;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class GaugeLong implements Gauge {
+
+    private AtomicLong value = new AtomicLong(0);
+
+    @Override
+    public void incr() {
+        value.incrementAndGet();
+    }
+
+    @Override
+    public void incr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(delta);
+    }
+
+    @Override
+    public void decr() {
+        value.decrementAndGet();
+    }
+
+    @Override
+    public void decr(int delta) {
+        assert delta > 0;
+        value.getAndAdd(-delta);
+    }
+
+    @Override
+    public Long snapshot() {
+        return value.get();
+    }
+}