You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hugegraph.apache.org by "SunnyBoy-WYH (via GitHub)" <gi...@apache.org> on 2023/08/16 14:20:54 UTC

[GitHub] [incubator-hugegraph] SunnyBoy-WYH opened a new pull request, #2286: Feat:metric api support promtheus return format

SunnyBoy-WYH opened a new pull request, #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286

   1.增加原有Metric接口的prom格式返回:
   
   > \# HELP hugegraph_info
   \# TYPE hugegraph_info untyped
   hugegraph_info{version="0.69",} 1.0
   \# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity
   \# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity gauge
   org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_capacity 1000000
   \# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire
   \# TYPE org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire gauge
   org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_expire 600000
   \# HELP org_apache_hugegraph_backend_cache_Cache_edge_hugegraph_hits
   
   2.增加statistics接口,返回【请求总数、成功数、失败数、平均响应时间、最大响应时间】五个指标,同时支持prop格式返回
   json:
   > {
       "metrics/GET":{
           "FAILED_REQUEST":0,
           "MEAN_RESPONSE_TIME":10.047648352712768,
           "MAX_RESPONSE_TIME":27,
           "SUCCESS_REQUEST":12,
           "TOTAL_REQUEST":12
       },
       "metrics/statistics/GET":{
           "FAILED_REQUEST":0,
           "MEAN_RESPONSE_TIME":0.6234681965773761,
           "MAX_RESPONSE_TIME":2,
           "SUCCESS_REQUEST":3,
           "TOTAL_REQUEST":3
       }
   }
   prom格式:
   
   > \# HELP hugegraph_info
   \# TYPE hugegraph_info untyped
   hugegraph_info{version="0.69",} 1.0
   \# HELP metrics_GET
   \# TYPE metrics_GET gauge
   metrics_GET{name=FAILED_REQUEST,} 0
   metrics_GET{name=MEAN_RESPONSE_TIME,} 10.047648352712768
   metrics_GET{name=MAX_RESPONSE_TIME,} 27
   metrics_GET{name=SUCCESS_REQUEST,} 12
   metrics_GET{name=TOTAL_REQUEST,} 12
   
   3.需要讨论一下 statistics接口的数据是否要合并在Metric接口中,目前没有合并是因为,原有指标结果JSON中只包含counter、summary等五种标准指标 
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] JackyYangPassion commented on a diff in pull request #2286: Feat:metric api support promtheus return format & add statistic metric api

Posted by "JackyYangPassion (via GitHub)" <gi...@apache.org>.
JackyYangPassion commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1296025451


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");

Review Comment:
   can keep the params alignment style



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,69 @@
+package org.apache.hugegraph.api.filter;

Review Comment:
   need add apache license 



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -165,8 +190,8 @@ public void testMetricsBackend() {
                     String key = (String) e.getKey();
                     value = e.getValue();
                     Assert.assertTrue(String.format(
-                                      "Expect map value for key %s but got %s",
-                                      key, value),
+                                              "Expect map value for key %s but got %s",

Review Comment:
   prefer to keep the origin alignment



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");
     private static final Meter ILLEGAL_ARG_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "illegal-arg");
+            MetricsUtil.registerMeter(API.class, "illegal-arg");

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");
     private static final Meter ILLEGAL_ARG_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "illegal-arg");
+            MetricsUtil.registerMeter(API.class, "illegal-arg");
     private static final Meter EXPECTED_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "expected-error");
+            MetricsUtil.registerMeter(API.class, "expected-error");
     private static final Meter UNKNOWN_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "unknown-error");
+            MetricsUtil.registerMeter(API.class, "unknown-error");
 
     public static HugeGraph graph(GraphManager manager, String graph) {
         HugeGraph g = manager.graph(graph);
         if (g == null) {
             throw new NotFoundException(String.format(
-                      "Graph '%s' does not exist",  graph));
+                    "Graph '%s' does not exist", graph));

Review Comment:
   prefer to keep the origin alignment



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");
     private static final Meter ILLEGAL_ARG_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "illegal-arg");
+            MetricsUtil.registerMeter(API.class, "illegal-arg");
     private static final Meter EXPECTED_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "expected-error");
+            MetricsUtil.registerMeter(API.class, "expected-error");

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");
     private static final Meter ILLEGAL_ARG_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "illegal-arg");
+            MetricsUtil.registerMeter(API.class, "illegal-arg");
     private static final Meter EXPECTED_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "expected-error");
+            MetricsUtil.registerMeter(API.class, "expected-error");
     private static final Meter UNKNOWN_ERROR_METER =
