Repository: apache/skywalking (language: python)

Issue:
[Feature] elasticsearch server monitoring
### Search before asking

- [X] I had searched in the [issues](https://github.com/apache/skywalking/issues?q=is%3Aissue) and found no similar feature requirement.


### Description

SkyWalking currently does not support monitoring Elasticsearch. Elasticsearch is a popular full-text search system, and as one of the optional underlying storage options for SkyWalking, monitoring it would be very useful.

Data Flow:
Prometheus elasticsearch exporter -> OpenTelemetry Collector -> SkyWalking OTEL receiver (OTLP)

I have a few questions:

1. Should it be placed in the database menu?
2. I'm not sure how to add some tests. Could you give me some help?

### Use case

_No response_

### Related issues

_No response_

### Are you willing to submit a PR?

- [X] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)



Discussion / hints:
1. Yes, ElasticSearch is a database.
2. There are plenty of e2e tests for this. Take this recent PR as reference, https://github.com/apache/skywalking/pull/10655

Fix patch:
diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml
index 0982075a9b5c..5a75037ed756 100644
--- a/.github/workflows/skywalking.yaml
+++ b/.github/workflows/skywalking.yaml
@@ -679,6 +679,8 @@ jobs:
             config: test/e2e-v2/cases/aws/api-gateway/e2e.yaml
           - name: Redis Prometheus
             config: test/e2e-v2/cases/redis/redis-exporter/e2e.yaml
+          - name: Elasticsearch
+            config: test/e2e-v2/cases/elasticsearch/e2e.yaml
     steps:
       - uses: actions/checkout@v3
         with:
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 0fc57149efe5..61251dad509c 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -34,6 +34,7 @@
 * Add component ID for amqp, amqp-producer and amqp-consumer.
 * Support no-proxy mode for aws-firehose receiver
 * Bump up armeria to 1.23.1
+* Support Elasticsearch Monitoring.
 
 #### UI
 * Revert: cpm5d function. This feature is cancelled from backend.
