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

[incubator-skywalking] branch master updated: Database metrics provided. (#2025)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new f7ca267  Database metrics provided. (#2025)
f7ca267 is described below

commit f7ca26729dbc2db3d9aa83df72d3ee9a74fc557c
Author: Lemon <li...@hotmail.com>
AuthorDate: Sun Jan 27 08:27:34 2019 +0800

    Database metrics provided. (#2025)
    
    * Add Database source
    
    * Add DatabaseSource source and database_* script for oal
    
    * Enable Database_Indicator
    
    * Add file license
    
    * Rename DatabaseService to ClientDatabase. In the future, we may have real database server monitoring.
    
    * Add query database from H2
    
    * refactor
    
    * update submodule
    
    * refactor
    
    * Fix style
    
    * Fix: unknown tag error
    
    * fix checkstyle
---
 .../apache/skywalking/oal/tool/grammar/OALLexer.g4 |  1 +
 .../skywalking/oal/tool/grammar/OALParser.g4       |  2 +-
 .../oal/tool/output/DispatcherContext.java         |  1 +
 .../skywalking/oal/tool/output/FileGenerator.java  | 11 ++++
 .../oal/tool/parser/SourceColumnsFactory.java      |  6 ++
 .../DatabaseAccessDispatcherTemplate.ftl           | 66 ++++++++++++++++++++
 .../src/main/resources/official_analysis.oal       | 11 +++-
 .../server/core/query/MetadataQueryService.java    |  4 ++
 .../Scope.java => query/entity/Database.java}      | 26 ++++----
 .../oap/server/core/register/ServiceInventory.java |  5 ++
 .../source/{Scope.java => DatabaseAccess.java}     | 29 +++++----
 .../skywalking/oap/server/core/source/Scope.java   |  2 +-
 .../core/storage/query/IMetadataQueryDAO.java      |  2 +
 .../oap/query/graphql/resolver/MetadataQuery.java  |  4 ++
 .../src/main/resources/query-protocol              |  2 +-
 .../listener/endpoint/MultiScopesSpanListener.java |  6 +-
 .../parser/listener/endpoint/SourceBuilder.java    | 14 +++++
 .../elasticsearch/query/MetadataQueryEsDAO.java    | 34 +++++++++++
 .../plugin/jdbc/h2/dao/H2MetadataQueryDAO.java     | 70 +++++++++++++++++-----
 19 files changed, 253 insertions(+), 43 deletions(-)

diff --git a/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4 b/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
index be2f5d7..2e0995e 100644
--- a/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
+++ b/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
@@ -37,6 +37,7 @@ SRC_SERVICE_INSTANCE_JVM_CPU: 'ServiceInstanceJVMCPU';
 SRC_SERVICE_INSTANCE_JVM_MEMORY: 'ServiceInstanceJVMMemory';
 SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL: 'ServiceInstanceJVMMemoryPool';
 SRC_SERVICE_INSTANCE_JVM_GC: 'ServiceInstanceJVMGC';
+SRC_DATABASE_ACCESS: 'DatabaseAccess';
 
 // Literals
 
diff --git a/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4 b/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
index 6e1f1f8..82221c8 100644
--- a/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
+++ b/oap-server/generate-tool/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
@@ -46,7 +46,7 @@ filterExpression
     ;
 
 source
-    : SRC_ALL | SRC_SERVICE | SRC_SERVICE_INSTANCE | SRC_ENDPOINT |
+    : SRC_ALL | SRC_SERVICE | SRC_DATABASE_ACCESS | SRC_SERVICE_INSTANCE | SRC_ENDPOINT |
       SRC_SERVICE_RELATION | SRC_SERVICE_INSTANCE_RELATION | SRC_ENDPOINT_RELATION |
       SRC_SERVICE_INSTANCE_JVM_CPU | SRC_SERVICE_INSTANCE_JVM_MEMORY | SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL | SRC_SERVICE_INSTANCE_JVM_GC// JVM source of service instance
     ;
diff --git a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
index 834b73e..9a160f8 100644
--- a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
+++ b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
@@ -36,4 +36,5 @@ public class DispatcherContext {
     private List<AnalysisResult> serviceInstanceJVMMemoryIndicators = new LinkedList<>();
     private List<AnalysisResult> serviceInstanceJVMMemoryPoolIndicators = new LinkedList<>();
     private List<AnalysisResult> serviceInstanceJVMGCIndicators = new LinkedList<>();
+    private List<AnalysisResult> databaseAccessIndicators = new LinkedList<>();
 }
diff --git a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
index 0e3114a..19bb941 100644
--- a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
+++ b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
@@ -51,6 +51,10 @@ public class FileGenerator {
         createFile(file);
         this.generateServiceDispatcher(new FileWriter(file));
 
+        file = new File(outputPath, "generated/databaseaccess/DatabaseAccessDispatcher.java");
+        createFile(file);
+        this.generateDatabaseAccessDispatcher(new FileWriter(file));
+
         file = new File(outputPath, "generated/servicerelation/ServiceRelationDispatcher.java");
         createFile(file);
         this.generateServiceRelationDispatcher(new FileWriter(file));
@@ -127,6 +131,10 @@ public class FileGenerator {
         configuration.getTemplate("ServiceDispatcherTemplate.ftl").process(dispatcherContext, output);
     }
 
+    void generateDatabaseAccessDispatcher(Writer output) throws IOException, TemplateException {
+        configuration.getTemplate("DatabaseAccessDispatcherTemplate.ftl").process(dispatcherContext, output);
+    }
+
     void generateServiceRelationDispatcher(Writer output) throws IOException, TemplateException {
         configuration.getTemplate("ServiceRelationDispatcherTemplate.ftl").process(dispatcherContext, output);
     }
@@ -201,6 +209,9 @@ public class FileGenerator {
                 case "ServiceInstanceJVMGC":
                     dispatcherContext.getServiceInstanceJVMGCIndicators().add(result);
                     break;
+                case "DatabaseAccess":
+                    dispatcherContext.getDatabaseAccessIndicators().add(result);
+                    break;
                 default:
                     throw new RuntimeException("Unexpected dispatcher");
             }
diff --git a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
index 578963c..070e554 100644
--- a/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
+++ b/oap-server/generate-tool/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
@@ -90,6 +90,12 @@ public class SourceColumnsFactory {
                 SourceColumn destServiceInstance = new SourceColumn("childServiceInstanceId", "child_service_instance_id", int.class, false);
                 columnList.add(destServiceInstance);
                 return columnList;
+            case "DatabaseAccess":
+                columnList = new LinkedList<>();
+                // Service id;
+                idColumn = new SourceColumn("entityId", "entity_id", String.class, true);
+                columnList.add(idColumn);
+                return columnList;
             default:
                 throw new IllegalArgumentException("Illegal source :" + source);
         }
diff --git a/oap-server/generate-tool/src/main/resources/code-templates/DatabaseAccessDispatcherTemplate.ftl b/oap-server/generate-tool/src/main/resources/code-templates/DatabaseAccessDispatcherTemplate.ftl
new file mode 100644
index 0000000..7bfb7b3
--- /dev/null
+++ b/oap-server/generate-tool/src/main/resources/code-templates/DatabaseAccessDispatcherTemplate.ftl
@@ -0,0 +1,66 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+package org.apache.skywalking.oap.server.core.analysis.generated.databaseaccess;
+
+import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
+<#if (databaseAccessIndicators?size>0)>
+import org.apache.skywalking.oap.server.core.analysis.worker.IndicatorProcess;
+    <#list databaseAccessIndicators as indicator>
+        <#if indicator.filterExpressions??>
+            import org.apache.skywalking.oap.server.core.analysis.indicator.expression.*;
+            <#break>
+        </#if>
+    </#list>
+</#if>
+import org.apache.skywalking.oap.server.core.source.*;
+
+/**
+* This class is auto generated. Please don't change this class manually.
+*
+* @author Observability Analysis Language code generator
+*/
+public class DatabaseAccessDispatcher implements SourceDispatcher<DatabaseAccess> {
+
+    @Override public void dispatch(DatabaseAccess source) {
+    <#list databaseAccessIndicators as indicator>
+        do${indicator.metricName}(source);
+    </#list>
+    }
+
+    <#list databaseAccessIndicators as indicator>
+    private void do${indicator.metricName}(DatabaseAccess source) {
+        ${indicator.metricName}Indicator indicator = new ${indicator.metricName}Indicator();
+
+        <#if indicator.filterExpressions??>
+            <#list indicator.filterExpressions as filterExpression>
+                if (!new ${filterExpression.expressionObject}().setLeft(${filterExpression.left}).setRight(${filterExpression.right}).match()) {
+                return;
+                }
+            </#list>
+        </#if>
+
+        indicator.setTimeBucket(source.getTimeBucket());
+        <#list indicator.fieldsFromSource as field>
+        indicator.${field.fieldSetter}(source.${field.fieldGetter}());
+        </#list>
+        indicator.${indicator.entryMethod.methodName}(<#list indicator.entryMethod.argsExpressions as arg>${arg}<#if arg_has_next>, </#if></#list>);
+        IndicatorProcess.INSTANCE.in(indicator);
+    }
+    </#list>
+}
diff --git a/oap-server/generated-analysis/src/main/resources/official_analysis.oal b/oap-server/generated-analysis/src/main/resources/official_analysis.oal
index c38865b..57c2abc 100644
--- a/oap-server/generated-analysis/src/main/resources/official_analysis.oal
+++ b/oap-server/generated-analysis/src/main/resources/official_analysis.oal
@@ -70,4 +70,13 @@ instance_jvm_memory_noheap_max = from(ServiceInstanceJVMMemory.max).filter(heapS
 instance_jvm_young_gc_time = from(ServiceInstanceJVMGC.time).filter(phrase == GCPhrase.NEW).longAvg();
 instance_jvm_old_gc_time = from(ServiceInstanceJVMGC.time).filter(phrase == GCPhrase.OLD).longAvg();
 instance_jvm_young_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.NEW).sum();
-instance_jvm_old_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.OLD).sum();
\ No newline at end of file
+instance_jvm_old_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.OLD).sum();
+
+database_access_resp_time = from(DatabaseAccess.latency).longAvg();
+database_access_sla = from(DatabaseAccess.*).percent(status == true);
+database_access_cpm = from(DatabaseAccess.*).cpm();
+database_access_p99 = from(DatabaseAccess.latency).p99(10);
+database_access_p95 = from(DatabaseAccess.latency).p95(10);
+database_access_p90 = from(DatabaseAccess.latency).p90(10);
+database_access_p75 = from(DatabaseAccess.latency).p75(10);
+database_access_p50 = from(DatabaseAccess.latency).p50(10);
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
index 14c9378..f6aaf68 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetadataQueryService.java
@@ -77,6 +77,10 @@ public class MetadataQueryService implements org.apache.skywalking.oap.server.li
         return getMetadataQueryDAO().getAllServices(startTimestamp, endTimestamp);
     }
 
