You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/12/28 03:19:42 UTC

[GitHub] little-cui closed pull request #519: SCB-1092 More abundant metrics information

little-cui closed pull request #519: SCB-1092 More abundant metrics information
URL: https://github.com/apache/servicecomb-service-center/pull/519
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/integration/health-metrics-grafana.json b/integration/health-metrics-grafana.json
index 7b435ba3..0cf10b1d 100644
--- a/integration/health-metrics-grafana.json
+++ b/integration/health-metrics-grafana.json
@@ -109,7 +109,7 @@
       },
       "gridPos": {
         "h": 3,
-        "w": 4,
+        "w": 3,
         "x": 0,
         "y": 0
       },
@@ -192,10 +192,10 @@
       "gridPos": {
         "h": 3,
         "w": 3,
-        "x": 4,
+        "x": 3,
         "y": 0
       },
-      "id": 26,
+      "id": 19,
       "interval": null,
       "links": [],
       "mappingType": 1,
@@ -233,7 +233,7 @@
       "tableColumn": "",
       "targets": [
         {
-          "expr": "max(service_center_db_domain_total{job=\"service-center\"})",
+          "expr": "max(service_center_db_backend_total{job=\"service-center\"})",
           "format": "time_series",
           "instant": false,
           "intervalFactor": 2,
@@ -241,7 +241,7 @@
         }
       ],
       "thresholds": "",
-      "title": "Domain Volume",
+      "title": "Backends",
       "type": "singlestat",
       "valueFontSize": "80%",
       "valueMaps": [
@@ -263,7 +263,7 @@
       "gridPos": {
         "h": 5,
         "w": 8,
-        "x": 7,
+        "x": 6,
         "y": 0
       },
       "height": "",
@@ -358,7 +358,7 @@
       "gridPos": {
         "h": 5,
         "w": 9,
-        "x": 15,
+        "x": 14,
         "y": 0
       },
       "id": 25,
@@ -412,11 +412,11 @@
       },
       "gridPos": {
         "h": 3,
-        "w": 4,
+        "w": 3,
         "x": 0,
         "y": 3
       },
-      "id": 19,
+      "id": 26,
       "interval": null,
       "links": [],
       "mappingType": 1,
@@ -454,7 +454,7 @@
       "tableColumn": "",
       "targets": [
         {
-          "expr": "max(service_center_db_backend_total{job=\"service-center\"})",
+          "expr": "max(service_center_db_domain_total{job=\"service-center\"})",
           "format": "time_series",
           "instant": false,
           "intervalFactor": 2,
@@ -462,7 +462,7 @@
         }
       ],
       "thresholds": "",
-      "title": "Backends",
+      "title": "Domain Volume",
       "type": "singlestat",
       "valueFontSize": "80%",
       "valueMaps": [
@@ -495,10 +495,10 @@
       "gridPos": {
         "h": 3,
         "w": 3,
-        "x": 4,
+        "x": 3,
         "y": 3
       },
-      "id": 20,
+      "id": 21,
       "interval": null,
       "links": [],
       "mappingType": 1,
@@ -533,10 +533,10 @@
         "lineColor": "rgb(31, 120, 193)",
         "show": false
       },
-      "tableColumn": "",
+      "tableColumn": "Value",
       "targets": [
         {
-          "expr": "max(sum(service_center_db_service_total{job=\"service-center\"}) by (instance))",
+          "expr": "max(service_center_db_instance_total{job=\"service-center\"})",
           "format": "time_series",
           "instant": false,
           "intervalFactor": 2,
@@ -544,7 +544,7 @@
         }
       ],
       "thresholds": "",