-                         MetricsUtil.registerMeter(API.class, "unknown-error");
+            MetricsUtil.registerMeter(API.class, "unknown-error");

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -141,7 +139,7 @@ protected static void checkUpdatingBody(Checkable body) {
     }
 
     protected static void checkCreatingBody(
-                          Collection<? extends Checkable> bodies) {
+            Collection<? extends Checkable> bodies) {

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -97,7 +95,7 @@ public static <R> R commit(HugeGraph g, Callable<R> callable) {
             SUCCEED_METER.mark();
             return result;
         } catch (IllegalArgumentException | NotFoundException |
-                 ForbiddenException e) {
+                ForbiddenException e) {

Review Comment:
   ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] JackyYangPassion commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "JackyYangPassion (via GitHub)" <gi...@apache.org>.
JackyYangPassion commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1337073467


##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -234,8 +259,8 @@ public void testMetricsBackend() {
                     String key = (String) e.getKey();
                     value = e.getValue();
                     Assert.assertTrue(String.format(
-                                      "Expect map value for key %s but got %s",
-                                      key, value),
+                                              "Expect map value for key %s but got %s",

Review Comment:
   prefer to keep the origin alignment



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1328054366


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -325,13 +323,12 @@ private String baseMetricPrometheusAll() {
             }
         }
 
-        MetricsUtil.writePrometheus(promMetric,
+        MetricsUtil.writePrometheusFormat(promMetric,

Review Comment:
   don't forget update the 327 alignment



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +176,244 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+    }
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";

Review Comment:
   also define a const var



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -49,6 +49,8 @@ public class API {
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
                                APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;

Review Comment:
   also align with APPLICATION_TEXT_WITH_CHARSET



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +176,244 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+

Review Comment:
   expect to remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -102,7 +102,7 @@ public static String replaceSlashInKey(String orgKey) {
         return orgKey.replace("/", "_");
     }
 
-    public static void writePrometheus(StringBuilder promeMetrics,
+    public static void writePrometheusFormat(StringBuilder promeMetrics,

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +176,244 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+    }
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";
+        //version
+        promMetric.append(STR_HELP)
+                  .append(helpName).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(helpName)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(helpName)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        //gauges
+        for (String key : reporter.gauges().keySet()) {
+            final com.codahale.metrics.Gauge<?> gauge

Review Comment:
   can we remove final mark and import com.codahale.metrics.Gauge as possible



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,83 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.api.filter.PathFilter.REQUEST_TIME;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+

Review Comment:
   expect to remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -24,12 +24,45 @@
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Snapshot;
 import com.codahale.metrics.Timer;
 
 public class MetricsUtil {
 
-    private static final MetricRegistry REGISTRY =
-                                        MetricManager.INSTANCE.getRegistry();
+    public static final String METRICS_PATH_TOTAL_COUNTER = "TOTAL_COUNTER";
+    public static final String METRICS_PATH_FAILED_COUNTER = "FAILED_COUNTER";
+    public static final String METRICS_PATH_SUCCESS_COUNTER = "SUCCESS_COUNTER";
+    public static final String METRICS_PATH_RESPONSE_TIME_HISTOGRAM =
+            "RESPONSE_TIME_HISTOGRAM";
+    public static final String P75_ATTR = "{name=\"p75\",} ";
+    public static final String P95_ATTR = "{name=\"p95\",} ";
+    public static final String P98_ATTR = "{name=\"p98\",} ";
+    public static final String P99_ATTR = "{name=\"p99\",} ";
+    public static final String P999_ATTR = "{name=\"p999\",} ";
+    public static final String MEAN_RATE_ATRR = "{name=\"mean_rate\",} ";
+    public static final String ONE_MIN_RATE_ATRR = "{name=\"m1_rate\",} ";
+    public static final String FIVE_MIN_RATE_ATRR = "{name=\"m5_rate\",} ";
+    public static final String FIFT_MIN_RATE_ATRR = "{name=\"m15_rate\",} ";
+    public static final MetricRegistry REGISTRY =
+            MetricManager.INSTANCE.getRegistry();

Review Comment:
   seems one line is ok



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -97,7 +95,7 @@ public static <R> R commit(HugeGraph g, Callable<R> callable) {
             SUCCEED_METER.mark();
             return result;
         } catch (IllegalArgumentException | NotFoundException |
-                 ForbiddenException e) {
+                ForbiddenException e) {

Review Comment:
   not addressed comment



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -165,8 +190,8 @@ public void testMetricsBackend() {
                     String key = (String) e.getKey();
                     value = e.getValue();
                     Assert.assertTrue(String.format(
-                                      "Expect map value for key %s but got %s",
-                                      key, value),
+                                              "Expect map value for key %s but got %s",

Review Comment:
   not addressed: prefer to keep the origin alignment



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,145 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +176,244 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+    }
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";
+        //version
+        promMetric.append(STR_HELP)
+                  .append(helpName).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(helpName)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(helpName)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        //gauges
+        for (String key : reporter.gauges().keySet()) {
+            final com.codahale.metrics.Gauge<?> gauge
+                    = reporter.gauges().get(key);
+            if (gauge != null) {
+                helpName = replaceDotDashInKey(key);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promMetric.append(helpName)
+                          .append(SPACE_STR + gauge.getValue() + END_LSTR);
+            }
+        }
+
+        //histograms
+        for (String histogramkey : reporter.histograms().keySet()) {
+            final Histogram histogram = reporter.histograms().get(histogramkey);
+            if (histogram != null) {
+                helpName = replaceDotDashInKey(histogramkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(histogram.getCount() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, histogram.getSnapshot()));
+            }
+        }
+
+        //meters
+        for (String meterkey : reporter.meters().keySet()) {
+            final Meter metric = reporter.meters().get(meterkey);
+            if (metric != null) {
+                helpName = replaceDotDashInKey(meterkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(metric.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(MEAN_RATE_ATRR)
+                          .append(metric.getMeanRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(metric.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(metric.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(metric.getFifteenMinuteRate() + END_LSTR);
+            }
+        }
+
+        //timer

Review Comment:
   note expected "// xx" style, and it's better to add more details for these comments



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +176,244 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+    }
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";
+        //version
+        promMetric.append(STR_HELP)
+                  .append(helpName).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(helpName)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(helpName)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        //gauges
+        for (String key : reporter.gauges().keySet()) {
+            final com.codahale.metrics.Gauge<?> gauge
+                    = reporter.gauges().get(key);
+            if (gauge != null) {
+                helpName = replaceDotDashInKey(key);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promMetric.append(helpName)
+                          .append(SPACE_STR + gauge.getValue() + END_LSTR);
+            }
+        }
+
+        //histograms
+        for (String histogramkey : reporter.histograms().keySet()) {
+            final Histogram histogram = reporter.histograms().get(histogramkey);
+            if (histogram != null) {
+                helpName = replaceDotDashInKey(histogramkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(histogram.getCount() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, histogram.getSnapshot()));
+            }
+        }
+
+        //meters
+        for (String meterkey : reporter.meters().keySet()) {
+            final Meter metric = reporter.meters().get(meterkey);
+            if (metric != null) {
+                helpName = replaceDotDashInKey(meterkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(metric.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(MEAN_RATE_ATRR)
+                          .append(metric.getMeanRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(metric.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(metric.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(metric.getFifteenMinuteRate() + END_LSTR);
+            }
+        }
+
+        //timer
+        for (String timerkey : reporter.timers().keySet()) {
+            final com.codahale.metrics.Timer timer = reporter.timers()
+                                                             .get(timerkey);
+            if (timer != null) {
+                helpName = replaceDotDashInKey(timerkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(timer.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(timer.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(timer.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(timer.getFifteenMinuteRate() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, timer.getSnapshot()));
+            }
+        }
+
+        MetricsUtil.writePrometheusFormat(promMetric,
+                                    MetricManager.INSTANCE.getRegistry());
+
+        return promMetric.toString();
+    }
+
+    private Map<String, Map<String, Object>> statistics() {
+        Map<String, Map<String, Object>> metricsMap = new HashMap<>();
+        ServerReporter reporter = ServerReporter.instance();
+        for (Map.Entry<String, Histogram> entry : reporter.histograms().entrySet()) {
+            // entryKey = path/method/responseTimeHistogram
+            String entryKey = entry.getKey();
+            String[] split = entryKey.split("/");
+            String lastWord = split[split.length - 1];
+            if (!lastWord.equals(METRICS_PATH_RESPONSE_TIME_HISTOGRAM)) {
+                // original metrics dont report
+                continue;
+            }
+            // metricsName = path/method
+            String metricsName =
+                    entryKey.substring(0, entryKey.length() - lastWord.length() - 1);
+
+            Counter totalCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_TOTAL_COUNTER));
+            Counter failedCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_FAILED_COUNTER));
+            Counter successCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_SUCCESS_COUNTER));
+
+
+            Histogram histogram = entry.getValue();
+            Map<String, Object> entryMetricsMap = new HashMap<>();
+            entryMetricsMap.put(MetricsKeys.MAX_RESPONSE_TIME.name(),
+                                histogram.getSnapshot().getMax());
+            entryMetricsMap.put(MetricsKeys.MEAN_RESPONSE_TIME.name(),
+                                histogram.getSnapshot().getMean());
+
+            entryMetricsMap.put(MetricsKeys.TOTAL_REQUEST.name(),
+                                totalCounter.getCount());
+
+            if (failedCounter == null) {
+                entryMetricsMap.put(MetricsKeys.FAILED_REQUEST.name(), 0);
+            } else {
+                entryMetricsMap.put(MetricsKeys.FAILED_REQUEST.name(),
+                                    failedCounter.getCount());
+            }
+
+            if (successCounter == null) {
+                entryMetricsMap.put(MetricsKeys.SUCCESS_REQUEST.name(), 0);
+            } else {
+                entryMetricsMap.put(MetricsKeys.SUCCESS_REQUEST.name(),
+                                    successCounter.getCount());
+            }
+
+            metricsMap.put(metricsName, entryMetricsMap);
+
+        }
+        return metricsMap;
+    }
+
+    private String statisticsProm(Map<String, Map<String, Object>> metricMap) {
+        StringBuilder promMetric = new StringBuilder();
+
+        //version

Review Comment:
   ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] SunnyBoy-WYH commented on pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "SunnyBoy-WYH (via GitHub)" <gi...@apache.org>.
SunnyBoy-WYH commented on PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#issuecomment-1689237627

   > @SunnyBoy-WYH seems CI failed? could check the CI status in your **personal repo** (submit a PR to your repo, u could check/test CI there)
   
   Nice idea! ( when i push this pr, the local test passed, and a few days before i am looking for the ci problem,but ci info not enough.) i will try it again.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] SunnyBoy-WYH commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "SunnyBoy-WYH (via GitHub)" <gi...@apache.org>.
SunnyBoy-WYH commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1338287717


##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -234,8 +259,8 @@ public void testMetricsBackend() {
                     String key = (String) e.getKey();
                     value = e.getValue();
                     Assert.assertTrue(String.format(
-                                      "Expect map value for key %s but got %s",
-                                      key, value),
+                                              "Expect map value for key %s but got %s",

Review Comment:
   seems done? if we choose all commit
   ![image](https://github.com/apache/incubator-hugegraph/assets/48077841/bd8d8020-5e47-4b5b-922e-13bae6ff912a)
   



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -234,8 +259,8 @@ public void testMetricsBackend() {
                     String key = (String) e.getKey();
                     value = e.getValue();
                     Assert.assertTrue(String.format(
-                                      "Expect map value for key %s but got %s",
-                                      key, value),
+                                              "Expect map value for key %s but got %s",

Review Comment:
   seems done? if we choose all commit
   ![image](https://github.com/apache/incubator-hugegraph/assets/48077841/bd8d8020-5e47-4b5b-922e-13bae6ff912a)
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] codecov[bot] commented on pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#issuecomment-1712699804

   ## [Codecov](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   > Merging [#2286](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) (7e51963) into [master](https://app.codecov.io/gh/apache/incubator-hugegraph/commit/d12f5734e64a56fd45c9fe09c1f277acf83af2e2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) (d12f573) will **decrease** coverage by `19.71%`.
   > Report is 5 commits behind head on master.
   > The diff coverage is `52.78%`.
   
   ```diff
   @@              Coverage Diff              @@
   ##             master    #2286       +/-   ##
   =============================================
   - Coverage     68.60%   48.90%   -19.71%     
   + Complexity      979      654      -325     
   =============================================
     Files           498      501        +3     
     Lines         41240    41477      +237     
     Branches       5738     5735        -3     
   =============================================
   - Hits          28294    20283     -8011     
   - Misses        10211    19017     +8806     
   + Partials       2735     2177      -558     
   ```
   
   
   | [Files Changed](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [...pi/src/main/java/org/apache/hugegraph/api/API.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL2FwaS9BUEkuamF2YQ==) | `70.00% <ø> (ø)` | |
   | [...java/org/apache/hugegraph/metrics/MetricsKeys.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL21ldHJpY3MvTWV0cmljc0tleXMuamF2YQ==) | `0.00% <0.00%> (ø)` | |
   | [...a/org/apache/hugegraph/api/metrics/MetricsAPI.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL2FwaS9tZXRyaWNzL01ldHJpY3NBUEkuamF2YQ==) | `29.44% <24.55%> (-36.35%)` | :arrow_down: |
   | [...java/org/apache/hugegraph/metrics/MetricsUtil.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL21ldHJpY3MvTWV0cmljc1V0aWwuamF2YQ==) | `90.38% <92.85%> (+27.88%)` | :arrow_up: |
   | [...g/apache/hugegraph/api/filter/AccessLogFilter.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL2FwaS9maWx0ZXIvQWNjZXNzTG9nRmlsdGVyLmphdmE=) | `100.00% <100.00%> (ø)` | |
   | [...va/org/apache/hugegraph/api/filter/PathFilter.java](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-aHVnZWdyYXBoLWFwaS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvaHVnZWdyYXBoL2FwaS9maWx0ZXIvUGF0aEZpbHRlci5qYXZh) | `100.00% <100.00%> (ø)` | |
   
   ... and [210 files with indirect coverage changes](https://app.codecov.io/gh/apache/incubator-hugegraph/pull/2286/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   
   :mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] imbajin commented on pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "imbajin (via GitHub)" <gi...@apache.org>.
imbajin commented on PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#issuecomment-1689231138

   @SunnyBoy-WYH seems CI failed? could check the CI status in your **personal repo** (submit a PR to your repo, u could check/test CI there)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


Re: [PR] feat(api): support metric API Prometheus format & add statistic metric api [incubator-hugegraph]

Posted by "JackyYangPassion (via GitHub)" <gi...@apache.org>.
JackyYangPassion merged PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1327964696


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,247 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+

Review Comment:
   remove the blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,247 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+    }
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";
+        //version
+        promMetric.append(STR_HELP)
+                  .append(helpName).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(helpName)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(helpName)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        //gauges
+        for (String key : reporter.gauges().keySet()) {
+            final com.codahale.metrics.Gauge<?> gauge
+                    = reporter.gauges().get(key);
+            if (gauge != null) {
+                helpName = replaceDotDashInKey(key);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promMetric.append(helpName)
+                          .append(SPACE_STR + gauge.getValue() + END_LSTR);
+            }
+        }
+
+        //histograms
+        for (String histogramkey : reporter.histograms().keySet()) {
+            final Histogram histogram = reporter.histograms().get(histogramkey);
+            if (histogram != null) {
+                helpName = replaceDotDashInKey(histogramkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(histogram.getCount() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, histogram.getSnapshot()));
+            }
+        }
+
+        //meters
+        for (String meterkey : reporter.meters().keySet()) {
+            final Meter metric = reporter.meters().get(meterkey);
+            if (metric != null) {
+                helpName = replaceDotDashInKey(meterkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(metric.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(MEAN_RATE_ATRR)
+                          .append(metric.getMeanRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(metric.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(metric.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(metric.getFifteenMinuteRate() + END_LSTR);
+            }
+        }
+
+        //timer
+        for (String timerkey : reporter.timers().keySet()) {
+            final com.codahale.metrics.Timer timer = reporter.timers()
+                                                             .get(timerkey);
+            if (timer != null) {
+                helpName = replaceDotDashInKey(timerkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(timer.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(timer.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(timer.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(timer.getFifteenMinuteRate() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, timer.getSnapshot()));
+            }
+        }
+
+        MetricsUtil.writePrometheus(promMetric,
+                                    MetricManager.INSTANCE.getRegistry());
+
+        return promMetric.toString();
+    }
+
+

Review Comment:
   remove a blank line



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -17,20 +17,24 @@
 
 package org.apache.hugegraph.api;
 
+import java.util.HashMap;
 import java.util.Map;
 
-import jakarta.ws.rs.core.Response;
+import org.apache.hugegraph.testutil.Assert;
 import org.junit.Test;
 
-import org.apache.hugegraph.testutil.Assert;
+import jakarta.ws.rs.core.Response;
 
 public class MetricsApiTest extends BaseApiTest {
 
-    private static String path = "/metrics";
+    private static final String path = "/metrics";
+    private static final String statistics_path = path + "/statistics";

Review Comment:
   rename the var name to statisticsPath style



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -24,12 +24,45 @@
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Snapshot;
 import com.codahale.metrics.Timer;
 
 public class MetricsUtil {
 
-    private static final MetricRegistry REGISTRY =
-                                        MetricManager.INSTANCE.getRegistry();
+    public static final String METRICS_PATH_TOTAL_COUNTER = "TOTAL_COUNTER";

Review Comment:
   does these name will be showed to users? if yes please rename to total_counter style?



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,145 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+
     public static Meter registerMeter(Class<?> clazz, String name) {
         return REGISTRY.meter(MetricRegistry.name(clazz, name));
     }
 
     public static Timer registerTimer(Class<?> clazz, String name) {
         return REGISTRY.timer(MetricRegistry.name(clazz, name));
     }
+
+    public static String replaceDotDashInKey(String orgKey) {
+        return orgKey.replace(".", "_").replace("-", "_");
+    }
+
+    public static String replaceSlashInKey(String orgKey) {
+        return orgKey.replace("/", "_");
+    }
+
+    public static void writePrometheus(StringBuilder promeMetrics,

Review Comment:
   writePrometheusFormat



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,145 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+

Review Comment:
   remove a blank line



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -17,20 +17,24 @@
 
 package org.apache.hugegraph.api;
 
+import java.util.HashMap;
 import java.util.Map;
 
-import jakarta.ws.rs.core.Response;
+import org.apache.hugegraph.testutil.Assert;
 import org.junit.Test;
 
-import org.apache.hugegraph.testutil.Assert;
+import jakarta.ws.rs.core.Response;
 
 public class MetricsApiTest extends BaseApiTest {
 
-    private static String path = "/metrics";
+    private static final String path = "/metrics";
+    private static final String statistics_path = path + "/statistics";
 
     @Test
-    public void testMetricsAll() {
-        Response r = client().get(path);
+    public void testBaseMetricsAll() {
+        Map<String, Object> params = new HashMap<>();
+        params.put("type", "json");
+        Response r = client().get(path,params);

Review Comment:
   expect a space after the "path,"



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsKeys.java:
##########
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hugegraph.metrics;
+
+public enum MetricsKeys {
+    // 最大响应时间 Maximum response time
+    // 平均响应时间 Mean response time
+    // 请求总数 Total Requests
+    // 失败数   Failed Requests
+    // 成功数   Success Requests

Review Comment:
   remove unused comments or translate them?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] SunnyBoy-WYH commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "SunnyBoy-WYH (via GitHub)" <gi...@apache.org>.
SunnyBoy-WYH commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1296871026


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java:
##########
@@ -22,55 +22,53 @@
 import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 
-import jakarta.ws.rs.ForbiddenException;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.NotSupportedException;
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.hugegraph.HugeException;
+import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.core.GraphManager;
 import org.apache.hugegraph.define.Checkable;
 import org.apache.hugegraph.metrics.MetricsUtil;
-import org.slf4j.Logger;
-
-import org.apache.hugegraph.HugeException;
-import org.apache.hugegraph.HugeGraph;
 import org.apache.hugegraph.util.E;
 import org.apache.hugegraph.util.JsonUtil;
 import org.apache.hugegraph.util.Log;
+import org.slf4j.Logger;
+
 import com.codahale.metrics.Meter;
 import com.google.common.collect.ImmutableMap;
 
-public class API {
+import jakarta.ws.rs.ForbiddenException;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.core.MediaType;
 
-    protected static final Logger LOG = Log.logger(API.class);
+public class API {
 
     public static final String CHARSET = "UTF-8";
-
     public static final String TEXT_PLAIN = MediaType.TEXT_PLAIN;
     public static final String APPLICATION_JSON = MediaType.APPLICATION_JSON;
     public static final String APPLICATION_JSON_WITH_CHARSET =
-                               APPLICATION_JSON + ";charset=" + CHARSET;
+            APPLICATION_JSON + ";charset=" + CHARSET;
+    public static final String APPLICATION_TEXT_WITH_CHARSET =
+            MediaType.TEXT_PLAIN + ";charset=" + CHARSET;
     public static final String JSON = MediaType.APPLICATION_JSON_TYPE
-                                               .getSubtype();
-
+            .getSubtype();
     public static final String ACTION_APPEND = "append";
     public static final String ACTION_ELIMINATE = "eliminate";
     public static final String ACTION_CLEAR = "clear";
-
+    protected static final Logger LOG = Log.logger(API.class);
     private static final Meter SUCCEED_METER =
-                         MetricsUtil.registerMeter(API.class, "commit-succeed");
+            MetricsUtil.registerMeter(API.class, "commit-succeed");

Review Comment:
   okay,i used hg-code-style.xml with idea ,so it auto format when save.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1320685171


##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,147 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+
     public static Meter registerMeter(Class<?> clazz, String name) {
         return REGISTRY.meter(MetricRegistry.name(clazz, name));
     }
 
     public static Timer registerTimer(Class<?> clazz, String name) {
         return REGISTRY.timer(MetricRegistry.name(clazz, name));
     }
+
+    public static String replaceDotDashInKey(String orgKey) {
+        return orgKey.replace(".", "_").replace("-", "_");
+    }
+
+    public static String replaceSlashInKey(String orgKey) {
+        return orgKey.replace("/", "_");
+    }
+
+    public static void writePrometheus(StringBuilder promeMetrics,
+                                       MetricRegistry registry) {
+        // gauges
+        registry.getGauges().forEach((key, gauge) -> {
+            if (gauge != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promeMetrics.append(helpName).append(SPACE_STR).append(gauge.getValue())
+                            .append(END_LSTR);
+            }
+        });
+
+        // histograms
+        registry.getHistograms().forEach((key, histogram) -> {
+            if (histogram != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(histogram.getCount()).append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshort(helpName, histogram.getSnapshot()));
+            }
+        });
+
+        // meters
+        registry.getMeters().forEach((key, metric) -> {
+            if (metric != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(metric.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(MEAN_RATE_ATRR).append(metric.getMeanRate()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(metric.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(metric.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(metric.getFifteenMinuteRate())
+                            .append(END_LSTR);
+            }
+        });
+
+        // timer
+        registry.getTimers().forEach((key, timer) -> {
+            if (timer != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(timer.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(timer.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(timer.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(timer.getFifteenMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshort(helpName, timer.getSnapshot()));
+            }
+        });
+    }
+
+    public static String exportSnapshort(final String helpName, final Snapshot snapshot) {
+        if (snapshot != null) {
+            StringBuilder snapMetrics = new StringBuilder();
+            snapMetrics.append(helpName)
+                       .append(MIN_ATTR).append(snapshot.getMin()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(MAX_ATTR).append(snapshot.getMax()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(MEAN_ATTR).append(snapshot.getMean()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(STDDEV_ATTR).append(snapshot.getStdDev()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P50_ATTR).append(snapshot.getMedian()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P75_ATTR).append(snapshot.get75thPercentile()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P95_ATTR).append(snapshot.get95thPercentile()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P98_ATTR).append(snapshot.get98thPercentile()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P99_ATTR).append(snapshot.get99thPercentile()).append(END_LSTR);
+            snapMetrics.append(helpName)
+                       .append(P999_ATTR).append(snapshot.get999thPercentile()).append(END_LSTR);
+            return snapMetrics.toString();
+        }
+        return "";
+    }
+
+

Review Comment:
   remove the 2 blank lines



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+
+    }
+
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+
+    private static final String DELIMETER = "/";
+
+    /**
+     * Use filter to log request info
+     *
+     * @param requestContext  requestContext
+     * @param responseContext responseContext
+     */
+    @Override
+    public void filter(ContainerRequestContext requestContext,
+                       ContainerResponseContext responseContext)
+            throws IOException {
+        // Grab corresponding request / response info from context;
+        String method = requestContext.getRequest().getMethod();
+        String path = requestContext.getUriInfo().getPath();
+        String metricsName = join(path, method);
+
+        MetricsUtil.registerCounter(
+                           join(metricsName, METRICS_PATH_TOTAL_COUNTER))

Review Comment:
   seems we can move to the previous line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java:
##########
@@ -0,0 +1,41 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import java.io.IOException;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Singleton
+@PreMatching
+public class PathFilter implements ContainerRequestFilter {
+
+
+    @Override
+    public void filter(ContainerRequestContext context)
+            throws IOException {
+
+        context.setProperty("RequestTime", System.currentTimeMillis());
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsKeys.java:
##########
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.hugegraph.metrics;
+
+public enum MetricsKeys {
+    // 最大响应时间 Maximum response time
+    // 平均响应时间 Mean response time
+    // 请求总数 Total Requests
+    // 失败数   Failed Requests
+    // 成功数   Success Requests

Review Comment:
   remove unused comments or translate them?



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,147 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+
     public static Meter registerMeter(Class<?> clazz, String name) {
         return REGISTRY.meter(MetricRegistry.name(clazz, name));
     }
 
     public static Timer registerTimer(Class<?> clazz, String name) {
         return REGISTRY.timer(MetricRegistry.name(clazz, name));
     }
+
+    public static String replaceDotDashInKey(String orgKey) {
+        return orgKey.replace(".", "_").replace("-", "_");
+    }
+
+    public static String replaceSlashInKey(String orgKey) {
+        return orgKey.replace("/", "_");
+    }
+
+    public static void writePrometheus(StringBuilder promeMetrics,
+                                       MetricRegistry registry) {
+        // gauges
+        registry.getGauges().forEach((key, gauge) -> {
+            if (gauge != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promeMetrics.append(helpName).append(SPACE_STR).append(gauge.getValue())
+                            .append(END_LSTR);
+            }
+        });
+
+        // histograms
+        registry.getHistograms().forEach((key, histogram) -> {
+            if (histogram != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(histogram.getCount()).append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshort(helpName, histogram.getSnapshot()));
+            }
+        });
+
+        // meters
+        registry.getMeters().forEach((key, metric) -> {
+            if (metric != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(metric.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(MEAN_RATE_ATRR).append(metric.getMeanRate()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(metric.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(metric.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(metric.getFifteenMinuteRate())
+                            .append(END_LSTR);
+            }
+        });
+
+        // timer
+        registry.getTimers().forEach((key, timer) -> {
+            if (timer != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(timer.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(timer.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(timer.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(timer.getFifteenMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshort(helpName, timer.getSnapshot()));
+            }
+        });
+    }
+
+    public static String exportSnapshort(final String helpName, final Snapshot snapshot) {

Review Comment:
   exportSnapshort => exportSnapshot



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+
+    private static final String DELIMETER = "/";
+
+    /**
+     * Use filter to log request info
+     *
+     * @param requestContext  requestContext
+     * @param responseContext responseContext
+     */
+    @Override
+    public void filter(ContainerRequestContext requestContext,
+                       ContainerResponseContext responseContext)
+            throws IOException {

Review Comment:
   prefer to align with ContainerResponseContext



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,147 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+

Review Comment:
   remove a blank line



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -17,20 +17,24 @@
 
 package org.apache.hugegraph.api;
 
+import java.util.HashMap;
 import java.util.Map;
 
-import jakarta.ws.rs.core.Response;
+import org.apache.hugegraph.testutil.Assert;
 import org.junit.Test;
 
-import org.apache.hugegraph.testutil.Assert;
+import jakarta.ws.rs.core.Response;
 
 public class MetricsApiTest extends BaseApiTest {
 
-    private static String path = "/metrics";
+    private static final String path = "/metrics";
+    private static final String statistics_path = path + "/statistics";
 
     @Test
-    public void testMetricsAll() {
-        Response r = client().get(path);
+    public void testBaseMetricsAll() {
+        Map<String, Object> params = new HashMap<>();
+        params.put("type", "json");
+        Response r = client().get(path,params);

Review Comment:
   expect a space after the ","



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -24,12 +24,45 @@
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Snapshot;
 import com.codahale.metrics.Timer;
 
 public class MetricsUtil {
 
-    private static final MetricRegistry REGISTRY =
-                                        MetricManager.INSTANCE.getRegistry();
+    public static final String METRICS_PATH_TOTAL_COUNTER = "TOTAL_COUNTER";

Review Comment:
   does these name will be showed to users? if yes please rename to total_counter style?



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+
+    }
+
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,147 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+
     public static Meter registerMeter(Class<?> clazz, String name) {
         return REGISTRY.meter(MetricRegistry.name(clazz, name));
     }
 
     public static Timer registerTimer(Class<?> clazz, String name) {
         return REGISTRY.timer(MetricRegistry.name(clazz, name));
     }
+
+    public static String replaceDotDashInKey(String orgKey) {
+        return orgKey.replace(".", "_").replace("-", "_");
+    }
+
+    public static String replaceSlashInKey(String orgKey) {
+        return orgKey.replace("/", "_");
+    }
+
+    public static void writePrometheus(StringBuilder promeMetrics,

Review Comment:
   writePrometheusFormat



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -17,20 +17,24 @@
 
 package org.apache.hugegraph.api;
 
+import java.util.HashMap;
 import java.util.Map;
 
-import jakarta.ws.rs.core.Response;
+import org.apache.hugegraph.testutil.Assert;
 import org.junit.Test;
 
-import org.apache.hugegraph.testutil.Assert;
+import jakarta.ws.rs.core.Response;
 
 public class MetricsApiTest extends BaseApiTest {
 
-    private static String path = "/metrics";
+    private static final String path = "/metrics";
+    private static final String statistics_path = path + "/statistics";

Review Comment:
   statisticsPath



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java:
##########
@@ -0,0 +1,41 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import java.io.IOException;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Singleton
+@PreMatching
+public class PathFilter implements ContainerRequestFilter {
+
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+
+    private static final String DELIMETER = "/";
+
+    /**
+     * Use filter to log request info
+     *
+     * @param requestContext  requestContext
+     * @param responseContext responseContext
+     */
+    @Override
+    public void filter(ContainerRequestContext requestContext,
+                       ContainerResponseContext responseContext)
+            throws IOException {
+        // Grab corresponding request / response info from context;
+        String method = requestContext.getRequest().getMethod();
+        String path = requestContext.getUriInfo().getPath();
+        String metricsName = join(path, method);
+
+        MetricsUtil.registerCounter(
+                           join(metricsName, METRICS_PATH_TOTAL_COUNTER))
+                   .inc();
+        if (responseContext.getStatus() == 200 ||
+            responseContext.getStatus() == 201 ||
+            responseContext.getStatus() == 202) {
+            MetricsUtil.registerCounter(
+                               join(metricsName, METRICS_PATH_SUCCESS_COUNTER))

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+
+    private static final String DELIMETER = "/";
+
+    /**
+     * Use filter to log request info
+     *
+     * @param requestContext  requestContext
+     * @param responseContext responseContext
+     */
+    @Override
+    public void filter(ContainerRequestContext requestContext,
+                       ContainerResponseContext responseContext)
+            throws IOException {
+        // Grab corresponding request / response info from context;
+        String method = requestContext.getRequest().getMethod();
+        String path = requestContext.getUriInfo().getPath();
+        String metricsName = join(path, method);
+
+        MetricsUtil.registerCounter(
+                           join(metricsName, METRICS_PATH_TOTAL_COUNTER))
+                   .inc();
+        if (responseContext.getStatus() == 200 ||
+            responseContext.getStatus() == 201 ||
+            responseContext.getStatus() == 202) {
+            MetricsUtil.registerCounter(
+                               join(metricsName, METRICS_PATH_SUCCESS_COUNTER))
+                       .inc();
+        } else {
+            MetricsUtil.registerCounter(
+                               join(metricsName, METRICS_PATH_FAILED_COUNTER))
+                       .inc();
+        }
+
+        //  get responseTime

Review Comment:
   expect just one space after "//"



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java:
##########
@@ -0,0 +1,41 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import java.io.IOException;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Singleton
+@PreMatching
+public class PathFilter implements ContainerRequestFilter {
+
+
+    @Override
+    public void filter(ContainerRequestContext context)
+            throws IOException {
+
+        context.setProperty("RequestTime", System.currentTimeMillis());

Review Comment:
   expect request_time style



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_SUCCESS_COUNTER;
+import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_TOTAL_COUNTER;
+
+import java.io.IOException;
+
+import org.apache.hugegraph.metrics.MetricsUtil;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.ext.Provider;
+
+
+@Provider
+@Singleton
+public class AccessLogFilter implements ContainerResponseFilter {
+
+
+    private static final String DELIMETER = "/";
+
+    /**
+     * Use filter to log request info
+     *
+     * @param requestContext  requestContext
+     * @param responseContext responseContext
+     */
+    @Override
+    public void filter(ContainerRequestContext requestContext,
+                       ContainerResponseContext responseContext)
+            throws IOException {
+        // Grab corresponding request / response info from context;
+        String method = requestContext.getRequest().getMethod();
+        String path = requestContext.getUriInfo().getPath();
+        String metricsName = join(path, method);
+
+        MetricsUtil.registerCounter(
+                           join(metricsName, METRICS_PATH_TOTAL_COUNTER))
+                   .inc();
+        if (responseContext.getStatus() == 200 ||
+            responseContext.getStatus() == 201 ||
+            responseContext.getStatus() == 202) {

Review Comment:
   add a method `boolean statusOK(status)`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org


[GitHub] [incubator-hugegraph] javeme commented on a diff in pull request #2286: feat(api): support metric API Prometheus format & add statistic metric api

Posted by "javeme (via GitHub)" <gi...@apache.org>.
javeme commented on code in PR #2286:
URL: https://github.com/apache/incubator-hugegraph/pull/2286#discussion_r1324632529


##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java:
##########
@@ -0,0 +1,40 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import java.io.IOException;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Singleton
+@PreMatching
+public class PathFilter implements ContainerRequestFilter {
+
+    @Override
+    public void filter(ContainerRequestContext context)
+            throws IOException {
+
+        context.setProperty("request_time", System.currentTimeMillis());

Review Comment:
   can we define a const var for "request_time"?



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java:
##########
@@ -0,0 +1,40 @@
+/*
+ * 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.hugegraph.api.filter;
+
+import java.io.IOException;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Singleton
+@PreMatching
+public class PathFilter implements ContainerRequestFilter {
+
+    @Override
+    public void filter(ContainerRequestContext context)
+            throws IOException {
+
+        context.setProperty("request_time", System.currentTimeMillis());
+

Review Comment:
   remove a blank line



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+
+    }
+
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+
+    }
+
+

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java:
##########
@@ -158,4 +177,253 @@ public String timers() {
         ServerReporter reporter = ServerReporter.instance();
         return JsonUtil.toJson(reporter.timers());
     }
+
+
+    @GET
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String all(@Context GraphManager manager,
+                      @QueryParam("type") String type) {
+
+        if (type != null && type.equals(JSON_STR)) {
+            return baseMetricAll();
+        } else {
+            return baseMetricPrometheusAll();
+        }
+    }
+
+    @GET
+    @Path("statistics")
+    @Timed
+    @Produces(APPLICATION_TEXT_WITH_CHARSET)
+    @RolesAllowed({"admin", "$owner= $action=metrics_read"})
+    public String statistics(@QueryParam("type") String type) {
+        Map<String, Map<String, Object>> metricMap = statistics();
+
+        if (type != null && type.equals(JSON_STR)) {
+            return JsonUtil.toJson(metricMap);
+        }
+        return statisticsProm(metricMap);
+
+    }
+
+
+    public String baseMetricAll() {
+        ServerReporter reporter = ServerReporter.instance();
+        Map<String, Map<String, ? extends Metric>> result = new LinkedHashMap<>();
+        result.put("gauges", reporter.gauges());
+        result.put("counters", reporter.counters());
+        result.put("histograms", reporter.histograms());
+        result.put("meters", reporter.meters());
+        result.put("timers", reporter.timers());
+        return JsonUtil.toJson(result);
+    }
+
+    private String baseMetricPrometheusAll() {
+
+        StringBuilder promMetric = new StringBuilder();
+        ServerReporter reporter = ServerReporter.instance();
+        String helpName = "hugegraph_info";
+        //version
+        promMetric.append(STR_HELP)
+                  .append(helpName).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(helpName)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(helpName)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        //gauges
+        for (String key : reporter.gauges().keySet()) {
+            final com.codahale.metrics.Gauge<?> gauge
+                    = reporter.gauges().get(key);
+            if (gauge != null) {
+                helpName = replaceDotDashInKey(key);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promMetric.append(helpName)
+                          .append(SPACE_STR + gauge.getValue() + END_LSTR);
+            }
+        }
+
+        //histograms
+        for (String histogramkey : reporter.histograms().keySet()) {
+            final Histogram histogram = reporter.histograms().get(histogramkey);
+            if (histogram != null) {
+                helpName = replaceDotDashInKey(histogramkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(histogram.getCount() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, histogram.getSnapshot()));
+            }
+        }
+
+
+        //meters
+        for (String meterkey : reporter.meters().keySet()) {
+            final Meter metric = reporter.meters().get(meterkey);
+            if (metric != null) {
+                helpName = replaceDotDashInKey(meterkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(metric.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(MEAN_RATE_ATRR)
+                          .append(metric.getMeanRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(metric.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(metric.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(metric.getFifteenMinuteRate() + END_LSTR);
+            }
+        }
+
+        //timer
+        for (String timerkey : reporter.timers().keySet()) {
+            final com.codahale.metrics.Timer timer = reporter.timers()
+                                                             .get(timerkey);
+            if (timer != null) {
+                helpName = replaceDotDashInKey(timerkey);
+                promMetric.append(STR_HELP)
+                          .append(helpName).append(END_LSTR);
+                promMetric.append(STR_TYPE)
+                          .append(helpName)
+                          .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promMetric.append(helpName)
+                          .append(COUNT_ATTR)
+                          .append(timer.getCount() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(ONE_MIN_RATE_ATRR)
+                          .append(timer.getOneMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIVE_MIN_RATE_ATRR)
+                          .append(timer.getFiveMinuteRate() + END_LSTR);
+                promMetric.append(helpName)
+                          .append(FIFT_MIN_RATE_ATRR)
+                          .append(timer.getFifteenMinuteRate() + END_LSTR);
+                promMetric.append(
+                        exportSnapshot(helpName, timer.getSnapshot()));
+            }
+        }
+
+        MetricsUtil.writePrometheus(promMetric,
+                                    MetricManager.INSTANCE.getRegistry());
+
+        return promMetric.toString();
+    }
+
+
+    private Map<String, Map<String, Object>> statistics() {
+        Map<String, Map<String, Object>> metricsMap = new HashMap<>();
+        ServerReporter reporter = ServerReporter.instance();
+        for (Map.Entry<String, Histogram> entry : reporter.histograms().entrySet()) {
+            // entryKey = path/method/responseTimeHistogram
+            String entryKey = entry.getKey();
+            String[] split = entryKey.split("/");
+            String lastWord = split[split.length - 1];
+            if (!lastWord.equals(METRICS_PATH_RESPONSE_TIME_HISTOGRAM)) {
+                // original metrics dont report
+                continue;
+            }
+            // metricsName = path/method
+            String metricsName =
+                    entryKey.substring(0, entryKey.length() - lastWord.length() - 1);
+
+            Counter totalCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_TOTAL_COUNTER));
+            Counter failedCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_FAILED_COUNTER));
+            Counter successCounter = reporter.counters().get(
+                    joinWithSlash(metricsName, METRICS_PATH_SUCCESS_COUNTER));
+
+
+            Histogram histogram = entry.getValue();
+            Map<String, Object> entryMetricsMap = new HashMap<>();
+            entryMetricsMap.put(MetricsKeys.MAX_RESPONSE_TIME.name(),
+                                histogram.getSnapshot().getMax());
+            entryMetricsMap.put(MetricsKeys.MEAN_RESPONSE_TIME.name(),
+                                histogram.getSnapshot().getMean());
+
+            entryMetricsMap.put(MetricsKeys.TOTAL_REQUEST.name(),
+                                totalCounter.getCount());
+
+            if (failedCounter == null) {
+                entryMetricsMap.put(MetricsKeys.FAILED_REQUEST.name(), 0);
+            } else {
+                entryMetricsMap.put(MetricsKeys.FAILED_REQUEST.name(),
+                                    failedCounter.getCount());
+            }
+
+            if (successCounter == null) {
+                entryMetricsMap.put(MetricsKeys.SUCCESS_REQUEST.name(), 0);
+            } else {
+                entryMetricsMap.put(MetricsKeys.SUCCESS_REQUEST.name(),
+                                    successCounter.getCount());
+            }
+
+            metricsMap.put(metricsName, entryMetricsMap);
+
+        }
+        return metricsMap;
+    }
+
+
+    private String statisticsProm(Map<String, Map<String, Object>> metricMap) {
+        StringBuilder promMetric = new StringBuilder();
+
+        //version
+        promMetric.append(STR_HELP)
+                  .append(PROM_HELP_NAME).append(END_LSTR);
+        promMetric.append(STR_TYPE)
+                  .append(PROM_HELP_NAME)
+                  .append(SPACE_STR + UNTYPED + END_LSTR);
+        promMetric.append(PROM_HELP_NAME)
+                  .append("{version=\"")
+                  .append(ApiVersion.VERSION.toString()).append("\",}")
+                  .append(SPACE_STR + "1.0" + END_LSTR);
+
+        for (String methodKey : metricMap.keySet()) {
+            String metricName = replaceSlashInKey(methodKey);
+            promMetric.append(STR_HELP)
+                      .append(metricName).append(END_LSTR);
+            promMetric.append(STR_TYPE)
+                      .append(metricName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+            Map<String, Object> itemMetricMap = metricMap.get(methodKey);
+            for (String labelName : itemMetricMap.keySet()) {
+                promMetric.append(metricName).append(LEFT_NAME_STR).append(labelName)
+                          .append(RIGHT_NAME_STR).append(itemMetricMap.get(labelName))
+                          .append(END_LSTR);
+            }
+        }
+        return promMetric.toString();
+    }
+
+    private String joinWithSlash(String path1, String path2) {
+        return String.join("/", path1, path2);
+    }
+
+

Review Comment:
   ditto



##########
hugegraph-test/src/main/java/org/apache/hugegraph/api/MetricsApiTest.java:
##########
@@ -39,6 +43,27 @@ public void testMetricsAll() {
         assertJsonContains(result, "timers");
     }
 
+    @Test
+    public void testBaseMetricsPromAll() {
+        Response r = client().get(path);
+        assertResponseStatus(200, r);
+    }
+
+    @Test
+    public void testStatisticsMetricsAll() {
+        Map<String, String> params = new HashMap<>();
+        params.put("type", "json");
+        Response r = client().get(path);
+        assertResponseStatus(200, r);
+    }
+
+    @Test
+    public void testStatisticsMetricsPromAll() {
+        Response r = client().get(statistics_path);
+        assertResponseStatus(200, r);
+    }
+
+

Review Comment:
   ditto



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsUtil.java:
##########
@@ -40,15 +73,146 @@ public static Counter registerCounter(Class<?> clazz, String name) {
         return REGISTRY.counter(MetricRegistry.name(clazz, name));
     }
 
+    public static Counter registerCounter(String name) {
+        return REGISTRY.counter(MetricRegistry.name(name));
+    }
+
     public static Histogram registerHistogram(Class<?> clazz, String name) {
         return REGISTRY.histogram(MetricRegistry.name(clazz, name));
     }
 
+    public static Histogram registerHistogram(String name) {
+        return REGISTRY.histogram(name);
+    }
+
+
     public static Meter registerMeter(Class<?> clazz, String name) {
         return REGISTRY.meter(MetricRegistry.name(clazz, name));
     }
 
     public static Timer registerTimer(Class<?> clazz, String name) {
         return REGISTRY.timer(MetricRegistry.name(clazz, name));
     }
+
+    public static String replaceDotDashInKey(String orgKey) {
+        return orgKey.replace(".", "_").replace("-", "_");
+    }
+
+    public static String replaceSlashInKey(String orgKey) {
+        return orgKey.replace("/", "_");
+    }
+
+    public static void writePrometheus(StringBuilder promeMetrics,
+                                       MetricRegistry registry) {
+        // gauges
+        registry.getGauges().forEach((key, gauge) -> {
+            if (gauge != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName).append(SPACE_STR + GAUGE_TYPE + END_LSTR);
+                promeMetrics.append(helpName).append(SPACE_STR).append(gauge.getValue())
+                            .append(END_LSTR);
+            }
+        });
+
+        // histograms
+        registry.getHistograms().forEach((key, histogram) -> {
+            if (histogram != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(histogram.getCount()).append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshot(helpName, histogram.getSnapshot()));
+            }
+        });
+
+        // meters
+        registry.getMeters().forEach((key, metric) -> {
+            if (metric != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(metric.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(MEAN_RATE_ATRR).append(metric.getMeanRate()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(metric.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(metric.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(metric.getFifteenMinuteRate())
+                            .append(END_LSTR);
+            }
+        });
+
+        // timer
+        registry.getTimers().forEach((key, timer) -> {
+            if (timer != null) {
+                String helpName = replaceDotDashInKey(key);
+                promeMetrics.append(STR_HELP)
+                            .append(helpName).append(END_LSTR);
+                promeMetrics.append(STR_TYPE)
+                            .append(helpName)
+                            .append(SPACE_STR + HISTOGRAM_TYPE + END_LSTR);
+
+                promeMetrics.append(helpName)
+                            .append(COUNT_ATTR).append(timer.getCount()).append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(ONE_MIN_RATE_ATRR).append(timer.getOneMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIVE_MIN_RATE_ATRR).append(timer.getFiveMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(helpName)
+                            .append(FIFT_MIN_RATE_ATRR).append(timer.getFifteenMinuteRate())
+                            .append(END_LSTR);
+                promeMetrics.append(
+                        exportSnapshot(helpName, timer.getSnapshot()));
+            }
+        });
+    }
+
+    public static String exportSnapshot(final String helpName, final Snapshot snapshot) {
+        if (snapshot != null) {

Review Comment:
   return first if if (snapshot == null)



##########
hugegraph-api/src/main/java/org/apache/hugegraph/metrics/MetricsKeys.java:
##########
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     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.hugegraph.metrics;
+
+public enum MetricsKeys {
+    // 最大响应时间 Maximum response time
+    // 平均响应时间 Mean response time
+    // 请求总数 Total Requests
+    // 失败数   Failed Requests
+    // 成功数   Success Requests
+
+    MAX_RESPONSE_TIME(1, "MAX_RESPONSE_TIME"),
+
+    MEAN_RESPONSE_TIME(2, "MEAN_RESPONSE_TIME"),
+
+    TOTAL_REQUEST(3, "TOTAL_REQUEST"),
+
+    FAILED_REQUEST(4, "FAILED_REQUEST"),
+
+    SUCCESS_REQUEST(5, "SUCCESS_REQUEST"),
+    ;
+
+    private final byte code;
+    private final String name;
+
+

Review Comment:
   ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@hugegraph.apache.org
For additional commands, e-mail: issues-help@hugegraph.apache.org