+    public List<Database> getAllDatabases() throws IOException {
+        return getMetadataQueryDAO().getAllDatabases();
+    }
+
     public List<Service> searchServices(final long startTimestamp, final long endTimestamp,
         final String keyword) throws IOException {
         return getMetadataQueryDAO().searchServices(startTimestamp, endTimestamp, keyword);
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/entity/Database.java
similarity index 55%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/entity/Database.java
index fa63941..7396221 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/entity/Database.java
@@ -16,20 +16,18 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core.source;
+package org.apache.skywalking.oap.server.core.query.entity;
 
-/**
- * @author peng-yongsheng, wusheng
- */
-public enum Scope {
-    All, Service, ServiceInstance, Endpoint, ServiceRelation, ServiceInstanceRelation, EndpointRelation, NetworkAddress,
-    ServiceInstanceJVMCPU, ServiceInstanceJVMMemory, ServiceInstanceJVMMemoryPool, ServiceInstanceJVMGC,
-    Segment, Alarm, ServiceInventory, ServiceInstanceInventory, EndpointInventory;
+import lombok.Getter;
+import lombok.Setter;
 
-    public static Scope valueOf(int ordinal) {
-        if (ordinal < 0 || ordinal >= values().length) {
-            throw new IndexOutOfBoundsException("Invalid ordinal");
-        }
-        return values()[ordinal];
-    }
+/**
+ * @author: liuhaoyang
+ **/
+@Getter
+@Setter
+public class Database {
+    private int id;
+    private String name;
+    private String type;
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/register/ServiceInventory.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/register/ServiceInventory.java
index 72fae39..f8b3546 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/register/ServiceInventory.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/register/ServiceInventory.java
@@ -195,6 +195,11 @@ public class ServiceInventory extends RegisterSource {
         return true;
     }
 
+    public static class PropertyUtil {
+
+        public static final String DATABASE = "database";
+    }
+
     public static class Builder implements StorageBuilder<ServiceInventory> {
 
         @Override public ServiceInventory map2Data(Map<String, Object> dbMap) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DatabaseAccess.java
similarity index 60%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DatabaseAccess.java
index fa63941..0bb1e9d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DatabaseAccess.java
@@ -18,18 +18,27 @@
 
 package org.apache.skywalking.oap.server.core.source;
 
+import lombok.Getter;
+import lombok.Setter;
+
 /**
- * @author peng-yongsheng, wusheng
+ * @author: liuhaoyang
  */
-public enum Scope {
-    All, Service, ServiceInstance, Endpoint, ServiceRelation, ServiceInstanceRelation, EndpointRelation, NetworkAddress,
-    ServiceInstanceJVMCPU, ServiceInstanceJVMMemory, ServiceInstanceJVMMemoryPool, ServiceInstanceJVMGC,
-    Segment, Alarm, ServiceInventory, ServiceInstanceInventory, EndpointInventory;
+public class DatabaseAccess extends Source {
+
+    @Override
+    public Scope scope() {
+        return Scope.DatabaseAccess;
+    }
 
-    public static Scope valueOf(int ordinal) {
-        if (ordinal < 0 || ordinal >= values().length) {
-            throw new IndexOutOfBoundsException("Invalid ordinal");
-        }
-        return values()[ordinal];
+    @Override
+    public String getEntityId() {
+        return String.valueOf(id);
     }
+
+    @Getter @Setter private long id;
+    @Getter @Setter private String name;
+    @Getter @Setter private int databaseTypeId;
+    @Getter @Setter private int latency;
+    @Getter @Setter private boolean status;
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
index fa63941..d162f3e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Scope.java
@@ -24,7 +24,7 @@ package org.apache.skywalking.oap.server.core.source;
 public enum Scope {
     All, Service, ServiceInstance, Endpoint, ServiceRelation, ServiceInstanceRelation, EndpointRelation, NetworkAddress,
     ServiceInstanceJVMCPU, ServiceInstanceJVMMemory, ServiceInstanceJVMMemoryPool, ServiceInstanceJVMGC,
-    Segment, Alarm, ServiceInventory, ServiceInstanceInventory, EndpointInventory;
+    Segment, Alarm, ServiceInventory, ServiceInstanceInventory, EndpointInventory, DatabaseAccess;
 
     public static Scope valueOf(int ordinal) {
         if (ordinal < 0 || ordinal >= values().length) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetadataQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetadataQueryDAO.java
index 79d0edb..d277d6f 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetadataQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetadataQueryDAO.java
@@ -36,6 +36,8 @@ public interface IMetadataQueryDAO extends DAO {
 
     List<Service> getAllServices(final long startTimestamp, final long endTimestamp) throws IOException;
 
+    List<Database> getAllDatabases() throws IOException;
+
     List<Service> searchServices(final long startTimestamp, final long endTimestamp,
         final String keyword) throws IOException;
 
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetadataQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetadataQuery.java
index 157a639..986d6a6 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetadataQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetadataQuery.java
@@ -89,4 +89,8 @@ public class MetadataQuery implements GraphQLQueryResolver {
     public EndpointInfo getEndpointInfo(final int endpointId) throws IOException {
         return getMetadataQueryService().getEndpointInfo(endpointId);
     }
+
+    public List<Database> getAllDatabases(final Duration duration) throws IOException {
+        return getMetadataQueryService().getAllDatabases();
+    }
 }
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
index c65a23b..85b81e2 160000
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
@@ -1 +1 @@
-Subproject commit c65a23bd6b9bba8d1df30d4de261624952df2b7b
+Subproject commit 85b81e2e34efb0b670d039154feca336c9203700
diff --git a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
index 217cb9c..590d71e 100644
--- a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
+++ b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
@@ -211,12 +211,16 @@ public class MultiScopesSpanListener implements EntrySpanListener, ExitSpanListe
             exitSourceBuilder.setTimeBucket(minuteTimeBucket);
             sourceReceiver.receive(exitSourceBuilder.toServiceRelation());
             sourceReceiver.receive(exitSourceBuilder.toServiceInstanceRelation());
+            if (RequestType.DATABASE.equals(exitSourceBuilder.getType())) {
+                sourceReceiver.receive(exitSourceBuilder.toDatabaseAccess());
+            }
         });
     }
 
     public static class Factory implements SpanListenerFactory {
 
-        @Override public SpanListener create(ModuleManager moduleManager) {
+        @Override
+        public SpanListener create(ModuleManager moduleManager) {
             return new MultiScopesSpanListener(moduleManager);
         }
     }
diff --git a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
index 2d39ecc..1d2e1b1 100644
--- a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
+++ b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
@@ -171,4 +171,18 @@ class SourceBuilder {
         endpointRelation.setTimeBucket(timeBucket);
         return endpointRelation;
     }
+
+    DatabaseAccess toDatabaseAccess() {
+        if (!RequestType.DATABASE.equals(type)) {
+            return null;
+        }
+        DatabaseAccess databaseAccess = new DatabaseAccess();
+        databaseAccess.setId(destServiceId);
+        databaseAccess.setDatabaseTypeId(componentId);
+        databaseAccess.setLatency(latency);
+        databaseAccess.setName(destServiceName);
+        databaseAccess.setStatus(status);
+        databaseAccess.setTimeBucket(timeBucket);
+        return databaseAccess;
+    }
 }
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetadataQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetadataQueryEsDAO.java
index e80d616..f1a8a31 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetadataQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetadataQueryEsDAO.java
@@ -20,8 +20,10 @@ package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
 
 import com.google.common.base.Strings;
 import com.google.gson.*;
+
 import java.io.IOException;
 import java.util.*;
+
 import org.apache.skywalking.oap.server.core.query.entity.*;
 import org.apache.skywalking.oap.server.core.register.*;
 import org.apache.skywalking.oap.server.core.source.DetectPoint;
@@ -105,6 +107,38 @@ public class MetadataQueryEsDAO extends EsDAO implements IMetadataQueryDAO {
         return buildServices(response);
     }
 
+    @Override
+    public List<Database> getAllDatabases() throws IOException {
+        SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
+
+        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
+        boolQueryBuilder.must().add(QueryBuilders.termQuery(ServiceInventory.NODE_TYPE, NodeType.Database.value()));
+
+        sourceBuilder.query(boolQueryBuilder);
+        sourceBuilder.size(100);
+
+        SearchResponse response = getClient().search(ServiceInventory.MODEL_NAME, sourceBuilder);
+
+        List<Database> databases = new ArrayList<>();
+        for (SearchHit searchHit : response.getHits()) {
+            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
+            Database database = new Database();
+            database.setId(((Number) sourceAsMap.get(ServiceInventory.SEQUENCE)).intValue());
+            database.setName((String) sourceAsMap.get(ServiceInventory.NAME));
+            String propertiesString = (String) sourceAsMap.get(ServiceInstanceInventory.PROPERTIES);
+            if (!Strings.isNullOrEmpty(propertiesString)) {
+                JsonObject properties = GSON.fromJson(propertiesString, JsonObject.class);
+                if (properties.has(ServiceInventory.PropertyUtil.DATABASE)) {
+                    database.setType(properties.get(ServiceInventory.PropertyUtil.DATABASE).getAsString());
+                } else {
+                    database.setType("UNKNOWN");
+                }
+            }
+            databases.add(database);
+        }
+        return databases;
+    }
+
     @Override public List<Service> searchServices(long startTimestamp, long endTimestamp,
         String keyword) throws IOException {
         SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
index b5e12cd..12aabeb 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
@@ -20,9 +20,11 @@ package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
 
 import com.google.common.base.Strings;
 import com.google.gson.*;
+
 import java.io.IOException;
 import java.sql.*;
 import java.util.*;
+
 import org.apache.skywalking.oap.server.core.query.entity.*;
 import org.apache.skywalking.oap.server.core.register.*;
 import org.apache.skywalking.oap.server.core.source.DetectPoint;
@@ -44,7 +46,8 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         this.h2Client = h2Client;
     }
 
-    @Override public int numOfService(long startTimestamp, long endTimestamp) throws IOException {
+    @Override
+    public int numOfService(long startTimestamp, long endTimestamp) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select count(*) num from ").append(ServiceInventory.MODEL_NAME).append(" where ");
@@ -63,7 +66,8 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         return 0;
     }
 
-    @Override public int numOfEndpoint(long startTimestamp, long endTimestamp) throws IOException {
+    @Override
+    public int numOfEndpoint(long startTimestamp, long endTimestamp) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select count(*) num from ").append(EndpointInventory.MODEL_NAME).append(" where ");
@@ -82,8 +86,9 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         return 0;
     }
 
-    @Override public int numOfConjectural(long startTimestamp, long endTimestamp,
-        int nodeTypeValue) throws IOException {
+    @Override
+    public int numOfConjectural(long startTimestamp, long endTimestamp,
+                                int nodeTypeValue) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select count(*) num from ").append(ServiceInventory.MODEL_NAME).append(" where ");
@@ -120,8 +125,42 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         }
     }
 
-    @Override public List<Service> searchServices(long startTimestamp, long endTimestamp,
-        String keyword) throws IOException {
+    @Override
+    public List<Database> getAllDatabases() throws IOException {
+        StringBuilder sql = new StringBuilder();
+        List<Object> condition = new ArrayList<>(1);
+        sql.append("select * from ").append(ServiceInventory.MODEL_NAME).append(" where ");
+        sql.append(ServiceInventory.NODE_TYPE).append("=? limit 100");
+        condition.add(NodeType.Database.value());
+
+        try (Connection connection = h2Client.getConnection()) {
+            try (ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]))) {
+                List<Database> databases = new ArrayList<>();
+                while (resultSet.next()) {
+                    Database database = new Database();
+                    database.setId(resultSet.getInt(ServiceInventory.SEQUENCE));
+                    database.setName(resultSet.getString(ServiceInventory.NAME));
+                    String propertiesString = resultSet.getString(ServiceInstanceInventory.PROPERTIES);
+                    if (!Strings.isNullOrEmpty(propertiesString)) {
+                        JsonObject properties = GSON.fromJson(propertiesString, JsonObject.class);
+                        if (properties.has(ServiceInventory.PropertyUtil.DATABASE)) {
+                            database.setType(properties.get(ServiceInventory.PropertyUtil.DATABASE).getAsString());
+                        } else {
+                            database.setType("UNKNOWN");
+                        }
+                    }
+                    databases.add(database);
+                }
+                return databases;
+            }
+        } catch (SQLException e) {
+            throw new IOException(e);
+        }
+    }
+
+    @Override
+    public List<Service> searchServices(long startTimestamp, long endTimestamp,
+                                        String keyword) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select * from ").append(ServiceInventory.MODEL_NAME).append(" where ");
@@ -142,7 +181,8 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         }
     }
 
-    @Override public Service searchService(String serviceCode) throws IOException {
+    @Override
+    public Service searchService(String serviceCode) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select * from ").append(ServiceInventory.MODEL_NAME).append(" where ");
@@ -168,8 +208,9 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         return null;
     }
 
-    @Override public List<Endpoint> searchEndpoint(String keyword, String serviceId,
-        int limit) throws IOException {
+    @Override
+    public List<Endpoint> searchEndpoint(String keyword, String serviceId,
+                                         int limit) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select * from ").append(EndpointInventory.MODEL_NAME).append(" where ");
@@ -199,8 +240,9 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         return endpoints;
     }
 
-    @Override public List<ServiceInstance> getServiceInstances(long startTimestamp, long endTimestamp,
-        String serviceId) throws IOException {
+    @Override
+    public List<ServiceInstance> getServiceInstances(long startTimestamp, long endTimestamp,
+                                                     String serviceId) throws IOException {
         StringBuilder sql = new StringBuilder();
         List<Object> condition = new ArrayList<>(5);
         sql.append("select * from ").append(ServiceInstanceInventory.MODEL_NAME).append(" where ");
@@ -255,13 +297,13 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
     }
 
     private void setTimeRangeCondition(StringBuilder sql, List<Object> conditions, long startTimestamp,
-        long endTimestamp) {
+                                       long endTimestamp) {
         sql.append(" ( (").append(RegisterSource.HEARTBEAT_TIME).append(" >= ? and ")
-            .append(RegisterSource.REGISTER_TIME).append(" <= ? )");
+                .append(RegisterSource.REGISTER_TIME).append(" <= ? )");
         conditions.add(endTimestamp);
         conditions.add(endTimestamp);
         sql.append(" or (").append(RegisterSource.REGISTER_TIME).append(" <= ? and ")
-            .append(RegisterSource.HEARTBEAT_TIME).append(" >= ? ) ) ");
+                .append(RegisterSource.HEARTBEAT_TIME).append(" >= ? ) ) ");
         conditions.add(endTimestamp);
         conditions.add(startTimestamp);
     }