-      "title": "Microservice Volume",
+      "title": "Instance Volume",
       "type": "singlestat",
       "valueFontSize": "80%",
       "valueMaps": [
@@ -566,7 +566,7 @@
       "gridPos": {
         "h": 5,
         "w": 8,
-        "x": 7,
+        "x": 6,
         "y": 5
       },
       "height": "",
@@ -663,7 +663,7 @@
       "gridPos": {
         "h": 5,
         "w": 3,
-        "x": 15,
+        "x": 14,
         "y": 5
       },
       "id": 31,
@@ -712,7 +712,7 @@
       "gridPos": {
         "h": 5,
         "w": 3,
-        "x": 18,
+        "x": 17,
         "y": 5
       },
       "id": 32,
@@ -761,7 +761,7 @@
       "gridPos": {
         "h": 5,
         "w": 3,
-        "x": 21,
+        "x": 20,
         "y": 5
       },
       "id": 33,
@@ -816,10 +816,92 @@
       "gridPos": {
         "h": 3,
         "w": 3,
-        "x": 4,
+        "x": 0,
         "y": 6
       },
-      "id": 21,
+      "id": 20,
+      "interval": null,
+      "links": [],
+      "mappingType": 1,
+      "mappingTypes": [
+        {
+          "name": "value to text",
+          "value": 1
+        },
+        {
+          "name": "range to text",
+          "value": 2
+        }
+      ],
+      "maxDataPoints": 100,
+      "minSpan": 4,
+      "nullPointMode": "connected",
+      "nullText": null,
+      "postfix": "",
+      "postfixFontSize": "50%",
+      "prefix": "",
+      "prefixFontSize": "50%",
+      "rangeMaps": [
+        {
+          "from": "null",
+          "text": "N/A",
+          "to": "null"
+        }
+      ],
+      "sparkline": {
+        "fillColor": "rgba(31, 118, 189, 0.18)",
+        "full": true,
+        "lineColor": "rgb(31, 120, 193)",
+        "show": false
+      },
+      "tableColumn": "",
+      "targets": [
+        {
+          "expr": "max(sum(service_center_db_service_total{job=\"service-center\"}) by (instance))",
+          "format": "time_series",
+          "instant": false,
+          "intervalFactor": 2,
+          "refId": "A"
+        }
+      ],
+      "thresholds": "",
+      "title": "Microservice Volume",
+      "type": "singlestat",
+      "valueFontSize": "80%",
+      "valueMaps": [
+        {
+          "op": "=",
+          "text": "N/A",
+          "value": "null"
+        }
+      ],
+      "valueName": "current"
+    },
+    {
+      "cacheTimeout": null,
+      "colorBackground": false,
+      "colorValue": false,
+      "colors": [
+        "#299c46",
+        "rgba(237, 129, 40, 0.89)",
+        "#d44a3a"
+      ],
+      "datasource": "${DS_LOCAL}",
+      "format": "none",
+      "gauge": {
+        "maxValue": 100,
+        "minValue": 0,
+        "show": false,
+        "thresholdLabels": false,
+        "thresholdMarkers": true
+      },
+      "gridPos": {
+        "h": 3,
+        "w": 3,
+        "x": 3,
+        "y": 6
+      },
+      "id": 39,
       "interval": null,
       "links": [],
       "mappingType": 1,
@@ -857,7 +939,7 @@
       "tableColumn": "Value",
       "targets": [
         {
-          "expr": "max(service_center_db_instance_total{job=\"service-center\"})",
+          "expr": "max(service_center_db_schema_total{job=\"service-center\"})",
           "format": "time_series",
           "instant": false,
           "intervalFactor": 2,
@@ -865,7 +947,7 @@
         }
       ],
       "thresholds": "",
-      "title": "Instance Volume",
+      "title": "Schema Volume",
       "type": "singlestat",
       "valueFontSize": "80%",
       "valueMaps": [
@@ -1402,6 +1484,96 @@
         "alignLevel": null
       }
     },
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "${DS_LOCAL}",
+      "fill": 1,
+      "gridPos": {
+        "h": 6,
+        "w": 8,
+        "x": 8,
+        "y": 19
+      },
+      "height": "",
+      "id": 34,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": true,
+        "max": true,
+        "min": true,
+        "show": true,
+        "sort": null,
+        "sortDesc": null,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 1,
+      "links": [],
+      "minSpan": 4,
+      "nullPointMode": "null",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "expr": "max(avg_over_time(service_center_db_heartbeat_durations_microseconds{job=\"service-center\"}[1m])) by (status)",
+          "format": "time_series",
+          "instant": false,
+          "intervalFactor": 2,
+          "legendFormat": "{{status}}",
+          "refId": "A"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Heartbeat Latency",
+      "tooltip": {
+        "shared": true,
+        "sort": 0,
+        "value_type": "individual"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "µs",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
     {
       "content": "<div class=\"text-center dashboard-header\">\n  <span>INSTANCE METRICS</span>\n</div>\n",
       "gridPos": {
@@ -1569,6 +1741,13 @@
           "intervalFactor": 2,
           "legendFormat": "{{instance}}> {{method}} {{api}}",
           "refId": "A"
+        },
+        {
+          "expr": "sum(irate(service_center_db_heartbeat_total{job=\"service-center\"}[1m])) by (instance)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> RENEW Lease",
+          "refId": "B"
         }
       ],
       "thresholds": [],
@@ -1667,7 +1846,7 @@
       "thresholds": [],
       "timeFrom": null,
       "timeShift": null,
-      "title": "Read Latency",
+      "title": "API Read Latency",
       "tooltip": {
         "shared": true,
         "sort": 0,
@@ -1756,12 +1935,19 @@
           "intervalFactor": 2,
           "legendFormat": "{{instance}}> {{method}} {{api}}",
           "refId": "A"
+        },
+        {
+          "expr": "max(avg_over_time(service_center_db_heartbeat_durations_microseconds{job=\"service-center\"}[1m])) by (instance)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> RENEW Lease",
+          "refId": "B"
         }
       ],
       "thresholds": [],
       "timeFrom": null,
       "timeShift": null,