diff --git a/docs/en/setup/backend/backend-elasticsearch-monitoring.md b/docs/en/setup/backend/backend-elasticsearch-monitoring.md
new file mode 100644
index 000000000000..c16f2675ee08
--- /dev/null
+++ b/docs/en/setup/backend/backend-elasticsearch-monitoring.md
@@ -0,0 +1,115 @@
+# Elasticsearch monitoring
+
+SkyWalking leverages elasticsearch-exporter for collecting metrics data from Elasticsearch. It leverages OpenTelemetry
+Collector to transfer the metrics to
+[OpenTelemetry receiver](opentelemetry-receiver.md) and into the [Meter System](./../../concepts-and-designs/meter.md).
+
+## Data flow
+
+1. The elasticsearch-exporter collect metrics data from Elasticsearch.
+2. OpenTelemetry Collector fetches metrics from elasticsearch-exporter via Prometheus Receiver and pushes metrics to
+   SkyWalking OAP Server via OpenTelemetry gRPC exporter.
+3. The SkyWalking OAP Server parses the expression with [MAL](../../concepts-and-designs/mal.md) to
+   filter/calculate/aggregate and store the results.
+
+## Setup
+
+1. Setup [elasticsearch-exporter](https://github.com/prometheus-community/elasticsearch_exporter).
+2. Set up [OpenTelemetry Collector ](https://opentelemetry.io/docs/collector/getting-started/#kubernetes). The example for OpenTelemetry Collector configuration, refer
+   to [here](../../../../test/e2e-v2/cases/elasticsearch/otel-collector-config.yaml).
+3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
+
+## Elasticsearch Monitoring
+
+Elasticsearch monitoring provides multidimensional metrics monitoring of Elasticsearch clusters as `Layer: ELASTICSEARCH` `Service` in the OAP. In each cluster, the nodes are represented as `Instance` and indices are `Endpoint`s.
+
+### Elasticsearch Cluster Supported Metrics
+
+| Monitoring Panel          | Metric Name                                                 | Description                                                                                     | Data Source            |
+|---------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------|------------------------|
+| Cluster Health            | meter_elasticsearch_cluster_health_status                   | Whether all primary and replica shards are allocated                                            | elasticsearch-exporter |
+| Tripped Of Breakers       | meter_elasticsearch_cluster_breakers_tripped                | Tripped for breaker                                                                             | elasticsearch-exporter |
+| Nodes                     | meter_elasticsearch_cluster_nodes                           | Number of nodes in the cluster.                                                                 | elasticsearch-exporter |
+| Data Nodes                | meter_elasticsearch_cluster_data_nodes                      | Number of data nodes in the cluster                                                             | elasticsearch-exporter |
+| Pending Tasks             | meter_elasticsearch_cluster_pending_tasks_total             | Cluster level changes which have not yet been executed                                          | elasticsearch-exporter |
+| CPU Usage Avg. (%)        | meter_elasticsearch_cluster_cpu_usage_avg                   | Cluster level percent CPU used by process                                                       | elasticsearch-exporter |
+| JVM Memory Used Avg. (%)  | meter_elasticsearch_cluster_jvm_memory_used_avg             | Cluster level percent JVM memory used                                                           | elasticsearch-exporter |
+| Open Files                | meter_elasticsearch_cluster_open_file_count                 | Open file descriptors                                                                           | elasticsearch-exporter |
+| Active Primary Shards     | meter_elasticsearch_cluster_primary_shards_total            | The number of primary shards in your cluster. This is an aggregate total across all indices     | elasticsearch-exporter |
+| Active Shards             | meter_elasticsearch_cluster_shards_total                    | Aggregate total of all shards across all indices, which includes replica shards                 | elasticsearch-exporter |
+| Initializing Shards       | meter_elasticsearch_cluster_initializing_shards_total       | Count of shards that are being freshly created                                                  | elasticsearch-exporter |
+| Delayed Unassigned Shards | meter_elasticsearch_cluster_delayed_unassigned_shards_total | Shards delayed to reduce reallocation overhead                                                  | elasticsearch-exporter |
+| Relocating Shards         | meter_elasticsearch_cluster_relocating_shards_total         | The number of shards that are currently moving from one node to another node                    | elasticsearch-exporter |
+| Unassigned Shards         | meter_elasticsearch_cluster_unassigned_shards_total         | The number of shards that exist in the cluster state, but cannot be found in the cluster itself | elasticsearch-exporter |
+
+### Elasticsearch Node Supported Metrics
+
+| Monitoring Panel                | Unit      | Metric Name                                                                                                                                          | Description                                        | Data Source            |
+|---------------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------|------------------------|
+| Node Rules                      |           | meter_elasticsearch_node_rules                                                                                                                       | Node roles                                         | elasticsearch-exporter |
+| JVM Memory Used                 | MB        | meter_elasticsearch_node_jvm_memory_used                                                                                                             | Node level JVM memory used size                    | elasticsearch-exporter |
+| CPU Percent                     | %         | meter_elasticsearch_node_process_cpu_percent                                                                                                         | Node level percent CPU used by process             | elasticsearch-exporter |
+| Documents                       |           | meter_elasticsearch_node_indices_docs                                                                                                                | Count of index documents on this node              | elasticsearch-exporter |
+| Segments                        |           | meter_elasticsearch_node_segment_count                                                                                                               | Count of index segments on this node               | elasticsearch-exporter |
+| Disk Free Space                 | GB        | meter_elasticsearch_node_all_disk_free_space                                                                                                         | Available space on all block device                | elasticsearch-exporter |
+| Open Files                      |           | meter_elasticsearch_node_open_file_count                                                                                                             | Open file descriptors                              | elasticsearch-exporter |
+| Process CPU Usage Percent       | %         | meter_elasticsearch_node_process_cpu_percent                                                                                                         | Percent CPU used by process                        | elasticsearch-exporter |
+| OS CPU usage percent            | %         | meter_elasticsearch_node_os_cpu_percent                                                                                                              | Percent CPU used by the OS                         | elasticsearch-exporter |
+| Load Average                    |           | meter_elasticsearch_node_os_load1 <br/>meter_elasticsearch_node_os_load5<br/>meter_elasticsearch_node_os_load15                                      | Shortterm, Midterm, Longterm load average          | elasticsearch-exporter |
+| JVM Memory Usage                | MB        | meter_elasticsearch_node_jvm_memory_nonheap_used<br />meter_elasticsearch_node_jvm_memory_heap_used<br/>meter_elasticsearch_node_jvm_memory_heap_max | JVM memory currently usage by area                 | elasticsearch-exporter |
+| JVM Pool Peak Used              | MB        | meter_elasticsearch_node_jvm_memory_pool_peak_used                                                                                                   | JVM memory currently used by pool                  | elasticsearch-exporter |
+| GC Count                        |           | meter_elasticsearch_node_jvm_gc_count                                                                                                                | Count of JVM GC runs                               | elasticsearch-exporter |
+| GC Time                         | ms/min    | meter_elasticsearch_node_jvm_gc_time                                                                                                                 | GC run time                                        | elasticsearch-exporter |
+| All Operations ReqRate          |           | meter_elasticsearch_node_indices_*_req_rate                                                                                                          | All Operations ReqRate on node                     | elasticsearch-exporter |
+| Indexing Rate                   | reqps     | meter_elasticsearch_node_indices_indexing_index_total_req_rate<br />meter_elasticsearch_node_indices_indexing_index_total_proc_rate                  | Indexing rate on node                              | elasticsearch-exporter |
+| Searching Rate                  | reqps     | meter_elasticsearch_node_indices_search_fetch_total_req_rate<br />meter_elasticsearch_node_indices_search_query_time_seconds_proc_rate               | Searching rate on node                             | elasticsearch-exporter |
+| Total Translog Operations       |           | meter_elasticsearch_node_indices_translog_operations                                                                                                 | Total translog operations                          | elasticsearch-exporter |
+| Total Translog Size             | MB        | meter_elasticsearch_node_indices_translog_size                                                                                                       | Total translog size                                | elasticsearch-exporter |
+| Tripped For Breakers            |           | meter_elasticsearch_node_breakers_tripped                                                                                                            | Tripped for breaker                                | elasticsearch-exporter |
+| Estimated Size Of Breaker       | MB        | meter_elasticsearch_node_breakers_estimated_size                                                                                                     | Estimated size of breaker                          | elasticsearch-exporter |
+| Documents Count                 | KB/s      | meter_elasticsearch_node_indices_docs                                                                                                                | Count of documents on this node                    | elasticsearch-exporter |
+| Merged Documents Count          | count/s   | meter_elasticsearch_node_indices_merges_docs_total                                                                                                   | Cumulative docs merged                             | elasticsearch-exporter |
+| Deleted Documents Count         |           | meter_elasticsearch_node_indices_docs_deleted_total                                                                                                  | Count of deleted documents on this node            | elasticsearch-exporter |
+| Documents Index Rate            | calls/s   | meter_elasticsearch_node_indices_indexing_index_total_req_rate                                                                                       | Total index calls per second                       | elasticsearch-exporter |
+| Merged Documents Rate           | MB / s    | meter_elasticsearch_node_indices_merges_total_size_bytes_total                                                                                       | Total merge size per second                        | elasticsearch-exporter |
+| Documents Deleted Rate          | docs/s    | meter_elasticsearch_node_indices_docs_deleted                                                                                                        | Count of deleted documents per second on this node | elasticsearch-exporter |
+| Count Of Index Segments         |           | meter_elasticsearch_node_segment_count                                                                                                               | Count of index segments on this node               | elasticsearch-exporter |
+| Current Memory Size Of Segments | MB        | meter_elasticsearch_node_segment_memory                                                                                                              | Current memory size of segments                    | elasticsearch-exporter |
+| Network                         | bytes/sec | meter_elasticsearch_node_network_send_bytes<br/>meter_elasticsearch_node_network_receive_bytes                                                       | Total number of bytes sent and receive             | elasticsearch-exporter |
+| Disk Usage Percent              | %         | meter_elasticsearch_node_disk_usage_percent                                                                                                          | Used space on block device                         | elasticsearch-exporter |
+| Disk Usage                      | GB        | meter_elasticsearch_node_disk_usage                                                                                                                  | Used space size of block device                    | elasticsearch-exporter |
+| Disk Read                       | KBs       | meter_elasticsearch_node_disk_io_read_bytes                                                                                                          | Total kilobytes read from disk                     | elasticsearch-exporter |
+| Disk Write                      | KBs       | meter_elasticsearch_node_disk_io_write_bytes                                                                                                         | Total kilobytes write from disk                    | elasticsearch-exporter |
+
+### Elasticsearch Index Supported Metrics
+
+| Monitoring Panel                              | Unit  | Metric Name                                                                                                                                                                                                                                                    | Description                                                                            | Data Source            |
+|-----------------------------------------------|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------|
+| Documents Primary                             |       | meter_elasticsearch_index_indices_docs_primary                                                                                                                                                                                                                 | Count of documents with only primary shards on all nodes                               | elasticsearch-exporter |
+| Deleted Documents Primary                     |       | meter_elasticsearch_index_indices_deleted_docs_primary                                                                                                                                                                                                         | Count of deleted documents with only primary shards                                    | elasticsearch-exporter |
+| Data Primary                                  | GB    | meter_elasticsearch_index_indices_store_size_bytes_primary                                                                                                                                                                                                     | Current total size of stored index data with only primary shards on all nodes          | elasticsearch-exporter |
+| Data                                          | GB    | meter_elasticsearch_index_indices_store_size_bytes_total                                                                                                                                                                                                       | Current total size of stored index data with all shards on all nodes                   | elasticsearch-exporter |
+| Segments Primary                              |       | meter_elasticsearch_index_indices_segment_count_primary                                                                                                                                                                                                        | Current number of segments with only primary shards on all nodes                       | elasticsearch-exporter |
+| Segments Memory Primary                       | MB    | meter_elasticsearch_index_indices_segment_memory_bytes_primary                                                                                                                                                                                                 | Current size of segments with only primary shards on all nodes                         | elasticsearch-exporter |
+| Segments                                      |       | meter_elasticsearch_index_indices_segment_count_total                                                                                                                                                                                                          | Current number of segments with all shards on all nodes                                | elasticsearch-exporter |
+| Segments Memory                               | MB    | meter_elasticsearch_index_indices_segment_memory_bytes_total                                                                                                                                                                                                   | Current size of segments with all shards on all nodes                                  | elasticsearch-exporter |
+| Indexing Rate                                 |       | meter_elasticsearch_index_stats_indexing_index_total_req_rate<br/>meter_elasticsearch_index_stats_indexing_index_total_proc_rate                                                                                                                               | Indexing rate on index                                                                 | elasticsearch-exporter |
+| Searching Rate                                |       | meter_elasticsearch_index_stats_search_query_total_req_rate<br/>meter_elasticsearch_index_stats_search_query_total_proc_rate                                                                                                                                   | Searching rate on index                                                                | elasticsearch-exporter |
+| All Operations ReqRate                        |       | meter_elasticsearch_index_stats_*_req_rate                                                                                                                                                                                                                     | All Operations ReqRate on index                                                        | elasticsearch-exporter |
+| All Operations Runtime                        |       | meter_elasticsearch_index_stats_*_time_seconds_total                                                                                                                                                                                                           | All Operations Runtime/s on index                                                      | elasticsearch-exporter |
+| Avg. Search Time Execute / Request            | s     | meter_elasticsearch_index_search_fetch_avg_time<br/>meter_elasticsearch_index_search_query_avg_time<br/>meter_elasticsearch_index_search_scroll_avg_time<br/>meter_elasticsearch_index_search_suggest_avg_time                                                 | Search Operation Avg. time on index                                                    | elasticsearch-exporter |
+| Search Operations Rate                        | req/s | meter_elasticsearch_index_stats_search_query_total_req_rate<br/>meter_elasticsearch_index_stats_search_fetch_total_req_rate<br/>meter_elasticsearch_index_stats_search_scroll_total_req_rate<br/>meter_elasticsearch_index_stats_search_suggest_total_req_rate | Search Operations ReqRate on index                                                     | elasticsearch-exporter |
+| Shards Documents                              |       | meter_elasticsearch_index_indices_shards_docs                                                                                                                                                                                                                  | Count of documents per shards on index                                                 | elasticsearch-exporter |
+| Documents (Primary Shards)                    |       | meter_elasticsearch_index_indices_docs_primary                                                                                                                                                                                                                 | Count of documents with only primary shards on index                                   | elasticsearch-exporter |
+| Documents Created Per Min (Primary Shards)    |       | meter_elasticsearch_index_indices_docs_primary_rate                                                                                                                                                                                                            | Documents rate with only primary shards on index                                       | elasticsearch-exporter |
+| Total Size Of Index (Primary Shards)          | MB    | meter_elasticsearch_index_indices_store_size_bytes_primary                                                                                                                                                                                                     | Current total size of stored index data in bytes with only primary shards on all nodes | elasticsearch-exporter |
+| Documents (All Shards)                        |       | meter_elasticsearch_index_indices_docs_total                                                                                                                                                                                                                   | Count of documents with all shards on index                                            | elasticsearch-exporter |
+| Documents Created Per Min (All Shards)        |       | meter_elasticsearch_index_indices_docs_total_rate                                                                                                                                                                                                              | Documents rate with only all shards on index                                           | elasticsearch-exporter |
+| Total Size Of Index (All Shards)              | MB    | meter_elasticsearch_index_indices_store_size_bytes_total                                                                                                                                                                                                       | Current total size of stored index data in bytes with all shards on all nodes          | elasticsearch-exporter |
+
+## Customizations
+
+You can customize your own metrics/expression/dashboard panel.
+The metrics definition and expression rules are found
+in `/config/otel-rules/elasticsearch/elasticsearch-cluster.yaml，/config/otel-rules/elasticsearch/elasticsearch-node.yaml, /config/otel-rules/elasticsearch/elasticsearch-index.yaml`.
+The Elasticsearch dashboard panel configurations are found in `/config/ui-initialized-templates/elasticsearch`.
diff --git a/docs/menu.yml b/docs/menu.yml
index b0c027cd0760..420ec8b5ac3d 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -225,6 +225,8 @@ catalog:
                 path: "/en/setup/backend/backend-aws-dynamodb-monitoring"
               - name: "Redis"
                 path: "/en/setup/backend/backend-redis-monitoring"
+              - name: "Elasticsearch"
+                path: "/en/setup/backend/backend-elasticsearch-monitoring"
           - name: "Self Observability"
             catalog:
               - name: "OAP self telemetry"
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/Layer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/Layer.java
index 6906be90f1e9..68d7abd0c0bc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/Layer.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/Layer.java
@@ -170,7 +170,13 @@ public enum Layer {
      * Redis is an open source (BSD licensed), in-memory data structure store,
      * used as a database, cache, and message broker.
      */
-    REDIS(27, true);
+    REDIS(27, true),
+
+    /*
+     * Elasticsearch is a distributed, open source search and analytics engine for all types of data,
+     * including textual, numerical, geospatial, structured, and unstructured.
+     */
+    ELASTICSEARCH(28, true);
 
     private final int value;
     /**
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java
index 96d03f7e64b4..8986e7f8f466 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java
@@ -66,6 +66,7 @@ public class UITemplateInitializer {
         Layer.AWS_DYNAMODB.name(),
         Layer.AWS_GATEWAY.name(),
         Layer.REDIS.name(),
+        Layer.ELASTICSEARCH.name(),
         "custom"
     };
     private final UITemplateManagementService uiTemplateManagementService;
diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml
index 774fd2c4d518..76c775e765ba 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -332,8 +332,7 @@ receiver-otel:
   selector: ${SW_OTEL_RECEIVER:default}
   default:
     enabledHandlers: ${SW_OTEL_RECEIVER_ENABLED_HANDLERS:"oc,otlp"}
-    enabledOtelRules: ${SW_OTEL_RECEIVER_ENABLED_OTEL_RULES:"apisix,k8s/*,istio-controlplane,vm,mysql/*,postgresql/*,oap,aws-eks/*,windows,aws-s3/*,aws-dynamodb/*,aws-gateway/*,redis/*"}
-
+    enabledOtelRules: ${SW_OTEL_RECEIVER_ENABLED_OTEL_RULES:"apisix,k8s/*,istio-controlplane,vm,mysql/*,postgresql/*,oap,aws-eks/*,windows,aws-s3/*,aws-dynamodb/*,aws-gateway/*,redis/*,elasticsearch/*"}
 
 receiver-zipkin:
   selector: ${SW_RECEIVER_ZIPKIN:-}
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-cluster.yaml b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-cluster.yaml
new file mode 100644
index 000000000000..2f324d7b46a4
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-cluster.yaml
@@ -0,0 +1,72 @@
+# 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.
+
+# This will parse a textual representation of a duration. The formats
+# accepted are based on the ISO-8601 duration format {@code PnDTnHnMn.nS}
+# with days considered to be exactly 24 hours.
+# <p>
+# Examples:
+# <pre>
+#    "PT20.345S" -- parses as "20.345 seconds"
+#    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
+#    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
+#    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
+#    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
+#    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
+#    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
+#    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
+# </pre>
+filter: "{ tags -> tags.job_name == 'elasticsearch-monitoring' }" # The OpenTelemetry job name
+expSuffix: tag({tags -> tags.cluster = 'elasticsearch::' + tags.cluster}).service(['cluster'], Layer.ELASTICSEARCH)
+metricPrefix: meter_elasticsearch_cluster
+metricsRules:
+  # cluster health
+  - name: health_status
+    exp: elasticsearch_cluster_health_status.valueEqual(1).sum(['cluster' , 'color'])
+  # elasticsearch_breakers_tripped
+  - name: breakers_tripped
+    exp: elasticsearch_breakers_tripped.sum(['cluster']).increase('PT1M')
+  # cluster nodes
+  - name: nodes
+    exp: elasticsearch_cluster_health_number_of_nodes.sum(['cluster'])
+  # cluster data nodes
+  - name: data_nodes
+    exp: elasticsearch_cluster_health_number_of_data_nodes.sum(['cluster'])
+  # pending tasks total
+  - name: pending_tasks_total
+    exp: elasticsearch_cluster_health_number_of_pending_tasks.sum(['cluster'])
+  # cpu usage avg
+  - name: cpu_usage_avg
+    exp: elasticsearch_process_cpu_percent.avg(['cluster'])
+  # jvm used memory avg
+  - name: jvm_memory_used_avg
+    exp: elasticsearch_jvm_memory_used_bytes.sum(['cluster']) / elasticsearch_jvm_memory_max_bytes.sum(['cluster'])  * 100
+  # open file count
+  - name: open_file_count
+    exp: elasticsearch_process_open_files_count.sum(['cluster'])
+
+  # shards
+  - name: primary_shards_total
+    exp: elasticsearch_cluster_health_active_primary_shards.sum(['cluster'])
+  - name: shards_total
+    exp: elasticsearch_cluster_health_active_shards.sum(['cluster'])
+  - name: initializing_shards_total
+    exp: elasticsearch_cluster_health_initializing_shards.sum(['cluster'])
+  - name: delayed_unassigned_shards_total
+    exp: elasticsearch_cluster_health_delayed_unassigned_shards.sum(['cluster'])
+  - name: relocating_shards_total
+    exp: elasticsearch_cluster_health_relocating_shards.sum(['cluster'])
+  - name: unassigned_shards_total
+    exp: elasticsearch_cluster_health_unassigned_shards.sum(['cluster'])
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-index.yaml b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-index.yaml
new file mode 100644
index 000000000000..a31f05882914
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-index.yaml
@@ -0,0 +1,127 @@
+# 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.
+
+# This will parse a textual representation of a duration. The formats
+# accepted are based on the ISO-8601 duration format {@code PnDTnHnMn.nS}
+# with days considered to be exactly 24 hours.
+# <p>
+# Examples:
+# <pre>
+#    "PT20.345S" -- parses as "20.345 seconds"
+#    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
+#    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
+#    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
+#    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
+#    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
+#    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
+#    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
+# </pre>
+filter: "{ tags -> tags.job_name == 'elasticsearch-monitoring' }" # The OpenTelemetry job name
+expSuffix: tag({tags -> tags.cluster = 'elasticsearch::' + tags.cluster}).endpoint(['cluster'], ['index'], Layer.ELASTICSEARCH)
+metricPrefix: meter_elasticsearch_index
+metricsRules:
+  - name: stats_indexing_index_total_req_rate
+    exp: elasticsearch_index_stats_indexing_index_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_indexing_index_total_proc_rate
+    exp: 1 / (elasticsearch_index_stats_indexing_index_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') / elasticsearch_index_stats_indexing_index_total.sum(['cluster' , 'index']).rate('PT1M'))
+
+  - name: stats_search_query_total_req_rate
+    exp: elasticsearch_index_stats_search_query_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_query_total_proc_rate
+    exp: 1 / ((elasticsearch_index_stats_search_query_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') + elasticsearch_index_stats_search_fetch_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') + elasticsearch_index_stats_search_scroll_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') + elasticsearch_index_stats_search_suggest_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')) / elasticsearch_index_stats_search_query_total.sum(['cluster' , 'index']).rate('PT1M'))
+
+  - name: stats_merge_total_req_rate
+    exp: elasticsearch_index_stats_merge_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_flush_total_req_rate
+    exp: elasticsearch_index_stats_flush_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_refresh_total_req_rate
+    exp: elasticsearch_index_stats_refresh_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_warmer_total_req_rate
+    exp: elasticsearch_index_stats_warmer_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_indexing_delete_total_req_rate
+    exp: elasticsearch_index_stats_indexing_delete_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_fetch_total_req_rate
+    exp: elasticsearch_index_stats_search_fetch_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_scroll_total_req_rate
+    exp: elasticsearch_index_stats_search_scroll_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_suggest_total_req_rate
+    exp: elasticsearch_index_stats_search_suggest_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_get_total_req_rate
+    exp: elasticsearch_index_stats_get_total.sum(['cluster' , 'index']).rate('PT1M')
+
+  - name: stats_merge_time_seconds_total
+    exp: elasticsearch_index_stats_merge_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_flush_time_seconds_total
+    exp: elasticsearch_index_stats_flush_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_refresh_time_seconds_total
+    exp: elasticsearch_index_stats_refresh_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_warmer_time_seconds_total
+    exp: elasticsearch_index_stats_warmer_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_indexing_delete_time_seconds_total
+    exp: elasticsearch_index_stats_indexing_delete_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_fetch_time_seconds_total
+    exp: elasticsearch_index_stats_search_fetch_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_query_time_seconds_total
+    exp: elasticsearch_index_stats_search_query_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_scroll_time_seconds_total
+    exp: elasticsearch_index_stats_search_scroll_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_search_suggest_time_seconds_total
+    exp: elasticsearch_index_stats_search_suggest_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_indexing_index_time_seconds_total
+    exp: elasticsearch_index_stats_indexing_index_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_get_time_seconds_total
+    exp: elasticsearch_index_stats_get_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_merge_stopped_time_seconds_total
+    exp: elasticsearch_index_stats_merge_stopped_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_merge_throttle_time_seconds_total
+    exp: elasticsearch_index_stats_merge_throttle_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: stats_indexing_throttle_time_seconds_total
+    exp: elasticsearch_index_stats_indexing_throttle_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M')
+
+  - name: search_fetch_avg_time
+    exp: elasticsearch_index_stats_search_fetch_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') / elasticsearch_index_stats_search_fetch_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: search_query_avg_time
+    exp: elasticsearch_index_stats_search_query_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') / elasticsearch_index_stats_search_query_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: search_scroll_avg_time
+    exp: elasticsearch_index_stats_search_scroll_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') / elasticsearch_index_stats_search_scroll_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: search_suggest_avg_time
+    exp: elasticsearch_index_stats_search_suggest_time_seconds_total.sum(['cluster' , 'index']).rate('PT1M') / elasticsearch_index_stats_search_suggest_total.sum(['cluster' , 'index']).rate('PT1M')
+
+  - name: indices_docs_primary
+    exp: elasticsearch_indices_docs_primary.sum(['cluster' , 'index'])
+  - name: indices_docs_primary_rate
+    exp: elasticsearch_indices_docs_primary.sum(['cluster' , 'index']).rate('PT1M')
+  - name: indices_store_size_bytes_primary
+    exp: elasticsearch_indices_store_size_bytes_primary.sum(['cluster' , 'index'])
+  - name: indices_docs_total
+    exp: elasticsearch_indices_docs_total.sum(['cluster' , 'index'])
+  - name: indices_docs_total_rate
+    exp: elasticsearch_indices_docs_total.sum(['cluster' , 'index']).rate('PT1M')
+  - name: indices_store_size_bytes_total
+    exp: elasticsearch_indices_store_size_bytes_total.sum(['cluster' , 'index'])
+  - name: indices_deleted_docs_primary
+    exp: elasticsearch_indices_deleted_docs_primary.sum(['cluster' , 'index'])
+
+  - name: indices_segment_count_total
+    exp: elasticsearch_indices_segment_count_total.sum(['cluster' , 'index'])
+  - name: indices_segment_memory_bytes_total
+    exp: elasticsearch_indices_segment_memory_bytes_total.sum(['cluster' , 'index'])
+  - name: indices_segment_count_primary
+    exp: elasticsearch_indices_segment_count_primary.sum(['cluster' , 'index'])
+  - name: indices_segment_memory_bytes_primary
+    exp: elasticsearch_indices_segment_memory_bytes_primary.sum(['cluster' , 'index'])
+
+  - name: indices_shards_docs
+    exp: elasticsearch_indices_shards_docs.sum(['cluster' , 'index' , 'primary' , 'shard']).tag({tags -> if (tags['primary'] == 'true') {tags.primary = 'primary'} else {tags.primary = 'replica'} })
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-node.yaml b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-node.yaml
new file mode 100644
index 000000000000..90f428a3e8c3
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/elasticsearch/elasticsearch-node.yaml
@@ -0,0 +1,149 @@
+# 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.
+
+# This will parse a textual representation of a duration. The formats
+# accepted are based on the ISO-8601 duration format {@code PnDTnHnMn.nS}
+# with days considered to be exactly 24 hours.
+# <p>
+# Examples:
+# <pre>
+#    "PT20.345S" -- parses as "20.345 seconds"
+#    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
+#    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
+#    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
+#    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
+#    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
+#    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
+#    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
+# </pre>
+filter: "{ tags -> tags.job_name == 'elasticsearch-monitoring' }" # The OpenTelemetry job name
+expSuffix: tag({tags -> tags.cluster = 'elasticsearch::' + tags.cluster}).instance(['cluster'], ['name'], Layer.ELASTICSEARCH)
+metricPrefix: meter_elasticsearch_node
+metricsRules:
+  # node rules
+  - name: rules
+    exp: elasticsearch_process_cpu_percent.sum(['cluster' , 'name' , 'es_client_node' , 'es_data_node' , 'es_ingest_node' , 'es_master_node'])
+  - name: open_file_count
+    exp: elasticsearch_process_open_files_count.sum(['cluster' , 'name'])
+  - name: all_disk_free_space
+    exp: elasticsearch_filesystem_data_available_bytes.sum(['cluster' , 'name'])
+  - name: jvm_memory_used
+    exp: elasticsearch_jvm_memory_used_bytes.sum(['cluster' , 'name'])
+
+  # jvm
+  - name: jvm_memory_nonheap_used
+    exp: elasticsearch_jvm_memory_used_bytes.tagEqual('area' , 'non-heap').sum(['cluster' , 'name'])
+  - name: jvm_memory_heap_used
+    exp: elasticsearch_jvm_memory_used_bytes.tagEqual('area' , 'heap').sum(['cluster' , 'name'])
+  - name: jvm_memory_heap_max
+    exp: elasticsearch_jvm_memory_max_bytes.tagEqual('area' , 'heap').sum(['cluster' , 'name'])
+  - name: jvm_memory_nonheap_committed
+    exp: elasticsearch_jvm_memory_committed_bytes.tagEqual('area' , 'non-heap').sum(['cluster' , 'name'])
+  - name: jvm_memory_heap_committed
+    exp: elasticsearch_jvm_memory_committed_bytes.tagEqual('area' , 'heap').sum(['cluster' , 'name'])
+  - name: jvm_memory_pool_peak_used
+    exp: elasticsearch_jvm_memory_pool_peak_used_bytes.sum(['cluster' , 'name' , 'pool'])
+  - name: jvm_gc_count
+    exp: elasticsearch_jvm_gc_collection_seconds_count.sum(['cluster' , 'name' , 'gc']).increase('PT1M')
+  - name: jvm_gc_time
+    exp: (elasticsearch_jvm_gc_collection_seconds_sum * 1000).sum(['cluster' , 'name' , 'gc']).increase('PT1M')
+
+  # cpu
+  - name: process_cpu_percent
+    exp: elasticsearch_process_cpu_percent.sum(['cluster' , 'name'])
+  - name: os_cpu_percent
+    exp: elasticsearch_os_cpu_percent.sum(['cluster' , 'name'])
+  - name: os_load1
+    exp: elasticsearch_os_load1.sum(['cluster' , 'name']) * 100
+  - name: os_load5
+    exp: elasticsearch_os_load5.sum(['cluster' , 'name']) * 100
+  - name: os_load15
+    exp: elasticsearch_os_load15.sum(['cluster' , 'name']) * 100
+
+  # translog
+  - name: indices_translog_operations
+    exp: elasticsearch_indices_translog_operations.sum(['cluster' , 'name']).irate()
+  - name: indices_translog_size
+    exp: elasticsearch_indices_translog_size_in_bytes.sum(['cluster' , 'name']).irate()
+
+  # breakers tripped
+  - name: breakers_tripped
+    exp: elasticsearch_breakers_tripped.sum(['cluster' , 'name' , 'breaker']).increase('PT1M')
+  - name: breakers_estimated_size
+    exp: elasticsearch_breakers_estimated_size_bytes.sum(['cluster' , 'name' , 'breaker'])
+
+  # disk
+  - name: disk_usage_percent
+    exp: 100 - (elasticsearch_filesystem_data_available_bytes * 100).sum(['cluster' , 'name' , 'mount']) / elasticsearch_filesystem_data_size_bytes.sum(['cluster' , 'name' , 'mount'])
+  - name: disk_usage
+    exp: elasticsearch_filesystem_data_size_bytes.sum(['cluster' , 'name' , 'mount']) - elasticsearch_filesystem_data_available_bytes.sum(['cluster' , 'name' , 'mount'])
+  - name: disk_io_read_bytes
+    exp: elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum.sum(['cluster' , 'name' , 'mount']).irate()
+  - name: disk_io_write_bytes
+    exp: elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum.sum(['cluster' , 'name' , 'mount']).irate()
+
+  # network
+  - name: network_send_bytes
+    exp: elasticsearch_transport_tx_size_bytes_total.sum(['cluster' , 'name']).irate()
+  - name: network_receive_bytes
+    exp: elasticsearch_transport_rx_size_bytes_total.sum(['cluster' , 'name']).irate()
+
+  # operations
+  - name: indices_search_query_total_req_rate
+    exp: elasticsearch_indices_search_query_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_search_query_time_seconds_proc_rate
+    exp: 1 / ((elasticsearch_indices_search_query_time_seconds.sum(['cluster' , 'name']).rate('PT1M') + elasticsearch_indices_search_fetch_time_seconds.sum(['cluster' , 'name']).rate('PT1M') + elasticsearch_indices_search_scroll_time_seconds.sum(['cluster' , 'name']).rate('PT1M') + elasticsearch_indices_search_suggest_time_seconds.sum(['cluster' , 'name']).rate('PT1M')) / elasticsearch_indices_search_query_total.sum(['cluster' , 'name']).rate('PT1M'))
+  - name: indices_search_fetch_total_req_rate
+    exp: elasticsearch_indices_search_fetch_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_search_fetch_time_seconds
+    exp: elasticsearch_indices_search_fetch_time_seconds.sum(['cluster' , 'name']).increase('PT1M')
+  - name: indices_indexing_index_total_req_rate
+    exp: elasticsearch_indices_indexing_index_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_indexing_index_total_proc_rate
+    exp: 1 / (elasticsearch_indices_indexing_index_time_seconds_total.sum(['cluster' , 'name']).rate('PT1M') / elasticsearch_indices_indexing_index_total.sum(['cluster' , 'name']).rate('PT1M'))
+  - name: indices_merges_total_req_rate
+    exp: elasticsearch_indices_merges_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_refresh_total_req_rate
+    exp: elasticsearch_indices_refresh_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_flush_total_req_rate
+    exp: elasticsearch_indices_flush_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_get_exists_total_req_rate
+    exp: elasticsearch_indices_get_exists_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_get_missing_total_req_rate
+    exp: elasticsearch_indices_get_missing_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_get_total_req_rate
+    exp: elasticsearch_indices_get_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_indexing_delete_total_req_rate
+    exp: elasticsearch_indices_indexing_delete_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_search_scroll_total_req_rate
+    exp: elasticsearch_indices_search_scroll_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_search_suggest_total_req_rate
+    exp: elasticsearch_indices_search_suggest_total.sum(['cluster' , 'name']).rate('PT1M')
+
+  - name: indices_docs
+    exp: elasticsearch_indices_docs.sum(['cluster' , 'name'])
+  - name: indices_docs_deleted_total
+    exp: elasticsearch_indices_docs_deleted.sum(['cluster' , 'name'])
+  - name: indices_docs_deleted
+    exp: elasticsearch_indices_docs_deleted.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_merges_docs_total
+    exp: elasticsearch_indices_merges_docs_total.sum(['cluster' , 'name']).rate('PT1M')
+  - name: indices_merges_total_size_bytes_total
+    exp: elasticsearch_indices_merges_total_size_bytes_total.sum(['cluster' , 'name']).rate('PT1M')
+
+  - name: segment_count
+    exp: elasticsearch_indices_segments_count.sum(['cluster' , 'name'])
+  - name: segment_memory
+    exp: elasticsearch_indices_segments_memory_bytes.sum(['cluster' , 'name'])
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-cluster.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-cluster.json
new file mode 100644
index 000000000000..30f9834d3cac
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-cluster.json
@@ -0,0 +1,454 @@
+/**
+ * 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.
+ */
+[
+  {
+    "id": "Elasticsearch-Cluster",
+    "configuration": {
+      "children":[
+        {
+          "x":0,
+          "y":0,
+          "w":24,
+          "h":56,
+          "i":"0",
+          "type":"Tab",
+          "id":"0",
+          "metricTypes":[
+            ""
+          ],
+          "metrics":[
+            ""
+          ],
+          "activedTabIndex":0,
+          "children":[
+            {
+              "name":"Overview",
+              "children":[
+                {
+                  "x":0,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"0",
+                  "type":"Widget",
+                  "id":"0-0-0",
+                  "metricTypes":[
+                    "readLabeledMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_health_status"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Table",
+                    "showTableValues":false,
+                    "tableHeaderCol1":"status",
+                    "tableHeaderCol2":""
+                  },
+                  "widget":{
+                    "title":"Cluster Health"
+                  }
+                },
+                {
+                  "x":15,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"1",
+                  "type":"Widget",
+                  "id":"0-0-1",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_nodes"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Data Nodes"
+                  }
+                },
+                {
+                  "x":12,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"2",
+                  "type":"Widget",
+                  "id":"0-0-2",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_nodes"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Nodes"
+                  }
+                },
+                {
+                  "x":18,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"3",
+                  "type":"Widget",
+                  "id":"0-0-3",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_pending_tasks_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Pending Tasks"
+                  }
+                },
+                {
+                  "x":0,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"4",
+                  "type":"Widget",
+                  "id":"0-0-4",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_primary_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Active Primary Shards"
+                  }
+                },
+                {
+                  "x":4,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"5",
+                  "type":"Widget",
+                  "id":"0-0-5",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Active Shards"
+                  }
+                },
+                {
+                  "x":8,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"6",
+                  "type":"Widget",
+                  "id":"0-0-6",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_initializing_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Initializing Shards"
+                  }
+                },
+                {
+                  "x":16,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"7",
+                  "type":"Widget",
+                  "id":"0-0-7",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_delayed_unassigned_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Delayed Unassigned Shards"
+                  }
+                },
+                {
+                  "x":20,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"8",
+                  "type":"Widget",
+                  "id":"0-0-8",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_relocating_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Relocating Shards"
+                  }
+                },
+                {
+                  "x":12,
+                  "y":6,
+                  "w":4,
+                  "h":5,
+                  "i":"9",
+                  "type":"Widget",
+                  "id":"0-0-9",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_unassigned_shards_total"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":false
+                  },
+                  "widget":{
+                    "title":"Unassigned Shards"
+                  }
+                },
+                {
+                  "x":3,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"12",
+                  "type":"Widget",
+                  "id":"0-0-12",
+                  "metricTypes":[
+                    "readMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_breakers_tripped"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Tripped Of Breakers"
+                  }
+                },
+                {
+                  "x":6,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"13",
+                  "type":"Widget",
+                  "id":"0-0-13",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_cpu_usage_avg"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"CPU Usage Avg. (%)"
+                  }
+                },
+                {
+                  "x":9,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"14",
+                  "type":"Widget",
+                  "id":"0-0-14",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_jvm_memory_used_avg"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"JVM Memory Used Avg. (%)"
+                  }
+                },
+                {
+                  "x":21,
+                  "y":0,
+                  "w":3,
+                  "h":6,
+                  "i":"15",
+                  "type":"Widget",
+                  "id":"0-0-15",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_elasticsearch_cluster_open_file_count"
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Open Files"
+                  }
+                },
+                {
+                  "x":0,
+                  "y":11,
+                  "w":24,
+                  "h":16,
+                  "i":"16",
+                  "type":"Widget",
+                  "id":"0-0-16",
+                  "metricTypes":[
+                    ""
+                  ],
+                  "metrics":[
+                    ""
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"InstanceList",
+                    "dashboardName":"Elasticsearch-Node",
+                    "fontSize":12
+                  },
+                  "widget":{
+                    "title":"Nodes"
+                  }
+                },
+                {
+                  "x":0,
+                  "y":27,
+                  "w":24,
+                  "h":20,
+                  "i":"17",
+                  "type":"Widget",
+                  "id":"0-0-17",
+                  "metricTypes":[
+                    ""
+                  ],
+                  "metrics":[
+                    ""
+                  ],
+                  "moved":false,
+                  "graph":{
+                    "type":"EndpointList",
+                    "dashboardName":"Elasticsearch-Index",
+                    "fontSize":12,
+                    "showXAxis":false,
+                    "showYAxis":false
+                  },
+                  "widget":{
+                    "title":"Indices"
+                  }
+                }
+              ]
+            }
+          ],
+          "moved":false
+        }
+      ],
+      "layer":"ELASTICSEARCH",
+      "entity":"Service",
+      "name":"Elasticsearch-Cluster",
+      "id":"Elasticsearch-Cluster",
+      "isRoot":false
+    }
+  }
+]
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-index.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-index.json
new file mode 100644
index 000000000000..2a2a8951cb16
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-index.json
@@ -0,0 +1,796 @@
+/**
+ * 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.
+ */
+[
+  {
+    "id": "Elasticsearch-Index",
+    "configuration": {
+      "children":[
+        {
+          "x":0,
+          "y":6,
+          "w":12,
+          "h":13,
+          "i":"0",
+          "type":"Widget",
+          "id":"0",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_stats_indexing_index_total_req_rate",
+            "meter_elasticsearch_index_stats_indexing_index_total_proc_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Indexing Rate",
+            "tips":"`proc_rate`: processing ability, which is the number of requests that Elasticsearch can handle. Estimation is based on the processed requests and processed time for these requests."
+          },
+          "metricConfig":[
+            {
+              "label":"req_rate"
+            },
+            {
+              "label":"proc_rate"
+            }
+          ]
+        },
+        {
+          "x":12,
+          "y":6,
+          "w":12,
+          "h":13,
+          "i":"1",
+          "type":"Widget",
+          "id":"1",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_stats_search_query_total_req_rate",
+            "meter_elasticsearch_index_stats_search_query_total_proc_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Searching Rate",
+            "tips":"`proc_rate`: processing ability, which is the number of requests that Elasticsearch can handle. Estimation is based on the processed requests and processed time for these requests."
+          },
+          "metricConfig":[
+            {
+              "label":"req_rate"
+            },
+            {
+              "label":"proc_rate"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":19,
+          "w":12,
+          "h":16,
+          "i":"2",
+          "type":"Widget",
+          "id":"2",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_stats_merge_total_req_rate",
+            "meter_elasticsearch_index_stats_flush_total_req_rate",
+            "meter_elasticsearch_index_stats_refresh_total_req_rate",
+            "meter_elasticsearch_index_stats_warmer_total_req_rate",
+            "meter_elasticsearch_index_stats_indexing_delete_total_req_rate",
+            "meter_elasticsearch_index_stats_search_fetch_total_req_rate",
+            "meter_elasticsearch_index_stats_search_query_total_req_rate",
+            "meter_elasticsearch_index_stats_search_scroll_total_req_rate",
+            "meter_elasticsearch_index_stats_search_suggest_total_req_rate",
+            "meter_elasticsearch_index_stats_indexing_index_total_req_rate",
+            "meter_elasticsearch_index_stats_get_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"All Operations ReqRate"
+          },
+          "metricConfig":[
+            {
+              "label":"merge"
+            },
+            {
+              "label":"flush"
+            },
+            {
+              "label":"refresh"
+            },
+            {
+              "label":"warmer"
+            },
+            {
+              "label":"indexing_delete"
+            },
+            {
+              "label":"search_fetch"
+            },
+            {
+              "label":"search_query"
+            },
+            {
+              "label":"search_scroll"
+            },
+            {
+              "label":"search_suggest"
+            },
+            {
+              "label":"indexing_index"
+            },
+            {
+              "label":"get"
+            }
+          ]
+        },
+        {
+          "x":12,
+          "y":19,
+          "w":12,
+          "h":16,
+          "i":"3",
+          "type":"Widget",
+          "id":"3",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_stats_merge_time_seconds_total",
+            "meter_elasticsearch_index_stats_flush_time_seconds_total",
+            "meter_elasticsearch_index_stats_refresh_time_seconds_total",
+            "meter_elasticsearch_index_stats_warmer_time_seconds_total",
+            "meter_elasticsearch_index_stats_indexing_delete_time_seconds_total",
+            "meter_elasticsearch_index_stats_search_fetch_time_seconds_total",
+            "meter_elasticsearch_index_stats_search_query_time_seconds_total",
+            "meter_elasticsearch_index_stats_search_scroll_time_seconds_total",
+            "meter_elasticsearch_index_stats_search_suggest_time_seconds_total",
+            "meter_elasticsearch_index_stats_indexing_index_time_seconds_total",
+            "meter_elasticsearch_index_stats_get_time_seconds_total",
+            "meter_elasticsearch_index_stats_merge_stopped_time_seconds_total",
+            "meter_elasticsearch_index_stats_merge_throttle_time_seconds_total",
+            "meter_elasticsearch_index_stats_indexing_throttle_time_seconds_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"All Operations Runtime (s)"
+          },
+          "metricConfig":[
+            {
+              "label":"merge"
+            },
+            {
+              "label":"flush"
+            },
+            {
+              "label":"refresh"
+            },
+            {
+              "label":"warmer"
+            },
+            {
+              "label":"indexing_delete"
+            },
+            {
+              "label":"search_fetch"
+            },
+            {
+              "label":"search_query"
+            },
+            {
+              "label":"search_scroll"
+            },
+            {
+              "label":"search_suggest"
+            },
+            {
+              "label":"indexing_index"
+            },
+            {
+              "label":"get"
+            },
+            {
+              "label":"merge_stopped"
+            },
+            {
+              "label":"merge_throttle"
+            },
+            {
+              "label":"indexing_throttle"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":35,
+          "w":8,
+          "h":13,
+          "i":"4",
+          "type":"Widget",
+          "id":"4",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_search_fetch_avg_time",
+            "meter_elasticsearch_index_search_query_avg_time",
+            "meter_elasticsearch_index_search_scroll_avg_time",
+            "meter_elasticsearch_index_search_suggest_avg_time"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Avg. Search Time Execute / Request (s)"
+          },
+          "metricConfig":[
+            {
+              "label":"search_fetch"
+            },
+            {
+              "label":"search_query"
+            },
+            {
+              "label":"search_scroll"
+            },
+            {
+              "label":"search_suggest"
+            }
+          ]
+        },
+        {
+          "x":8,
+          "y":35,
+          "w":8,
+          "h":13,
+          "i":"5",
+          "type":"Widget",
+          "id":"5",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_stats_search_fetch_total_req_rate",
+            "meter_elasticsearch_index_stats_search_query_total_req_rate",
+            "meter_elasticsearch_index_stats_search_scroll_total_req_rate",
+            "meter_elasticsearch_index_stats_search_suggest_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "label":"search_fetch"
+            },
+            {
+              "label":"search_query"
+            },
+            {
+              "label":"search_scroll"
+            },
+            {
+              "label":"search_suggest"
+            }
+          ],
+          "widget":{
+            "title":"Search Operations Rate (req/s)"
+          }
+        },
+        {
+          "x":16,
+          "y":59,
+          "w":8,
+          "h":11,
+          "i":"6",
+          "type":"Widget",
+          "id":"6",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_store_size_bytes_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Total Size Of Index (All Shards) (MB)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":59,
+          "w":8,
+          "h":11,
+          "i":"7",
+          "type":"Widget",
+          "id":"7",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_docs_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Documents (All Shards)"
+          }
+        },
+        {
+          "x":8,
+          "y":59,
+          "w":8,
+          "h":11,
+          "i":"8",
+          "type":"Widget",
+          "id":"8",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_docs_total_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Documents Created Per Min (All Shards)"
+          }
+        },
+        {
+          "x":0,
+          "y":48,
+          "w":8,
+          "h":11,
+          "i":"9",
+          "type":"Widget",
+          "id":"9",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_docs_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Documents (Primary Shards)"
+          }
+        },
+        {
+          "x":8,
+          "y":48,
+          "w":8,
+          "h":11,
+          "i":"10",
+          "type":"Widget",
+          "id":"10",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_docs_primary_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Documents Created Per Min (Primary Shards)"
+          }
+        },
+        {
+          "x":16,
+          "y":48,
+          "w":8,
+          "h":11,
+          "i":"11",
+          "type":"Widget",
+          "id":"11",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_store_size_bytes_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"Total Size Of Index (Primary Shards) (MB)"
+          }
+        },
+        {
+          "x":0,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"12",
+          "type":"Widget",
+          "id":"12",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_docs_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Documents Count (Primary Shard)"
+          }
+        },
+        {
+          "x":9,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"14",
+          "type":"Widget",
+          "id":"14",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_store_size_bytes_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToGB"
+            }
+          ],
+          "widget":{
+            "title":"Data (GB)"
+          }
+        },
+        {
+          "x":6,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"15",
+          "type":"Widget",
+          "id":"15",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_store_size_bytes_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToGB"
+            }
+          ],
+          "widget":{
+            "title":"Data (Primary Shards) (GB)"
+          }
+        },
+        {
+          "x":18,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"16",
+          "type":"Widget",
+          "id":"16",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_segment_count_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Segments Count"
+          }
+        },
+        {
+          "x":12,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"17",
+          "type":"Widget",
+          "id":"17",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_segment_count_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Segments Count (Primary Shards)"
+          }
+        },
+        {
+          "x":21,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"18",
+          "type":"Widget",
+          "id":"18",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_segment_memory_bytes_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"Segments Memory (MB)"
+          }
+        },
+        {
+          "x":3,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"19",
+          "type":"Widget",
+          "id":"19",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_deleted_docs_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Deleted Documents Count (Primary Shard)"
+          }
+        },
+        {
+          "x":15,
+          "y":0,
+          "w":3,
+          "h":6,
+          "i":"20",
+          "type":"Widget",
+          "id":"20",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_segment_memory_bytes_primary"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Segments Memory (Primary Shards) (MB)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ]
+        },
+        {
+          "x":16,
+          "y":35,
+          "w":8,
+          "h":13,
+          "i":"21",
+          "type":"Widget",
+          "id":"21",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_index_indices_shards_docs"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Table",
+            "showTableValues":true,
+            "tableHeaderCol1":"",
+            "tableHeaderCol2":""
+          },
+          "widget":{
+            "title":"Shards Documents"
+          }
+        }
+      ],
+      "layer":"ELASTICSEARCH",
+      "entity":"Endpoint",
+      "name":"Elasticsearch-Index",
+      "id":"Elasticsearch-Index",
+      "isRoot":false
+    }
+  }
+]
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-node.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-node.json
new file mode 100644
index 000000000000..aa2b8e07c2b6
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-node.json
@@ -0,0 +1,1132 @@
+/**
+ * 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.
+ */
+[
+  {
+    "id": "Elasticsearch-Node",
+    "configuration": {
+      "children":[
+        {
+          "x":0,
+          "y":7,
+          "w":8,
+          "h":13,
+          "i":"0",
+          "type":"Widget",
+          "id":"0",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_process_cpu_percent"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":false
+            }
+          },
+          "widget":{
+            "title":"Process CPU Usage Percent (%)"
+          }
+        },
+        {
+          "x":16,
+          "y":7,
+          "w":8,
+          "h":13,
+          "i":"1",
+          "type":"Widget",
+          "id":"1",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_os_load1",
+            "meter_elasticsearch_node_os_load5",
+            "meter_elasticsearch_node_os_load15"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Load Average"
+          },
+          "metricConfig":[
+            {
+              "calculation":"percentage",
+              "label":"load1"
+            },
+            {
+              "calculation":"percentage",
+              "label":"load5"
+            },
+            {
+              "calculation":"percentage",
+              "label":"load15"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":20,
+          "w":6,
+          "h":13,
+          "i":"2",
+          "type":"Widget",
+          "id":"2",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_jvm_memory_heap_used",
+            "meter_elasticsearch_node_jvm_memory_heap_max",
+            "meter_elasticsearch_node_jvm_memory_nonheap_used"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Area",
+            "opacity":0.4,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB",
+              "label":"heap_used"
+            },
+            {
+              "calculation":"byteToMB",
+              "label":"heap_max"
+            },
+            {
+              "calculation":"byteToMB",
+              "label":"nonheap_used"
+            }
+          ],
+          "widget":{
+            "title":"JVM Memory Usage (MB)"
+          }
+        },
+        {
+          "x":6,
+          "y":20,
+          "w":6,
+          "h":13,
+          "i":"3",
+          "type":"Widget",
+          "id":"3",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_jvm_memory_pool_peak_used"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Area",
+            "opacity":0.4,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"JVM Pool Peak Used (MB)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "relatedTrace":{
+            "refIdType":"none"
+          }
+        },
+        {
+          "x":12,
+          "y":20,
+          "w":6,
+          "h":13,
+          "i":"4",
+          "type":"Widget",
+          "id":"4",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_jvm_gc_count"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Bar",
+            "showBackground":true
+          },
+          "widget":{
+            "title":"GC Count"
+          }
+        },
+        {
+          "x":18,
+          "y":20,
+          "w":6,
+          "h":13,
+          "i":"5",
+          "type":"Widget",
+          "id":"5",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_jvm_gc_time"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"GC Time (ms/min)"
+          },
+          "metricConfig":[
+            {
+              "calculation":""
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":33,
+          "w":8,
+          "h":13,
+          "i":"6",
+          "type":"Widget",
+          "id":"6",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_indexing_index_total_req_rate",
+            "meter_elasticsearch_node_indices_search_query_total_req_rate",
+            "meter_elasticsearch_node_indices_search_fetch_total_req_rate",
+            "meter_elasticsearch_node_indices_merges_total_req_rate",
+            "meter_elasticsearch_node_indices_refresh_total_req_rate",
+            "meter_elasticsearch_node_indices_flush_total_req_rate",
+            "meter_elasticsearch_node_indices_get_exists_total_req_rate",
+            "meter_elasticsearch_node_indices_get_missing_total_req_rate",
+            "meter_elasticsearch_node_indices_get_total_req_rate",
+            "meter_elasticsearch_node_indices_indexing_delete_total_req_rate",
+            "meter_elasticsearch_node_indices_search_scroll_total_req_rate",
+            "meter_elasticsearch_node_indices_search_suggest_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"All Operations ReqRate"
+          },
+          "metricConfig":[
+            {
+              "label":"indexing_index"
+            },
+            {
+              "label":"search_query"
+            },
+            {
+              "label":"search_fetch"
+            },
+            {
+              "label":"merges"
+            },
+            {
+              "label":"refresh"
+            },
+            {
+              "label":"flush"
+            },
+            {
+              "label":"get_exists"
+            },
+            {
+              "label":"get_missing"
+            },
+            {
+              "label":"get"
+            },
+            {
+              "label":"indexing_delete"
+            },
+            {
+              "label":"search_scroll"
+            },
+            {
+              "label":"suggest"
+            }
+          ]
+        },
+        {
+          "x":16,
+          "y":33,
+          "w":8,
+          "h":13,
+          "i":"7",
+          "type":"Widget",
+          "id":"7",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_search_query_time_seconds_proc_rate",
+            "meter_elasticsearch_node_indices_search_query_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Searching Rate",
+            "tips":"`proc_rate`: processing ability, which is the number of requests that Elasticsearch can handle. Estimation is based on the processed requests and processed time for these requests."
+          },
+          "metricConfig":[
+            {
+              "label":"proc_rate"
+            },
+            {
+              "label":"req_rate"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":46,
+          "w":6,
+          "h":13,
+          "i":"9",
+          "type":"Widget",
+          "id":"9",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_translog_operations"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Total Translog Operations"
+          }
+        },
+        {
+          "x":6,
+          "y":46,
+          "w":6,
+          "h":13,
+          "i":"10",
+          "type":"Widget",
+          "id":"10",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_translog_size"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Total Translog Size (MB)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ]
+        },
+        {
+          "x":12,
+          "y":46,
+          "w":6,
+          "h":13,
+          "i":"11",
+          "type":"Widget",
+          "id":"11",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_breakers_tripped"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Tripped For Breakers"
+          }
+        },
+        {
+          "x":18,
+          "y":46,
+          "w":6,
+          "h":13,
+          "i":"12",
+          "type":"Widget",
+          "id":"12",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_breakers_estimated_size"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"Estimated Size Of Breaker (MB)"
+          }
+        },
+        {
+          "x":8,
+          "y":86,
+          "w":8,
+          "h":13,
+          "i":"13",
+          "type":"Widget",
+          "id":"13",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_segment_memory"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"Current Memory Size Of Segments (MB)"
+          }
+        },
+        {
+          "x":0,
+          "y":99,
+          "w":6,
+          "h":14,
+          "i":"14",
+          "type":"Widget",
+          "id":"14",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_disk_usage_percent"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":true
+            }
+          },
+          "widget":{
+            "title":"Disk Usage Percent (%)"
+          },
+          "metricConfig":[
+            {
+              "calculation":""
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":59,
+          "w":8,
+          "h":13,
+          "i":"15",
+          "type":"Widget",
+          "id":"15",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_docs"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+
+          ],
+          "widget":{
+            "title":"Documents Count"
+          }
+        },
+        {
+          "x":0,
+          "y":86,
+          "w":8,
+          "h":13,
+          "i":"16",
+          "type":"Widget",
+          "id":"16",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_segment_count"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Bar",
+            "showBackground":true
+          },
+          "widget":{
+            "title":"Count Of Index Segments"
+          }
+        },
+        {
+          "x":0,
+          "y":0,
+          "w":6,
+          "h":7,
+          "i":"17",
+          "type":"Widget",
+          "id":"17",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_rules"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Table",
+            "showTableValues":false,
+            "tableHeaderCol1":"Client-Data-Ingest-Master",
+            "tableHeaderCol2":""
+          },
+          "widget":{
+            "title":"Node Rules"
+          }
+        },
+        {
+          "x":12,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"18",
+          "type":"Widget",
+          "id":"18",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_docs"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Documents"
+          }
+        },
+        {
+          "x":8,
+          "y":7,
+          "w":8,
+          "h":13,
+          "i":"26",
+          "type":"Widget",
+          "id":"26",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_os_cpu_percent"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":false
+            }
+          },
+          "widget":{
+            "title":"OS CPU Usage Persent (%)"
+          }
+        },
+        {
+          "x":6,
+          "y":99,
+          "w":6,
+          "h":14,
+          "i":"27",
+          "type":"Widget",
+          "id":"27",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_disk_usage"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":true
+            }
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToGB"
+            }
+          ],
+          "widget":{
+            "title":"Disk Usage (GB)"
+          }
+        },
+        {
+          "x":16,
+          "y":86,
+          "w":8,
+          "h":13,
+          "i":"28",
+          "type":"Widget",
+          "id":"28",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_network_send_bytes",
+            "meter_elasticsearch_node_network_receive_bytes"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":true
+            }
+          },
+          "widget":{
+            "title":"Network (bytes/sec)"
+          },
+          "metricConfig":[
+            {
+              "label":"sead"
+            },
+            {
+              "label":"receive"
+            }
+          ]
+        },
+        {
+          "x":12,
+          "y":99,
+          "w":6,
+          "h":14,
+          "i":"29",
+          "type":"Widget",
+          "id":"29",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_disk_io_read_bytes"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Disk Read (KBs)"
+          },
+          "metricConfig":[
+            {
+              "unit":"kb"
+            }
+          ]
+        },
+        {
+          "x":15,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"30",
+          "type":"Widget",
+          "id":"30",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_segment_count"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Segments"
+          }
+        },
+        {
+          "x":21,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"31",
+          "type":"Widget",
+          "id":"31",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_open_file_count"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Open Files"
+          }
+        },
+        {
+          "x":18,
+          "y":99,
+          "w":6,
+          "h":14,
+          "i":"32",
+          "type":"Widget",
+          "id":"32",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_disk_io_write_bytes"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":true
+            }
+          },
+          "widget":{
+            "title":"Disk Write (KBs)"
+          }
+        },
+        {
+          "x":6,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"33",
+          "type":"Widget",
+          "id":"33",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_jvm_memory_used"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"JVM Memory Used (MB)"
+          }
+        },
+        {
+          "x":9,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"34",
+          "type":"Widget",
+          "id":"34",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_process_cpu_percent"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"CPU Usage (%)"
+          }
+        },
+        {
+          "x":18,
+          "y":0,
+          "w":3,
+          "h":7,
+          "i":"35",
+          "type":"Widget",
+          "id":"35",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_all_disk_free_space"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToGB"
+            }
+          ],
+          "widget":{
+            "title":"Disk Free Space (GB)"
+          }
+        },
+        {
+          "x":8,
+          "y":33,
+          "w":8,
+          "h":13,
+          "i":"36",
+          "type":"Widget",
+          "id":"36",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_indexing_index_total_proc_rate",
+            "meter_elasticsearch_node_indices_indexing_index_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Indexing Rate",
+            "tips":"`proc_rate`: processing ability, which is the number of requests that Elasticsearch can handle. Estimation is based on the processed requests and processed time for these requests."
+          },
+          "metricConfig":[
+            {
+              "label":"proc_rate"
+            },
+            {
+              "label":"req_rate"
+            }
+          ]
+        },
+        {
+          "x":0,
+          "y":72,
+          "w":8,
+          "h":14,
+          "i":"37",
+          "type":"Widget",
+          "id":"37",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_indexing_index_total_req_rate"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true,
+            "legend":{
+              "show":false
+            }
+          },
+          "widget":{
+            "title":"Documents Index Rate (calls/s)"
+          }
+        },
+        {
+          "x":8,
+          "y":59,
+          "w":8,
+          "h":13,
+          "i":"38",
+          "type":"Widget",
+          "id":"38",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_merges_docs_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Merged Documents Count"
+          }
+        },
+        {
+          "x":16,
+          "y":59,
+          "w":8,
+          "h":13,
+          "i":"39",
+          "type":"Widget",
+          "id":"39",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_docs_deleted_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Deleted Documents"
+          }
+        },
+        {
+          "x":16,
+          "y":72,
+          "w":8,
+          "h":14,
+          "i":"40",
+          "type":"Widget",
+          "id":"40",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_docs_deleted"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Documents Deleted Rate (docs/s)"
+          }
+        },
+        {
+          "x":8,
+          "y":72,
+          "w":8,
+          "h":14,
+          "i":"41",
+          "type":"Widget",
+          "id":"41",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_elasticsearch_node_indices_merges_total_size_bytes_total"
+          ],
+          "moved":false,
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":true,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Merged Documents Rate (MB / s)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ]
+        }
+      ],
+      "layer":"ELASTICSEARCH",
+      "entity":"ServiceInstance",
+      "name":"Elasticsearch-Node",
+      "id":"Elasticsearch-Node",
+      "isRoot":false
+    }
+  }
+]
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-root.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-root.json
new file mode 100644
index 000000000000..31ce4b435c72
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/elasticsearch/elasticsearch-root.json
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ */
+[
+  {
+    "id": "Elasticsearch-Root",
+    "configuration": {
+      "children":[
+        {
+          "x":0,
+          "y":0,
+          "w":24,
+          "h":2,
+          "i":"1",
+          "type":"Text",
+          "id":"1",
+          "metricTypes":[
+            ""
+          ],
+          "metrics":[
+            ""
+          ],
+          "graph":{
+            "fontColor":"blue",
+            "backgroundColor":"white",
+            "content":"Provide Elasticsearch Server monitoring through OpenTelemetry's Prometheus Receiver",
+            "fontSize":14,
+            "textAlign":"left",
+            "url":"https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-elasticsearch-monitoring/"
+          },
+          "moved":false
+        },
+        {
+          "x":0,
+          "y":3,
+          "w":24,
+          "h":37,
+          "i":"2",
+          "type":"Widget",
+          "id":"2",
+          "metricTypes":[
+            ""
+          ],
+          "metrics":[
+            ""
+          ],
+          "moved":false,
+          "graph":{
+            "type":"ServiceList",
+            "dashboardName":"Elasticsearch-Cluster",
+            "fontSize":12,
+            "showXAxis":false,
+            "showYAxis":false,
+            "showGroup":true
+          }
+        }
+      ],
+      "id":"Elasticsearch-Root",
+      "layer":"ELASTICSEARCH",
+      "entity":"All",
+      "name":"Elasticsearch-Root",
+      "isRoot":true
+    }
+  }
+]
\ No newline at end of file