-      "title": "Write Latency",
+      "title": "API Write Latency",
       "tooltip": {
         "shared": true,
         "sort": 0,
@@ -1800,13 +1986,403 @@
       }
     },
     {
-      "content": "<div class=\"text-center dashboard-header\">\n  <span>RESOURCES</span>\n</div>\n",
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "${DS_LOCAL}",
+      "fill": 1,
       "gridPos": {
-        "h": 3,
-        "w": 24,
+        "h": 6,
+        "w": 6,
         "x": 0,
         "y": 34
       },
+      "height": "",
+      "id": 35,
+      "legend": {
+        "alignAsTable": false,
+        "avg": false,
+        "current": false,
+        "hideEmpty": true,
+        "hideZero": true,
+        "max": false,
+        "min": false,
+        "rightSide": false,
+        "show": false,
+        "sort": "avg",
+        "sortDesc": true,
+        "total": false,
+        "values": false
+      },
+      "lines": true,
+      "linewidth": 1,
+      "links": [],
+      "minSpan": 4,
+      "nullPointMode": "null",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "expr": "sum(service_center_notify_publish_total{job=\"service-center\"}) by (instance,source)",
+          "format": "time_series",
+          "instant": false,
+          "intervalFactor": 2,
+          "legendFormat": "{{instance}}> {{source}}",
+          "refId": "A"
+        },
+        {
+          "expr": "sum(service_center_db_backend_event_total{job=\"service-center\"}) by (instance)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> BACKEND",
+          "refId": "B"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Events Total",
+      "tooltip": {
+        "shared": true,
+        "sort": 0,
+        "value_type": "individual"
+      },
+      "transparent": false,
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "decimals": 0,
+          "format": "none",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "${DS_LOCAL}",
+      "fill": 1,
+      "gridPos": {
+        "h": 6,
+        "w": 6,
+        "x": 6,
+        "y": 34
+      },
+      "height": "",
+      "id": 36,
+      "legend": {
+        "alignAsTable": false,
+        "avg": true,
+        "current": false,
+        "hideEmpty": true,
+        "hideZero": true,
+        "max": true,
+        "min": true,
+        "rightSide": true,
+        "show": false,
+        "sort": "avg",
+        "sortDesc": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 1,
+      "links": [],
+      "minSpan": 4,
+      "nullPointMode": "null",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "expr": "max(avg_over_time(service_center_notify_publish_durations_microseconds{job=\"service-center\"}[1m])) by (instance,source)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> {{source}}",
+          "refId": "B"
+        },
+        {
+          "expr": "max(avg_over_time(service_center_db_backend_event_durations_microseconds{job=\"service-center\"}[1m])) by (instance)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> BACKEND",
+          "refId": "A"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Events Latency",
+      "tooltip": {
+        "shared": true,
+        "sort": 0,
+        "value_type": "individual"
+      },
+      "transparent": false,
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "µs",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "${DS_LOCAL}",
+      "fill": 1,
+      "gridPos": {
+        "h": 6,
+        "w": 6,
+        "x": 12,
+        "y": 34
+      },
+      "height": "",
+      "id": 37,
+      "legend": {
+        "alignAsTable": false,
+        "avg": false,
+        "current": false,
+        "hideEmpty": true,
+        "hideZero": true,
+        "max": false,
+        "min": false,
+        "rightSide": false,
+        "show": false,
+        "sort": "avg",
+        "sortDesc": true,
+        "total": false,
+        "values": false
+      },
+      "lines": true,
+      "linewidth": 1,
+      "links": [],
+      "minSpan": 4,
+      "nullPointMode": "null",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "expr": "sum(service_center_db_backend_operation_total{job=\"service-center\"}) by (instance,operation)",
+          "format": "time_series",
+          "instant": false,
+          "intervalFactor": 2,
+          "legendFormat": "{{instance}}> {{operation}}",
+          "refId": "A"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Backend Operation Total",
+      "tooltip": {
+        "shared": true,
+        "sort": 0,
+        "value_type": "individual"
+      },
+      "transparent": false,
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "decimals": 0,
+          "format": "none",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "${DS_LOCAL}",
+      "fill": 1,
+      "gridPos": {
+        "h": 6,
+        "w": 6,
+        "x": 18,
+        "y": 34
+      },
+      "height": "",
+      "id": 38,
+      "legend": {
+        "alignAsTable": false,
+        "avg": true,
+        "current": false,
+        "hideEmpty": true,
+        "hideZero": true,
+        "max": true,
+        "min": true,
+        "rightSide": true,
+        "show": false,
+        "sort": "avg",
+        "sortDesc": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 1,
+      "links": [],
+      "minSpan": 4,
+      "nullPointMode": "null",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "expr": "max(avg_over_time(service_center_db_backend_operation_durations_microseconds{job=\"service-center\"}[1m])) by (instance,operation)",
+          "format": "time_series",
+          "intervalFactor": 1,
+          "legendFormat": "{{instance}}> {{operation}}",
+          "refId": "B"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeShift": null,
+      "title": "Backend Operation Latency",
+      "tooltip": {
+        "shared": true,
+        "sort": 0,
+        "value_type": "individual"
+      },
+      "transparent": false,
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "µs",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "label": null,
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "content": "<div class=\"text-center dashboard-header\">\n  <span>RESOURCES</span>\n</div>\n",
+      "gridPos": {
+        "h": 3,
+        "w": 24,
+        "x": 0,
+        "y": 40
+      },
       "height": "1px",
       "id": 4,
       "links": [],
@@ -1826,7 +2402,7 @@
         "h": 7,
         "w": 8,
         "x": 0,
-        "y": 37
+        "y": 43
       },
       "height": "",
       "id": 2,
@@ -1915,7 +2491,7 @@
         "h": 7,
         "w": 8,
         "x": 8,
-        "y": 37
+        "y": 43
       },
       "height": "",
       "id": 9,
@@ -2002,7 +2578,7 @@
         "h": 7,
         "w": 8,
         "x": 16,
-        "y": 37
+        "y": 43
       },
       "height": "",
       "id": 8,
@@ -2089,7 +2665,7 @@
         "h": 7,
         "w": 8,
         "x": 0,
-        "y": 44
+        "y": 50
       },
       "id": 5,
       "legend": {
@@ -2174,7 +2750,7 @@
         "h": 7,
         "w": 8,
         "x": 8,
-        "y": 44
+        "y": 50
       },
       "id": 6,
       "legend": {
@@ -2259,7 +2835,7 @@
         "h": 7,
         "w": 8,
         "x": 16,
-        "y": 44
+        "y": 50
       },
       "id": 14,
       "legend": {
@@ -2344,7 +2920,7 @@
         "h": 7,
         "w": 24,
         "x": 0,
-        "y": 51
+        "y": 57
       },
       "id": 7,
       "legend": {
@@ -2437,7 +3013,7 @@
     "list": []
   },
   "time": {
-    "from": "now-5m",
+    "from": "now-15m",
     "to": "now"
   },
   "timepicker": {
@@ -2468,5 +3044,5 @@
   "timezone": "",
   "title": "ServiceCenter",
   "uid": "Zg6NoHGiz",
-  "version": 47
+  "version": 15
 }