Test patch:
diff --git a/test/e2e-v2/cases/elasticsearch/docker-compose.yml b/test/e2e-v2/cases/elasticsearch/docker-compose.yml
new file mode 100644
index 000000000000..4b18f201b841
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/docker-compose.yml
@@ -0,0 +1,98 @@
+# 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.
+
+version: '2.1'
+
+services:
+  oap:
+    extends:
+      file: ../../script/docker-compose/base-compose.yml
+      service: oap
+    ports:
+      - "12800:12800"
+    networks:
+      - e2e
+  es:
+    image: elastic/elasticsearch:8.3.2
+    expose:
+      - 9200
+    networks:
+      - e2e
+    environment:
+      - discovery.type=single-node
+      - cluster.routing.allocation.disk.threshold_enabled=false
+      - xpack.security.enabled=false
+      - cluster.name=cluster-e2e
+      - node.name=node-e2e
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9200"]
+      interval: 10s
+      timeout: 10s
+      retries: 120
+  es-exporter:
+    image: quay.io/prometheuscommunity/elasticsearch-exporter:v1.5.0
+    expose:
+      - 9114
+    networks:
+      - e2e
+    depends_on:
+      es:
+        condition: service_healthy
+    command:
+      - '--log.format=logfmt'
+      - '--log.level=info'
+      - '--es.uri=http://es:9200'
+      - '--es.all'
+      - '--es.indices'
+      - '--es.indices_settings'
+      - '--es.indices_mappings'
+      - '--es.shards'
+      - '--es.snapshots'
+      - '--es.timeout=30s'
+      - '--web.telemetry-path=/metrics'
+    healthcheck:
+      interval: 5s
+      timeout: 60s
+      retries: 120
+      test: ["CMD", "sh", "-c", "nc -vz localhost 9114"]
+  otel-collector:
+    image: otel/opentelemetry-collector:0.72.0
+    networks:
+      - e2e
+    command: [ "--config=/etc/otel-collector-config.yaml" ]
+    volumes:
+      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
+    expose:
+      - 55678
+    depends_on:
+      oap:
+        condition: service_healthy
+  es-mock:
+    image: curlimages/curl:latest
+    networks:
+      - e2e
+    depends_on:
+      es:
+        condition: service_healthy
+      es-exporter:
+        condition: service_healthy
+      oap:
+        condition: service_healthy
+    command: "sh /etc/es-e2e-data-mock.sh"
+    volumes:
+      - ./es-e2e-data-mock.sh:/etc/es-e2e-data-mock.sh
+
+networks:
+  e2e:
diff --git a/test/e2e-v2/cases/elasticsearch/e2e.yaml b/test/e2e-v2/cases/elasticsearch/e2e.yaml
new file mode 100644
index 000000000000..41af810da9a8
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/e2e.yaml
@@ -0,0 +1,37 @@
+# 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.
+
+# This file is used to show how to write configuration files and can be used to test.
+
+setup:
+  env: compose
+  file: docker-compose.yml
+  timeout: 20m
+  init-system-environment: ../../script/env
+  steps:
+    - name: set PATH
+      command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH
+    - name: install yq
+      command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
+    - name: install swctl
+      command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
+
+verify:
+  retry:
+    count: 60
+    interval: 3s
+  cases:
+    - includes:
+        - ./elasticsearch-cases.yaml
diff --git a/test/e2e-v2/cases/elasticsearch/elasticsearch-cases.yaml b/test/e2e-v2/cases/elasticsearch/elasticsearch-cases.yaml
new file mode 100644
index 000000000000..82ddbf8ac793
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/elasticsearch-cases.yaml
@@ -0,0 +1,219 @@
+# 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.
+
+# This file is used to show how to write configuration files and can be used to test.
+
+cases:
+  # service cases
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql service ls
+    expected: expected/service.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_cluster_health_status --service-name=elasticsearch::cluster-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_breakers_tripped --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_cpu_usage_avg --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_jvm_memory_used_avg --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_nodes --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_data_nodes --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_pending_tasks_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_open_file_count --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_primary_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_initializing_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_delayed_unassigned_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_relocating_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_cluster_unassigned_shards_total --service-name=elasticsearch::cluster-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+
+  # instance cases
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance ls --service-name=elasticsearch::cluster-e2e
+    expected: expected/instance.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_rules --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_jvm_memory_heap_used --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_jvm_memory_nonheap_used --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_jvm_memory_heap_max --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_jvm_memory_pool_peak_used --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_jvm_gc_count --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_jvm_gc_time --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_process_cpu_percent --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_docs --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_segment_count --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_all_disk_free_space --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_open_file_count --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_search_query_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_search_fetch_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_indexing_index_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_merges_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_refresh_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_flush_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_get_exists_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_get_missing_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_get_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_indexing_delete_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_search_scroll_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_search_suggest_total_req_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_search_query_time_seconds_proc_rate --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_translog_operations --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_translog_size --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_breakers_tripped --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_breakers_estimated_size --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_docs --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_docs_deleted_total --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_docs_deleted --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_merges_docs_total --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_indices_merges_total_size_bytes_total --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_segment_count --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_segment_memory --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_network_send_bytes --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_node_network_receive_bytes --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_disk_usage_percent --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_node_disk_usage --service-name=elasticsearch::cluster-e2e --instance-name=node-e2e | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+
+  # endpoint cases
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql endpoint ls --service-name=elasticsearch::cluster-e2e
+    expected: expected/endpoint.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_docs_primary --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_deleted_docs_primary --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_store_size_bytes_primary --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_docs_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_store_size_bytes_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_segment_count_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_segment_memory_bytes_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_segment_count_primary --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_segment_memory_bytes_primary --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_merge_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_flush_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_refresh_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_warmer_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_indexing_delete_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_fetch_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_scroll_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_suggest_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_get_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_merge_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_flush_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_refresh_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_warmer_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_indexing_delete_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_fetch_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_query_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_scroll_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_suggest_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_indexing_index_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_get_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_merge_stopped_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_merge_throttle_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_indexing_throttle_time_seconds_total --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics multiple-linear --name=meter_elasticsearch_index_indices_shards_docs --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries | with(.[] ; .value=(.value | to_entries))' -
+    expected: expected/metrics-has-value-label.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_docs_primary_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_indexing_index_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_indices_docs_total_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_stats_search_query_total_req_rate --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_search_fetch_avg_time --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_search_query_avg_time --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_search_suggest_avg_time --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_elasticsearch_index_search_scroll_avg_time --service-name=elasticsearch::cluster-e2e --endpoint-name=e2e-index-0 | yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
\ No newline at end of file
diff --git a/test/e2e-v2/cases/elasticsearch/es-e2e-data-mock.sh b/test/e2e-v2/cases/elasticsearch/es-e2e-data-mock.sh
new file mode 100644
index 000000000000..98b7640cebeb
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/es-e2e-data-mock.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# 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.
+
+E2E_ES_HOST="es:9200"
+INDEX_NAME_PREFIX="e2e-index-"
+i=0
+while [ $i -lt 10 ]
+do
+    curl -X PUT "${E2E_ES_HOST}/${INDEX_NAME_PREFIX}${i}?pretty" -H 'Content-Type: application/json' -d'
+    {
+      "settings": {
+        "index": {
+          "number_of_shards": 3,
+          "number_of_replicas": 2
+        }
+      }
+    }
+    '
+
+    curl -X POST "${E2E_ES_HOST}/${INDEX_NAME_PREFIX}0/_doc/?pretty" -H 'Content-Type: application/json' -d'{"message": "GET /search HTTP/1.1 200 '${i}'","userid":"test"}'
+
+
+
+    if [ $i -eq 10 ]
+    then
+      break
+    fi
+    i=`expr $i + 1`
+done
+
+while true
+do
+      curl -X GET "${E2E_ES_HOST}/${INDEX_NAME_PREFIX}0/_search?size=20&pretty" -H 'Content-Type: application/json' -d'
+      {
+        "query": {
+          "term": {
+            "userid": "test"
+          }
+        }
+      }
+      '
+
+      curl -X POST "${E2E_ES_HOST}/${INDEX_NAME_PREFIX}0/_search?pretty" -H 'Content-Type: application/json' -d'
+      {
+        "suggest": {
+          "my-suggest-1" : {
+            "text" : "test",
+            "term" : {
+              "field" : "userid"
+            }
+          }
+        }
+      }
+      '
+
+      curl -X POST "${E2E_ES_HOST}/${INDEX_NAME_PREFIX}0/_search?scroll=1m&pretty" -H 'Content-Type: application/json' -d'
+      {
+        "size": 100,
+        "query": {
+          "match": {
+            "userid": "test"
+          }
+        }
+      }
+      '
+
+      sleep 2
+done
\ No newline at end of file
diff --git a/test/e2e-v2/cases/elasticsearch/expected/endpoint.yml b/test/e2e-v2/cases/elasticsearch/expected/endpoint.yml
new file mode 100644
index 000000000000..c31a5a134c88
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/expected/endpoint.yml
@@ -0,0 +1,19 @@
+# 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.
+
+{{- contains .}}
+- id: {{ b64enc "elasticsearch::cluster-e2e" }}.1_{{ b64enc "e2e-index-0" }}
+  name: e2e-index-0
+{{- end}}
diff --git a/test/e2e-v2/cases/elasticsearch/expected/instance.yml b/test/e2e-v2/cases/elasticsearch/expected/instance.yml
new file mode 100644
index 000000000000..d9d74e1beb6d
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/expected/instance.yml
@@ -0,0 +1,22 @@
+# 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.
+
+{{- contains . }}
+- id: {{ notEmpty .id }}
+  name: node-e2e
+  instanceuuid: {{ notEmpty .instanceuuid }}
+  attributes: []
+  language: UNKNOWN
+{{- end }}
diff --git a/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value-label.yml b/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value-label.yml
new file mode 100644
index 000000000000..0c957c3c779b
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value-label.yml
@@ -0,0 +1,25 @@
+# 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.
+
+{{- contains . }}
+- key: {{ notEmpty .key }}
+  value:
+  {{- contains .value }}
+  - key: {{ notEmpty .key }}
+    value:
+      value: {{ ge .value.value 0 }}
+      isemptyvalue: false
+  {{- end }}
+{{- end }}
diff --git a/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value.yml b/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value.yml
new file mode 100644
index 000000000000..441165535245
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/expected/metrics-has-value.yml
@@ -0,0 +1,21 @@
+# 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.
+
+{{- contains . }}
+- key: {{ notEmpty .key }}
+  value:
+    value: {{ ge .value.value 0 }}
+    isemptyvalue: false
+{{- end }}
diff --git a/test/e2e-v2/cases/elasticsearch/expected/service.yml b/test/e2e-v2/cases/elasticsearch/expected/service.yml
new file mode 100644
index 000000000000..696f0faf132e
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/expected/service.yml
@@ -0,0 +1,24 @@
+# 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.
+
+{{- contains . }}
+- id: {{ b64enc "elasticsearch::cluster-e2e" }}.1
+  name: elasticsearch::cluster-e2e
+  group: elasticsearch
+  shortname: cluster-e2e
+  layers:
+    - ELASTICSEARCH
+  normal: true
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/elasticsearch/otel-collector-config.yaml b/test/e2e-v2/cases/elasticsearch/otel-collector-config.yaml
new file mode 100644
index 000000000000..2ae7ac5b7ad1
--- /dev/null
+++ b/test/e2e-v2/cases/elasticsearch/otel-collector-config.yaml
@@ -0,0 +1,44 @@
+# 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.
+
+receivers:
+  prometheus:
+    config:
+     scrape_configs:
+       - job_name: 'elasticsearch-monitoring'
+         scrape_interval: 10s
+         static_configs:
+           - targets: ['es-exporter:9114']
+
+processors:
+  batch:
+
+exporters:
+  ####################################################################################
+  # If you want to use otlp exporter please ensure that your OAP version is >= 9.2.0 #
+  ####################################################################################
+  otlp:
+    endpoint: oap:11800
+    tls:
+      insecure: true
+service:
+  pipelines:
+    metrics:
+      receivers:
+      - prometheus
+      processors:
+      - batch
+      exporters:
+      - otlp
diff --git a/test/e2e-v2/script/prepare/setup-e2e-shell/install-yq.sh b/test/e2e-v2/script/prepare/setup-e2e-shell/install-yq.sh
index 658e092eecda..e0cca7031b47 100644
--- a/test/e2e-v2/script/prepare/setup-e2e-shell/install-yq.sh
+++ b/test/e2e-v2/script/prepare/setup-e2e-shell/install-yq.sh
@@ -24,7 +24,7 @@ BIN_DIR=$2
 
 if ! command -v yq &> /dev/null; then
   mkdir -p $BASE_DIR/yq && cd $BASE_DIR/yq
-  curl -kLo yq.tar.gz https://github.com/mikefarah/yq/archive/v4.14.1.tar.gz
+  curl -kLo yq.tar.gz https://github.com/mikefarah/yq/archive/v4.33.3.tar.gz
   tar -zxf yq.tar.gz --strip=1
   go install && go build -ldflags -s && cp yq $BIN_DIR/
 fi
\ No newline at end of file