\ No newline at end of file
diff --git a/pkg/etcdsync/mutex.go b/pkg/etcdsync/mutex.go
index 4f0c53bc..94e7acd1 100644
--- a/pkg/etcdsync/mutex.go
+++ b/pkg/etcdsync/mutex.go
@@ -34,6 +34,8 @@ const (
 	DEFAULT_LOCK_TTL    = 60
 	DEFAULT_RETRY_TIMES = 3
 	ROOT_PATH           = "/cse/etcdsync"
+
+	OperationGlobalLock = "GLOBAL_LOCK"
 )
 
 type DLockFactory struct {
@@ -44,8 +46,9 @@ type DLockFactory struct {
 }
 
 type DLock struct {
-	builder *DLockFactory
-	id      string
+	builder  *DLockFactory
+	id       string
+	createAt time.Time
 }
 
 var (
@@ -77,9 +80,11 @@ func (m *DLockFactory) NewDLock(wait bool) (l *DLock, err error) {
 	if !IsDebug {
 		m.mutex.Lock()
 	}
+	now := time.Now()
 	l = &DLock{
-		builder: m,
-		id:      fmt.Sprintf("%v-%v-%v", hostname, pid, time.Now().Format("20060102-15:04:05.999999999")),
+		builder:  m,
+		id:       fmt.Sprintf("%v-%v-%v", hostname, pid, now.Format("20060102-15:04:05.999999999")),
+		createAt: now,
 	}
 	for try := 1; try <= DEFAULT_RETRY_TIMES; try++ {
 		err = l.Lock(wait)
@@ -168,6 +173,7 @@ func (m *DLock) Unlock() (err error) {
 		if !IsDebug {
 			m.builder.mutex.Unlock()
 		}
+		registry.ReportBackendOperationCompleted(OperationGlobalLock, nil, m.createAt)
 	}()
 
 	opts := []registry.PluginOpOption{
diff --git a/pkg/notify/notice.go b/pkg/notify/notice.go
index 836d47bd..87c0862b 100644
--- a/pkg/notify/notice.go
+++ b/pkg/notify/notice.go
@@ -16,16 +16,20 @@
  */
 package notify
 
+import "time"
+
 type Event interface {
 	Type() Type
 	Subject() string // required!
 	Group() string   // broadcast all the subscriber of the same subject if group is empty
+	CreateAt() time.Time
 }
 
 type baseEvent struct {
-	nType   Type
-	subject string
-	group   string
+	nType    Type
+	subject  string
+	group    string
+	createAt time.Time
 }
 
 func (s *baseEvent) Type() Type {
@@ -40,6 +44,10 @@ func (s *baseEvent) Group() string {
 	return s.group
 }
 
+func (s *baseEvent) CreateAt() time.Time {
+	return s.createAt
+}
+
 func NewEvent(t Type, s string, g string) Event {
-	return &baseEvent{t, s, g}
+	return &baseEvent{t, s, g, time.Now()}
 }
diff --git a/pkg/notify/notification_test.go b/pkg/notify/notification_test.go
index f130c270..9b6a06c5 100644
--- a/pkg/notify/notification_test.go
+++ b/pkg/notify/notification_test.go
@@ -59,7 +59,7 @@ func TestGetNotifyService(t *testing.T) {
 	if err != nil {
 		t.Fatalf("TestGetNotifyService failed, %v", err)
 	}
-	j := &baseEvent{INSTANCE, "s", "g"}
+	j := &baseEvent{INSTANCE, "s", "g", time.Now()}
 	err = notifyService.Publish(j)
 	if err != nil {
 		t.Fatalf("TestGetNotifyService failed")
diff --git a/server/core/backend/lease.go b/server/core/backend/lease.go
index 6d3eef91..5c6c2b35 100644
--- a/server/core/backend/lease.go
+++ b/server/core/backend/lease.go
@@ -44,6 +44,7 @@ func (lat *LeaseTask) Key() string {
 func (lat *LeaseTask) Do(ctx context.Context) (err error) {
 	recv, start := lat.ReceiveTime(), time.Now()
 	lat.TTL, err = lat.Client.LeaseRenew(ctx, lat.LeaseID)
+	ReportHeartbeatCompleted(err, recv)
 	if err != nil {
 		log.Errorf(err, "[%s]task[%s] renew lease[%d] failed(recv: %s, send: %s)",
 			time.Now().Sub(recv),
diff --git a/server/core/backend/metrics.go b/server/core/backend/metrics.go
index d20d21a7..81507669 100644
--- a/server/core/backend/metrics.go
+++ b/server/core/backend/metrics.go
@@ -19,6 +19,12 @@ package backend
 import (
 	"github.com/apache/servicecomb-service-center/server/metric"
 	"github.com/prometheus/client_golang/prometheus"
+	"time"
+)
+
+const (
+	success = "SUCCESS"
+	failure = "FAILURE"
 )
 
 var (
@@ -29,13 +35,41 @@ var (
 			Name:      "sc_total",
 			Help:      "Counter of the Service Center instance",
 		}, []string{"instance"})
+
+	heartbeatCounter = prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Namespace: metric.FamilyName,
+			Subsystem: "db",
+			Name:      "heartbeat_total",
+			Help:      "Counter of heartbeat renew",
+		}, []string{"instance", "status"})
+
+	heartbeatLatency = prometheus.NewSummaryVec(
+		prometheus.SummaryOpts{
+			Namespace:  metric.FamilyName,
+			Subsystem:  "db",
+			Name:       "heartbeat_durations_microseconds",
+			Help:       "Latency of heartbeat renew",
+			Objectives: prometheus.DefObjectives,
+		}, []string{"instance", "status"})
 )
 
 func init() {
-	prometheus.MustRegister(scCounter)
+	prometheus.MustRegister(scCounter, heartbeatCounter, heartbeatLatency)
 }
 
 func ReportScInstance() {
 	instance := metric.InstanceName()
 	scCounter.WithLabelValues(instance).Add(1)
 }
+
+func ReportHeartbeatCompleted(err error, start time.Time) {
+	instance := metric.InstanceName()
+	elapsed := float64(time.Since(start).Nanoseconds()) / float64(time.Microsecond)
+	status := success
+	if err != nil {
+		status = failure
+	}
+	heartbeatLatency.WithLabelValues(instance, status).Observe(elapsed)
+	heartbeatCounter.WithLabelValues(instance, status).Inc()
+}
diff --git a/server/notify/metrics.go b/server/notify/metrics.go
new file mode 100644
index 00000000..eac4c524
--- /dev/null
+++ b/server/notify/metrics.go
@@ -0,0 +1,61 @@
+// 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 notify
+
+import (
+	"github.com/apache/servicecomb-service-center/server/metric"
+	"github.com/prometheus/client_golang/prometheus"
+	"time"
+)
+
+const (
+	success = "SUCCESS"
+	failure = "FAILURE"
+)
+
+var (
+	notifyCounter = prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Namespace: metric.FamilyName,
+			Subsystem: "notify",
+			Name:      "publish_total",
+			Help:      "Counter of publishing instance events",
+		}, []string{"instance", "source", "status"})
+
+	notifyLatency = prometheus.NewSummaryVec(
+		prometheus.SummaryOpts{
+			Namespace:  metric.FamilyName,
+			Subsystem:  "notify",
+			Name:       "publish_durations_microseconds",
+			Help:       "Latency of publishing instance events",
+			Objectives: prometheus.DefObjectives,
+		}, []string{"instance", "source", "status"})
+)
+
+func init() {
+	prometheus.MustRegister(notifyCounter, notifyLatency)
+}
+
+func ReportPublishCompleted(source string, err error, start time.Time) {
+	instance := metric.InstanceName()
+	elapsed := float64(time.Since(start).Nanoseconds()) / float64(time.Microsecond)
+	status := success
+	if err != nil {
+		status = failure
+	}
+	notifyLatency.WithLabelValues(instance, source, status).Observe(elapsed)
+	notifyCounter.WithLabelValues(instance, source, status).Inc()
+}
diff --git a/server/notify/stream.go b/server/notify/stream.go
index 0bc17cdd..0e4e2d71 100644
--- a/server/notify/stream.go
+++ b/server/notify/stream.go
@@ -49,6 +49,7 @@ func HandleWatchJob(watcher *InstanceEventListWatcher, stream pb.ServiceInstance
 				watcher.Subject(), watcher.Group())
 
 			err = stream.Send(resp)
+			ReportPublishCompleted(INSTANCE.String(), err, job.CreateAt())
 			if err != nil {
 				log.Errorf(err, "send message error, subject: %s, group: %s",
 					watcher.Subject(), watcher.Group())
diff --git a/server/notify/websocket.go b/server/notify/websocket.go
index 64f62035..2f0a6d8e 100644
--- a/server/notify/websocket.go
+++ b/server/notify/websocket.go
@@ -169,8 +169,11 @@ func (wh *WebSocket) Pick() interface{} {
 func (wh *WebSocket) HandleWatchWebSocketJob(o interface{}) {
 	defer wh.SetReady()
 
-	remoteAddr := wh.conn.RemoteAddr().String()
-	var message []byte
+	var (
+		job        *InstanceEvent
+		message    []byte
+		remoteAddr = wh.conn.RemoteAddr().String()
+	)
 
 	switch o.(type) {
 	case error:
@@ -195,7 +198,7 @@ func (wh *WebSocket) HandleWatchWebSocketJob(o interface{}) {
 		wh.heartbeat(websocket.PingMessage)
 		return
 	case *InstanceEvent:
-		job := o.(*InstanceEvent)
+		job = o.(*InstanceEvent)
 		resp := job.Response
 
 		providerFlag := fmt.Sprintf("%s/%s/%s", resp.Key.AppId, resp.Key.ServiceName, resp.Key.Version)
@@ -227,6 +230,9 @@ func (wh *WebSocket) HandleWatchWebSocketJob(o interface{}) {
 	}
 
 	err := wh.conn.WriteMessage(websocket.TextMessage, message)
+	if job != nil {
+		ReportPublishCompleted(INSTANCE.String(), err, job.CreateAt())
+	}
 	if err != nil {
 		log.Errorf(err, "watcher[%s] catch an err, subject: %s, group: %s",
 			remoteAddr, wh.watcher.Subject(), wh.watcher.Group())
diff --git a/server/plugin/pkg/discovery/etcd/cacher_kv.go b/server/plugin/pkg/discovery/etcd/cacher_kv.go
index 6ea25d86..aa82b42f 100644
--- a/server/plugin/pkg/discovery/etcd/cacher_kv.go
+++ b/server/plugin/pkg/discovery/etcd/cacher_kv.go
@@ -367,6 +367,7 @@ func (c *KvCacher) deferHandle(ctx context.Context) {
 }
 
 func (c *KvCacher) onEvents(evts []discovery.KvEvent) {
+	start := time.Now()
 	init := !c.IsReady()
 	for i, evt := range evts {
 		key := util.BytesToStringWithNoCopy(evt.KV.Key)
@@ -403,6 +404,8 @@ func (c *KvCacher) onEvents(evts []discovery.KvEvent) {
 	}
 
 	c.notify(evts)
+
+	discovery.ReportProcessEventCompleted(evts, start)
 }
 
 func (c *KvCacher) notify(evts []discovery.KvEvent) {
diff --git a/server/plugin/pkg/registry/etcd/metrics.go b/server/plugin/pkg/discovery/metrics.go
similarity index 55%
rename from server/plugin/pkg/registry/etcd/metrics.go
rename to server/plugin/pkg/discovery/metrics.go
index 90c8fdd0..4e3737b4 100644
--- a/server/plugin/pkg/registry/etcd/metrics.go
+++ b/server/plugin/pkg/discovery/metrics.go
@@ -14,28 +14,49 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package etcd
+package discovery
 
 import (
 	"github.com/apache/servicecomb-service-center/server/metric"
 	"github.com/prometheus/client_golang/prometheus"
+	"time"
+)
+
+const (
+	success = "SUCCESS"
+	failure = "FAILURE"
 )
 
 var (
-	backendCounter = prometheus.NewGaugeVec(
+	eventsCounter = prometheus.NewGaugeVec(
 		prometheus.GaugeOpts{
 			Namespace: metric.FamilyName,
 			Subsystem: "db",
-			Name:      "backend_total",
-			Help:      "Gauge of the backend instance",
+			Name:      "backend_event_total",
+			Help:      "Counter of backend events",
+		}, []string{"instance"})
+
+	eventsLatency = prometheus.NewSummaryVec(
+		prometheus.SummaryOpts{
+			Namespace:  metric.FamilyName,
+			Subsystem:  "db",
+			Name:       "backend_event_durations_microseconds",
+			Help:       "Latency of backend events processing",
+			Objectives: prometheus.DefObjectives,
 		}, []string{"instance"})
 )
 
 func init() {
-	prometheus.MustRegister(backendCounter)
+	prometheus.MustRegister(eventsCounter, eventsLatency)
 }
 
-func ReportBackendInstance(c int) {
+func ReportProcessEventCompleted(evts []KvEvent, start time.Time) {
+	l := float64(len(evts))
+	if l == 0 {
+		return
+	}
 	instance := metric.InstanceName()
-	backendCounter.WithLabelValues(instance).Set(float64(c))
+	elapsed := float64(time.Since(start).Nanoseconds()) / float64(time.Microsecond)
+	eventsLatency.WithLabelValues(instance).Observe(elapsed / l)
+	eventsCounter.WithLabelValues(instance).Add(l)
 }
diff --git a/server/plugin/pkg/registry/etcd/common.go b/server/plugin/pkg/registry/etcd/common.go
new file mode 100644
index 00000000..d8d9832f
--- /dev/null
+++ b/server/plugin/pkg/registry/etcd/common.go
@@ -0,0 +1,34 @@
+// 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 etcd
+
+import "time"
+
+const (
+	// here will new an etcd connection after about 30s(=5s * 3 + (backoff:8s))
+	// when the connected etcd member was hung but tcp is still alive
+	healthCheckTimeout    = 5 * time.Second
+	healthCheckRetryTimes = 3
+)
+
+const (
+	OperationCompact     = "COMPACT"
+	OperationTxn         = "TXN"
+	OperationLeaseGrant  = "LEASE_GRANT"
+	OperationLeaseRenew  = "LEASE_RENEW"
+	OperationLeaseRevoke = "LEASE_REVOKE"
+	OperationSyncMembers = "SYNC"
+)
diff --git a/server/plugin/pkg/registry/etcd/etcd.go b/server/plugin/pkg/registry/etcd/etcd.go
index 5dc3e5c7..9aca3bed 100644
--- a/server/plugin/pkg/registry/etcd/etcd.go
+++ b/server/plugin/pkg/registry/etcd/etcd.go
@@ -39,13 +39,6 @@ import (
 	"time"
 )
 
-const (
-	// here will new an etcd connection after about 30s(=5s * 3 + (backoff:8s))
-	// when the connected etcd member was hung but tcp is still alive
-	healthCheckTimeout    = 5 * time.Second
-	healthCheckRetryTimes = 3
-)
-
 var firstEndpoint string
 
 func init() {
@@ -133,7 +126,7 @@ func (c *EtcdClient) newClient() (*clientv3.Client, error) {
 		return nil, err
 	}
 
-	ReportBackendInstance(len(resp.Members))
+	registry.ReportBackendInstance(len(resp.Members))
 
 	if len(c.Endpoints) == 1 {
 		// no need to check remote endpoints
@@ -192,6 +185,7 @@ func (c *EtcdClient) Compact(ctx context.Context, reserve int64) error {
 
 	t := time.Now()
 	_, err := c.Client.Compact(ctx, revToCompact, clientv3.WithCompactPhysical())
+	registry.ReportBackendOperationCompleted(OperationCompact, err, t)
 	if err != nil {
 		log.Errorf(err, "compact %s failed, revision is %d(current: %d, reserve %d)",
 			eps, revToCompact, curRev, reserve)
@@ -460,12 +454,13 @@ func (c *EtcdClient) Do(ctx context.Context, opts ...registry.PluginOpOption) (*
 
 	start := time.Now()
 	op := registry.OptionsToOp(opts...)
-
 	span := TracingBegin(ctx, "etcd:do", op)
-	defer TracingEnd(span, err)
-
 	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
+	defer func() {
+		registry.ReportBackendOperationCompleted(op.Action.String(), err, start)
+		TracingEnd(span, err)
+		cancel()
+	}()
 
 	switch op.Action {
 	case registry.Get:
@@ -539,9 +534,6 @@ func (c *EtcdClient) Txn(ctx context.Context, opts []registry.PluginOp) (*regist
 func (c *EtcdClient) TxnWithCmp(ctx context.Context, success []registry.PluginOp, cmps []registry.CompareOp, fail []registry.PluginOp) (*registry.PluginResponse, error) {
 	var err error
 
-	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-
 	start := time.Now()
 	etcdCmps := c.toCompares(cmps)
 	etcdSuccessOps := c.toTxnRequest(success)
@@ -555,7 +547,12 @@ func (c *EtcdClient) TxnWithCmp(ctx context.Context, success []registry.PluginOp
 	}
 
 	span := TracingBegin(ctx, "etcd:txn", traceOps[0])
-	defer TracingEnd(span, err)
+	otCtx, cancel := registry.WithTimeout(ctx)
+	defer func() {
+		registry.ReportBackendOperationCompleted(OperationTxn, err, start)
+		TracingEnd(span, err)
+		cancel()
+	}()
 
 	kvc := clientv3.NewKV(c.Client)
 	txn := kvc.Txn(otCtx)
@@ -592,13 +589,16 @@ func (c *EtcdClient) TxnWithCmp(ctx context.Context, success []registry.PluginOp
 
 func (c *EtcdClient) LeaseGrant(ctx context.Context, TTL int64) (int64, error) {
 	var err error
+
+	start := time.Now()
 	span := TracingBegin(ctx, "etcd:grant",
 		registry.PluginOp{Action: registry.Put, Key: util.StringToBytesWithNoCopy(strconv.FormatInt(TTL, 10))})
-	defer TracingEnd(span, err)
-
 	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-	start := time.Now()
+	defer func() {
+		registry.ReportBackendOperationCompleted(OperationLeaseGrant, err, start)
+		TracingEnd(span, err)
+		cancel()
+	}()
 	etcdResp, err := c.Client.Grant(otCtx, TTL)
 	if err != nil {
 		return 0, err
@@ -609,13 +609,17 @@ func (c *EtcdClient) LeaseGrant(ctx context.Context, TTL int64) (int64, error) {
 
 func (c *EtcdClient) LeaseRenew(ctx context.Context, leaseID int64) (int64, error) {
 	var err error
+
+	start := time.Now()
 	span := TracingBegin(ctx, "etcd:keepalive",
 		registry.PluginOp{Action: registry.Put, Key: util.StringToBytesWithNoCopy(strconv.FormatInt(leaseID, 10))})
-	defer TracingEnd(span, err)
-
 	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-	start := time.Now()
+	defer func() {
+		registry.ReportBackendOperationCompleted(OperationLeaseRenew, err, start)
+		TracingEnd(span, err)
+		cancel()
+	}()
+
 	etcdResp, err := c.Client.KeepAliveOnce(otCtx, clientv3.LeaseID(leaseID))
 	if err != nil {
 		if err.Error() == grpc.ErrorDesc(rpctypes.ErrGRPCLeaseNotFound) {
@@ -629,13 +633,17 @@ func (c *EtcdClient) LeaseRenew(ctx context.Context, leaseID int64) (int64, erro
 
 func (c *EtcdClient) LeaseRevoke(ctx context.Context, leaseID int64) error {
 	var err error
+
+	start := time.Now()
 	span := TracingBegin(ctx, "etcd:revoke",
 		registry.PluginOp{Action: registry.Delete, Key: util.StringToBytesWithNoCopy(strconv.FormatInt(leaseID, 10))})
-	defer TracingEnd(span, err)
-
 	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-	start := time.Now()
+	defer func() {
+		registry.ReportBackendOperationCompleted(OperationLeaseRevoke, err, start)
+		TracingEnd(span, err)
+		cancel()
+	}()
+
 	_, err = c.Client.Revoke(otCtx, clientv3.LeaseID(leaseID))
 	if err != nil {
 		if err.Error() == grpc.ErrorDesc(rpctypes.ErrGRPCLeaseNotFound) {
@@ -767,7 +775,12 @@ func (c *EtcdClient) parseEndpoints() {
 }
 
 func (c *EtcdClient) SyncMembers(ctx context.Context) error {
-	if err := c.Client.Sync(ctx); err != nil && err != c.Client.Ctx().Err() {
+	var err error
+
+	start := time.Now()
+	defer registry.ReportBackendOperationCompleted(OperationSyncMembers, err, start)
+
+	if err = c.Client.Sync(ctx); err != nil && err != c.Client.Ctx().Err() {
 		return err
 	}
 	return nil
diff --git a/server/plugin/pkg/registry/metrics.go b/server/plugin/pkg/registry/metrics.go
new file mode 100644
index 00000000..d0fa6fce
--- /dev/null
+++ b/server/plugin/pkg/registry/metrics.go
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package registry
+
+import (
+	"github.com/apache/servicecomb-service-center/server/metric"
+	"github.com/prometheus/client_golang/prometheus"
+	"time"
+)
+
+const (
+	success = "SUCCESS"
+	failure = "FAILURE"
+)
+
+var (
+	backendCounter = prometheus.NewGaugeVec(
+		prometheus.GaugeOpts{
+			Namespace: metric.FamilyName,
+			Subsystem: "db",
+			Name:      "backend_total",
+			Help:      "Gauge of the backend instance",
+		}, []string{"instance"})
+
+	operationCounter = prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Namespace: metric.FamilyName,
+			Subsystem: "db",
+			Name:      "backend_operation_total",
+			Help:      "Counter of backend operation",
+		}, []string{"instance", "operation", "status"})
+
+	operationLatency = prometheus.NewSummaryVec(
+		prometheus.SummaryOpts{
+			Namespace:  metric.FamilyName,
+			Subsystem:  "db",
+			Name:       "backend_operation_durations_microseconds",
+			Help:       "Latency of backend operation",
+			Objectives: prometheus.DefObjectives,
+		}, []string{"instance", "operation", "status"})
+)
+
+func init() {
+	prometheus.MustRegister(backendCounter, operationCounter, operationLatency)
+}
+
+func ReportBackendInstance(c int) {
+	instance := metric.InstanceName()
+	backendCounter.WithLabelValues(instance).Set(float64(c))
+}
+
+func ReportBackendOperationCompleted(operation string, err error, start time.Time) {
+	instance := metric.InstanceName()
+	elapsed := float64(time.Since(start).Nanoseconds()) / float64(time.Microsecond)
+	status := success
+	if err != nil {
+		status = failure
+	}
+	operationLatency.WithLabelValues(instance, operation, status).Observe(elapsed)
+	operationCounter.WithLabelValues(instance, operation, status).Inc()
+}
diff --git a/server/service/event/event.go b/server/service/event/event.go
index 1472c4a0..9399105a 100644
--- a/server/service/event/event.go
+++ b/server/service/event/event.go
@@ -28,4 +28,5 @@ func init() {
 	discovery.AddEventHandler(NewTagEventHandler())
 	discovery.AddEventHandler(NewDependencyEventHandler())
 	discovery.AddEventHandler(NewDependencyRuleEventHandler())
+	discovery.AddEventHandler(NewSchemaSummaryEventHandler())
 }
diff --git a/server/service/event/schema_summary_event_handler.go b/server/service/event/schema_summary_event_handler.go
new file mode 100644
index 00000000..79d85f18
--- /dev/null
+++ b/server/service/event/schema_summary_event_handler.go
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package event
+
+import (
+	"github.com/apache/servicecomb-service-center/server/core"
+	"github.com/apache/servicecomb-service-center/server/core/backend"
+	pb "github.com/apache/servicecomb-service-center/server/core/proto"
+	"github.com/apache/servicecomb-service-center/server/plugin/pkg/discovery"
+	"github.com/apache/servicecomb-service-center/server/service/metrics"
+	"strings"
+)
+
+type SchemaSummaryEventHandler struct {
+}
+
+func (h *SchemaSummaryEventHandler) Type() discovery.Type {
+	return backend.SCHEMA_SUMMARY
+}
+
+func (h *SchemaSummaryEventHandler) OnEvent(evt discovery.KvEvent) {
+	action := evt.Type
+	switch action {
+	case pb.EVT_INIT, pb.EVT_CREATE, pb.EVT_DELETE:
+		domainProject, _, _ := core.GetInfoFromSchemaSummaryKV(evt.KV.Key)
+		idx := strings.Index(domainProject, "/")
+		newDomain := domainProject[:idx]
+		if pb.EVT_DELETE == action {
+			metrics.ReportSchemas(newDomain, -1)
+		} else {
+			metrics.ReportSchemas(newDomain, 1)
+		}
+	default:
+	}
+}
+
+func NewSchemaSummaryEventHandler() *SchemaSummaryEventHandler {
+	return &SchemaSummaryEventHandler{}
+}
diff --git a/server/service/metrics/metrics.go b/server/service/metrics/metrics.go
index 05c366e5..35399dd3 100644
--- a/server/service/metrics/metrics.go
+++ b/server/service/metrics/metrics.go
@@ -45,10 +45,18 @@ var (
 			Name:      "instance_total",
 			Help:      "Gauge of microservice created in Service Center",
 		}, []string{"instance", "domain"})
+
+	schemaCounter = prometheus.NewGaugeVec(
+		prometheus.GaugeOpts{
+			Namespace: metric.FamilyName,
+			Subsystem: "db",
+			Name:      "schema_total",
+			Help:      "Gauge of schema created in Service Center",
+		}, []string{"instance", "domain"})
 )
 
 func init() {
-	prometheus.MustRegister(domainCounter, serviceCounter, instanceCounter)
+	prometheus.MustRegister(domainCounter, serviceCounter, instanceCounter, schemaCounter)
 }
 
 func ReportDomains(c float64) {
@@ -65,3 +73,8 @@ func ReportInstances(domain string, c float64) {
 	instance := metric.InstanceName()
 	instanceCounter.WithLabelValues(instance, domain).Add(c)
 }
+
+func ReportSchemas(domain string, c float64) {
+	instance := metric.InstanceName()
+	schemaCounter.WithLabelValues(instance, domain).Add(c)
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services