You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/04/08 11:03:39 UTC

[skywalking] branch master updated: Support Redis Mornitoring (#10655)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2cbeb55359 Support Redis Mornitoring (#10655)
2cbeb55359 is described below

commit 2cbeb55359625204373cc907b2f550684d5f6f0f
Author: yswdqz <74...@users.noreply.github.com>
AuthorDate: Sat Apr 8 19:03:31 2023 +0800

    Support Redis Mornitoring (#10655)
---
 .github/workflows/skywalking.yaml                  |   2 +
 docs/en/changes/changes.md                         |   1 +
 docs/en/setup/backend/backend-apisix-monitoring.md |   2 +-
 .../en/setup/backend/backend-aws-eks-monitoring.md |   2 +-
 docs/en/setup/backend/backend-k8s-monitoring.md    |   2 +-
 docs/en/setup/backend/backend-mysql-monitoring.md  |   2 +-
 .../setup/backend/backend-postgresql-monitoring.md |   5 +-
 docs/en/setup/backend/backend-redis-monitoring.md  |  38 +++
 docs/en/setup/backend/backend-vm-monitoring.md     |   2 +-
 docs/en/setup/backend/backend-win-monitoring.md    |   2 +-
 docs/en/setup/backend/dashboards-so11y.md          |   2 +-
 docs/menu.yml                                      |   2 +
 .../skywalking/oap/server/core/analysis/Layer.java |   8 +-
 .../ui/template/UITemplateInitializer.java         |   1 +
 .../src/main/resources/application.yml             |   3 +-
 .../resources/otel-rules/redis/redis-instance.yaml |  69 +++++
 .../resources/otel-rules/redis/redis-service.yaml  |  66 +++++
 .../redis/redis-instance.json                      | 320 ++++++++++++++++++++
 .../ui-initialized-templates/redis/redis-root.json |  62 ++++
 .../redis/redis-service.json                       | 325 +++++++++++++++++++++
 .../cases/redis/expected/metrics-has-value.yml     |  25 ++
 test/e2e-v2/cases/redis/expected/service.yml       |  24 ++
 test/e2e-v2/cases/redis/redis-cases.yaml           |  65 +++++
 .../cases/redis/redis-exporter/docker-compose.yml  |  93 ++++++
 test/e2e-v2/cases/redis/redis-exporter/e2e.yaml    |  38 +++
 test/e2e-v2/cases/redis/redis-exporter/mock.txt    |   8 +
 .../redis-exporter/otel-collector-config.yaml      |  54 ++++
 test/e2e-v2/cases/redis/redis-exporter/redis.conf  |  80 +++++
 28 files changed, 1291 insertions(+), 12 deletions(-)

diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml
index 7fb5265350..0982075a9b 100644
--- a/.github/workflows/skywalking.yaml
+++ b/.github/workflows/skywalking.yaml
@@ -677,6 +677,8 @@ jobs:
             config: test/e2e-v2/cases/promql/e2e.yaml
           - name: AWS API Gateway
             config: test/e2e-v2/cases/aws/api-gateway/e2e.yaml
+          - name: Redis Prometheus
+            config: test/e2e-v2/cases/redis/redis-exporter/e2e.yaml
     steps:
       - uses: actions/checkout@v3
         with:
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index f37917cede..1cb10ccceb 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -30,6 +30,7 @@
 * Support Amazon API Gateway monitoring.
 * Bump up graphql-java to fix cve.
 * Bump up Kubernetes Java client.
+* Support Redis Monitoring.
 
 #### UI
 * Revert: cpm5d function. This feature is cancelled from backend.
diff --git a/docs/en/setup/backend/backend-apisix-monitoring.md b/docs/en/setup/backend/backend-apisix-monitoring.md
index 703ba21274..13e0b1ed13 100644
--- a/docs/en/setup/backend/backend-apisix-monitoring.md
+++ b/docs/en/setup/backend/backend-apisix-monitoring.md
@@ -5,7 +5,7 @@ SkyWalking leverages OpenTelemetry Collector to transfer the metrics to
 
 ### Data flow
 1. [APISIX Prometheus plugin](https://apisix.apache.org/docs/apisix/plugins/prometheus/) collects metrics data from APSIX.
-2. OpenTelemetry Collector fetches metrics from [APISIX Prometheus plugin](https://apisix.apache.org/docs/apisix/plugins/prometheus/) via Prometheus Receiver and pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. OpenTelemetry Collector fetches metrics from [APISIX Prometheus plugin](https://apisix.apache.org/docs/apisix/plugins/prometheus/) 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.
 
 ### Set up
diff --git a/docs/en/setup/backend/backend-aws-eks-monitoring.md b/docs/en/setup/backend/backend-aws-eks-monitoring.md
index 319b3bb453..ffde5274d3 100644
--- a/docs/en/setup/backend/backend-aws-eks-monitoring.md
+++ b/docs/en/setup/backend/backend-aws-eks-monitoring.md
@@ -3,7 +3,7 @@ SkyWalking leverages OpenTelemetry Collector with [AWS Container Insights Receiv
 [OpenTelemetry receiver](opentelemetry-receiver.md) and into the [Meter System](./../../concepts-and-designs/meter.md).
 
 ### Data flow
-1. OpenTelemetry Collector fetches metrics from EKS via [AWS Container Insights Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/awscontainerinsightreceiver/README.md) and pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+1. OpenTelemetry Collector fetches metrics from EKS via [AWS Container Insights Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/awscontainerinsightreceiver/README.md) and pushes metrics to SkyWalking OAP Server via OpenTelemetry gRPC exporter.
 2. The SkyWalking OAP Server parses the expression with [MAL](../../concepts-and-designs/mal.md) to filter/calculate/aggregate and store the results.
 
 ### Set up
diff --git a/docs/en/setup/backend/backend-k8s-monitoring.md b/docs/en/setup/backend/backend-k8s-monitoring.md
index 29bac54f92..e6f2be4797 100644
--- a/docs/en/setup/backend/backend-k8s-monitoring.md
+++ b/docs/en/setup/backend/backend-k8s-monitoring.md
@@ -4,7 +4,7 @@ SkyWalking leverages K8s kube-state-metrics (KSM) and cAdvisor for collecting me
 
 ## Data flow
 1. K8s kube-state-metrics and cAdvisor collect metrics data from K8s.
-2. OpenTelemetry Collector fetches metrics from kube-state-metrics and cAdvisor via Prometheus Receiver and pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. OpenTelemetry Collector fetches metrics from kube-state-metrics and cAdvisor via Prometheus Receiver and pushes metrics to SkyWalking OAP Server via OpenTelemetry gRPC exporter.
 3. The SkyWalking OAP Server access to K8s's `API Server` gets meta info and parses the expression with [MAL](../../concepts-and-designs/mal.md) to filter/calculate/aggregate and store the results.
 
 ## Setup
diff --git a/docs/en/setup/backend/backend-mysql-monitoring.md b/docs/en/setup/backend/backend-mysql-monitoring.md
index b112a19fd9..79e636515d 100644
--- a/docs/en/setup/backend/backend-mysql-monitoring.md
+++ b/docs/en/setup/backend/backend-mysql-monitoring.md
@@ -5,7 +5,7 @@ SkyWalking leverages prometheus/mysqld_exporter for collecting metrics data. It
 
 ### Data flow
 1. mysqld_exporter collect metrics data from MySQL/MariaDB.
-2. OpenTelemetry Collector fetches metrics from mysqld_exporter via Prometheus Receiver and pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. OpenTelemetry Collector fetches metrics from mysqld_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.
 
 ### Set up
diff --git a/docs/en/setup/backend/backend-postgresql-monitoring.md b/docs/en/setup/backend/backend-postgresql-monitoring.md
index 32e93cb947..91978b3ae2 100644
--- a/docs/en/setup/backend/backend-postgresql-monitoring.md
+++ b/docs/en/setup/backend/backend-postgresql-monitoring.md
@@ -5,7 +5,7 @@ SkyWalking leverages postgres-exporter for collecting metrics data from PostgreS
 
 ### Data flow
 1. postgres-exporter collect metrics data from PostgreSQL.
-2. OpenTelemetry Collector fetches metrics from postgres-exporter via Prometheus Receiver and pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. OpenTelemetry Collector fetches metrics from postgres-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.
 
 ### Set up
@@ -14,8 +14,7 @@ SkyWalking leverages postgres-exporter for collecting metrics data from PostgreS
 3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
 
 ### PostgreSQL Monitoring
-PostgreSQL monitoring provides monitoring of the status and resources of the PostgreSQL server.PostgreSQL server as a `Service` in OAP, and land on the `Layer: POSTGRESQL`.
-
+PostgreSQL cluster is cataloged as a `Layer: PostgreSQL` `Service` in OAP. Each PostgreSQL server is cataloged as an `Instance` in OAP.
 #### Supported Metrics
 | Monitoring Panel | Unit | Metric Name | Description | Data Source |
 |-----|------|-----|-----|-----|
diff --git a/docs/en/setup/backend/backend-redis-monitoring.md b/docs/en/setup/backend/backend-redis-monitoring.md
new file mode 100644
index 0000000000..18c7652bce
--- /dev/null
+++ b/docs/en/setup/backend/backend-redis-monitoring.md
@@ -0,0 +1,38 @@
+# Redis monitoring
+## Redis server performance from `redis-exporter`
+SkyWalking leverages redis-exporter for collecting metrics data from Redis. 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. redis-exporter collect metrics data from Redis.
+2. OpenTelemetry Collector fetches metrics from redis-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.
+
+### Set up
+1. Set up [redis-exporter](https://github.com/oliver006/redis_exporter#building-and-running-the-exporter).
+2. Set up [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/getting-started/#docker). For details on Redis Receiver in OpenTelemetry Collector, refer to [here](../../../../test/e2e-v2/cases/redis/redis-exporter/otel-collector-config.yaml).
+3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
+
+### Redis Monitoring
+Redis monitoring provides monitoring of the status and resources of the Redis server. Redis cluster is cataloged as a `Layer: REDIS` `Service` in OAP.
+Each Redis server is cataloged as an `Instance` in OAP.
+#### Supported Metrics
+| Monitoring Panel                  | Unit   | Metric Name                                                                                       | Description                                        | Data Source    |
+|-----------------------------------|--------|---------------------------------------------------------------------------------------------------|----------------------------------------------------|----------------|
+| Uptime                            | day    | meter_redis_uptime                                                                                | The uptime of Redis.                               | redis-exporter |
+| Connected Clients                 |        | meter_redis_connected_clients                                                                     | The number of connected clients.                   | redis-exporter |
+| Blocked Clients                   |        | meter_redis_blocked_clients                                                                       | The number of blocked clients.                     | redis-exporter |
+| Memory Max Bytes                  | MB     | meter_redis_memory_max_bytes                                                                      | The max bytes of memory.                           | redis-exporter |
+| Hits Rate                         | %      | meter_redis_hit_rate                                                                              | Hit rate of redis when used as a cache.            | redis-exporter |
+| Average Time Spend By Command     | second | meter_redis_average_time_spent_by_command                                                         | Average time to execute various types of commands. | redis-exporter |
+| Total Commands Trend              |        | meter_redis_total_commands_rate                                                                   | The Trend of total commands.                       | redis-exporter |
+| DB keys                           |        | meter_redis_evicted_keys_total  </br>   meter_redis_expired_keys_total  </br> meter_redis_db_keys | The number of Expired / Evicted / total keys.      | redis-exporter |
+| Net Input/Output Bytes            | KB     | meter_redis_net_input_bytes  </br>  meter_redis_net_output_bytes                                  | Total bytes of input / output of redis net.        | redis-exporter |
+| Memory Usage                      | %      | meter_redis_memory_usage                                                                          | Percentage of used memory.                         | redis-exporter |
+| Total Time Spend By Command Trend |        | meter_redis_commands_duration_seconds_total_rate                                                  | The trend of total time spend by command           | redis-exporter |
+
+### Customizations
+You can customize your own metrics/expression/dashboard panel.
+The metrics definition and expression rules are found in `/config/otel-rules/redis`.
+The Redis dashboard panel configurations are found in `/config/ui-initialized-templates/redis`.
+
diff --git a/docs/en/setup/backend/backend-vm-monitoring.md b/docs/en/setup/backend/backend-vm-monitoring.md
index 2e9c716537..e55705dd86 100644
--- a/docs/en/setup/backend/backend-vm-monitoring.md
+++ b/docs/en/setup/backend/backend-vm-monitoring.md
@@ -10,7 +10,7 @@ VM entity as a `Service` in OAP and on the `Layer: OS_LINUX`.
 ## Data flow
 **For OpenTelemetry receiver:**
 1. The Prometheus node-exporter collects metrics data from the VMs.
-2. The OpenTelemetry Collector fetches metrics from node-exporter via Prometheus Receiver and pushes metrics to the SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. The OpenTelemetry Collector fetches metrics from node-exporter via Prometheus Receiver and pushes metrics to the 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.
 
 **For Telegraf receiver:**
diff --git a/docs/en/setup/backend/backend-win-monitoring.md b/docs/en/setup/backend/backend-win-monitoring.md
index 6ecf4135a6..c42c00eaf1 100644
--- a/docs/en/setup/backend/backend-win-monitoring.md
+++ b/docs/en/setup/backend/backend-win-monitoring.md
@@ -6,7 +6,7 @@ Windows entity as a `Service` in OAP and on the `Layer: OS_WINDOWS`.
 ## Data flow
 **For OpenTelemetry receiver:**
 1. The Prometheus windows_exporter collects metrics data from the VMs.
-2. The OpenTelemetry Collector fetches metrics from windows_exporter via Prometheus Receiver and pushes metrics to the SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+2. The OpenTelemetry Collector fetches metrics from windows_exporter via Prometheus Receiver and pushes metrics to the 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
diff --git a/docs/en/setup/backend/dashboards-so11y.md b/docs/en/setup/backend/dashboards-so11y.md
index 91e477c58b..2c9cfe33d0 100644
--- a/docs/en/setup/backend/dashboards-so11y.md
+++ b/docs/en/setup/backend/dashboards-so11y.md
@@ -6,7 +6,7 @@ it also provides a dashboard to visualize the self-observability metrics.
 ## Data flow
 1. SkyWalking OAP collects metrics data internally and exposes a Prometheus http endpoint to retrieve the metrics.
 2. SkyWalking OAP itself (or OpenTelemetry Collector, prefered in Kubernetes scenarios) fetches metrics from the Prometheus endpoint in step (1).
-3. OAP (or OpenTelemetry Collector) pushes metrics to SkyWalking OAP Server via the OpenCensus gRPC Exporter or OpenTelemetry gRPC exporter.
+3. OAP (or OpenTelemetry Collector) pushes metrics to SkyWalking OAP Server via OpenTelemetry gRPC exporter.
 4. The SkyWalking OAP Server parses the expression with [MAL](../../concepts-and-designs/mal.md) to filter/calculate/aggregate and store the results.
 
 ## Set up
diff --git a/docs/menu.yml b/docs/menu.yml
index 403ff93960..b0c027cd07 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -223,6 +223,8 @@ catalog:
                 path: "/en/setup/backend/backend-postgresql-monitoring"
               - name: "AWS DynamoDB"
                 path: "/en/setup/backend/backend-aws-dynamodb-monitoring"
+              - name: "Redis"
+                path: "/en/setup/backend/backend-redis-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 3756b25a2c..6906be90f1 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
@@ -164,7 +164,13 @@ public enum Layer {
      * Amazon API Gateway is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP,
      * and WebSocket APIs at any scale.
      */
-    AWS_GATEWAY(26, true);
+    AWS_GATEWAY(26, true),
+
+    /*
+     * Redis is an open source (BSD licensed), in-memory data structure store,
+     * used as a database, cache, and message broker.
+     */
+    REDIS(27, 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 1b2da1deb7..96d03f7e64 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
@@ -65,6 +65,7 @@ public class UITemplateInitializer {
         Layer.AWS_S3.name(),
         Layer.AWS_DYNAMODB.name(),
         Layer.AWS_GATEWAY.name(),
+        Layer.REDIS.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 7eb560f08b..9aa6c2bcc6 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -332,7 +332,8 @@ 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/*"}
+    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/*"}
+
 
 receiver-zipkin:
   selector: ${SW_RECEIVER_ZIPKIN:-}
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-instance.yaml b/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-instance.yaml
new file mode 100644
index 0000000000..f2aa2e03f7
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-instance.yaml
@@ -0,0 +1,69 @@
+# 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 == 'redis-monitoring' }" # The OpenTelemetry job name
+expSuffix:  tag({tags -> tags.host_name = 'redis::' + tags.host_name}).service(['host_name'] , Layer.REDIS).instance(['host_name'], ['service_instance_id'], Layer.REDIS)
+metricPrefix: meter_redis
+metricsRules:
+  - name: instance_uptime
+    exp: redis_uptime_in_seconds
+
+  - name: instance_connected_clients
+    exp: redis_connected_clients
+  - name: instance_memory_max_bytes
+    exp: redis_memory_max_bytes
+  - name: instance_memory_usage
+    exp: redis_memory_used_bytes * 100 / redis_memory_max_bytes
+  - name: instance_total_commands_rate
+    exp: redis_commands_total.sum(['cmd','host_name','service_instance_id']).rate('PT1M')
+  - name: instance_hit_rate
+    exp: redis_keyspace_hits_total * 100 / (redis_keyspace_misses_total + redis_keyspace_hits_total)
+
+
+
+  - name: instance_net_input_bytes_total
+    exp: redis_net_input_bytes_total.rate('PT5M')
+  - name: instance_net_output_bytes_total
+    exp: redis_net_output_bytes_total.rate('PT5M')
+
+  - name: instance_db_keys
+    exp: redis_db_keys
+  - name: instance_expired_keys_total
+    exp: redis_expired_keys_total
+  - name: instance_evicted_keys_total
+    exp: redis_evicted_keys_total
+
+  - name: instance_redis_blocked_clients
+    exp: redis_blocked_clients
+
+  - name: instance_average_time_spent_by_command
+    exp: (redis_commands_duration_seconds_total.sum(['host_name','cmd','service_instance_id']) / redis_commands_total.sum(['host_name','cmd','service_instance_id'])).rate('PT1M')
+  - name: instance_commands_duration_seconds_total_rate
+    exp: redis_commands_duration_seconds_total.sum(['host_name','cmd','service_instance_id']).rate('PT1M')
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-service.yaml b/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-service.yaml
new file mode 100644
index 0000000000..0a9d4b9b52
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/redis/redis-service.yaml
@@ -0,0 +1,66 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# 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 == 'redis-monitoring' }" # The OpenTelemetry job name
+expSuffix:  tag({tags -> tags.host_name = 'redis::' + tags.host_name}).service(['host_name'] , Layer.REDIS)
+metricPrefix: meter_redis
+metricsRules:
+  - name: uptime
+    exp: redis_uptime_in_seconds.max(['host_name'])
+  - name: connected_clients
+    exp: redis_connected_clients.sum(['host_name'])
+  - name: blocked_clients
+    exp: redis_blocked_clients.sum(['host_name'])
+  - name: memory_usage
+    exp: redis_memory_used_bytes.sum(['host_name']) * 100 / redis_memory_max_bytes.sum(['host_name'])
+  - name: total_commands_rate
+    exp: redis_commands_total.sum(['cmd','host_name']).rate('PT1M')
+  - name: hit_rate
+    exp: redis_keyspace_hits_total * 100 / (redis_keyspace_misses_total + redis_keyspace_hits_total)
+
+  - name: net_input_bytes_total
+    exp: redis_net_input_bytes_total.sum(['host_name']).rate('PT5M')
+  - name: net_output_bytes_total
+    exp: redis_net_output_bytes_total.sum(['host_name']).rate('PT5M')
+
+  - name: db_keys
+    exp: redis_db_keys.sum(['host_name'])
+  - name: expired_keys_total
+    exp: redis_expired_keys_total.sum(['host_name'])
+  - name: evicted_keys_total
+    exp: redis_evicted_keys_total.sum(['host_name'])
+
+  - name: average_time_spent_by_command
+    exp: (redis_commands_duration_seconds_total.sum(['host_name','cmd']) / redis_commands_total.sum(['host_name','cmd'])).rate('PT1M')
+  - name: commands_duration_seconds_total_rate
+    exp: redis_commands_duration_seconds_total.sum(['host_name','cmd']).rate('PT1M')
+
+
+
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-instance.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-instance.json
new file mode 100644
index 0000000000..19c4ee3737
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-instance.json
@@ -0,0 +1,320 @@
+/**
+ * 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":"redis-instance",
+    "configuration":{
+      "children":[
+        {
+          "x":0,
+          "y":0,
+          "w":6,
+          "h":6,
+          "i":"0",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_redis_instance_uptime"
+          ],
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Uptime (day)"
+          },
+          "metricConfig":[
+            {
+              "calculation":"secondToDay"
+            }
+          ]
+        },
+        {
+          "x":6,
+          "y":0,
+          "w":6,
+          "h":6,
+          "i":"1",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_redis_instance_connected_clients"
+          ],
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Connected Clients"
+          }
+        },
+        {
+          "x":0,
+          "y":6,
+          "w":6,
+          "h":12,
+          "i":"2",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_memory_usage"
+          ],
+          "graph":{
+            "type":"Area",
+            "opacity":0.4,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Memory Usage (%)"
+          }
+        },
+        {
+          "x":12,
+          "y":6,
+          "w":6,
+          "h":12,
+          "i":"3",
+          "type":"Widget",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_total_commands_rate"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Total Commands Trend"
+          }
+        },
+        {
+          "x":0,
+          "y":18,
+          "w":6,
+          "h":12,
+          "i":"4",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_hit_rate"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Hits Rate (%)"
+          }
+        },
+        {
+          "x":18,
+          "y":0,
+          "w":6,
+          "h":6,
+          "i":"5",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_redis_instance_memory_max_bytes"
+          ],
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToMB"
+            }
+          ],
+          "widget":{
+            "title":"Memory Max Bytes (MB)"
+          }
+        },
+        {
+          "x":6,
+          "y":18,
+          "w":6,
+          "h":12,
+          "i":"6",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_net_input_bytes_total",
+            "meter_redis_instance_net_output_bytes_total"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "metricConfig":[
+            {
+              "calculation":"byteToKB"
+            },
+            {
+              "calculation":"byteToKB"
+            }
+          ],
+          "widget":{
+            "title":"Net Input / Output Bytes (KB)"
+          }
+        },
+        {
+          "x":18,
+          "y":6,
+          "w":6,
+          "h":12,
+          "i":"7",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValues",
+            "readMetricsValues",
+            "readMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_db_keys",
+            "meter_redis_instance_evicted_keys_total",
+            "meter_redis_instance_expired_keys_total"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"DB Keys"
+          }
+        },
+        {
+          "x":12,
+          "y":0,
+          "w":6,
+          "h":6,
+          "i":"8",
+          "type":"Widget",
+          "metricTypes":[
+            "readMetricsValue"
+          ],
+          "metrics":[
+            "meter_redis_instance_blocked_clients"
+          ],
+          "graph":{
+            "type":"Card",
+            "fontSize":14,
+            "textAlign":"center",
+            "showUnit":true
+          },
+          "widget":{
+            "title":"Blocked Clients"
+          }
+        },
+        {
+          "x":12,
+          "y":18,
+          "w":6,
+          "h":12,
+          "i":"9",
+          "type":"Widget",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_commands_duration_seconds_total_rate"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Total Time Spent by Command Trend (sec)"
+          }
+        },
+        {
+          "x":6,
+          "y":6,
+          "w":6,
+          "h":12,
+          "i":"10",
+          "type":"Widget",
+          "metricTypes":[
+            "readLabeledMetricsValues"
+          ],
+          "metrics":[
+            "meter_redis_instance_average_time_spent_by_command"
+          ],
+          "graph":{
+            "type":"Line",
+            "step":false,
+            "smooth":false,
+            "showSymbol":false,
+            "showXAxis":true,
+            "showYAxis":true
+          },
+          "widget":{
+            "title":"Average Time Spent by Command / sec"
+          }
+        }
+      ],
+      "layer":"REDIS",
+      "entity":"ServiceInstance",
+      "name":"Redis-Instance",
+      "id":"redis-instance",
+      "isRoot":false
+    }
+  }
+]
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-root.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-root.json
new file mode 100644
index 0000000000..792bf237d9
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-root.json
@@ -0,0 +1,62 @@
+/**
+ * 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":"redis-root",
+    "configuration":{
+      "children":[
+        {
+          "x":0,
+          "y":2,
+          "w":24,
+          "h":31,
+          "i":"0",
+          "type":"Widget",
+          "graph":{
+            "type":"ServiceList",
+            "dashboardName":"Redis-Service",
+            "fontSize":12,
+            "showXAxis":false,
+            "showYAxis":false,
+            "showGroup":true
+          }
+        },
+        {
+          "x":0,
+          "y":0,
+          "w":24,
+          "h":2,
+          "i":"1",
+          "type":"Text",
+          "graph":{
+            "fontColor":"blue",
+            "backgroundColor":"white",
+            "content":"Provide Redis monitoring through OpenTelemetry's Prometheus Receiver",
+            "fontSize":14,
+            "textAlign":"left",
+            "url":"https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-redis-monitoring/"
+          }
+        }
+      ],
+      "name":"Redis-Root",
+      "layer":"REDIS",
+      "entity":"All",
+      "isRoot":true
+    }
+  }
+]
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-service.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-service.json
new file mode 100644
index 0000000000..1fb29209c0
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/redis/redis-service.json
@@ -0,0 +1,325 @@
+/**
+ * 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":"redis-service",
+    "configuration":{
+      "children":[
+        {
+          "x":0,
+          "y":0,
+          "w":24,
+          "h":36,
+          "i":"0",
+          "type":"Tab",
+          "children":[
+            {
+              "name":"Inspections",
+              "children":[
+                {
+                  "x":0,
+                  "y":0,
+                  "w":6,
+                  "h":6,
+                  "i":"0",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_redis_uptime"
+                  ],
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Uptime (day)"
+                  },
+                  "metricConfig":[
+                    {
+                      "calculation":"secondToDay"
+                    }
+                  ]
+                },
+                {
+                  "x":6,
+                  "y":0,
+                  "w":6,
+                  "h":6,
+                  "i":"1",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_redis_connected_clients"
+                  ],
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Connected Clients"
+                  }
+                },
+                {
+                  "x":12,
+                  "y":0,
+                  "w":6,
+                  "h":6,
+                  "i":"2",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_redis_memory_usage"
+                  ],
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Memory Usage (%)"
+                  }
+                },
+                {
+                  "x":12,
+                  "y":6,
+                  "w":6,
+                  "h":12,
+                  "i":"3",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readLabeledMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_total_commands_rate"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "widget":{
+                    "title":"Total Commands Trend"
+                  }
+                },
+                {
+                  "x":0,
+                  "y":6,
+                  "w":6,
+                  "h":12,
+                  "i":"4",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_hit_rate"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "widget":{
+                    "title":"Hits Rate (%)"
+                  }
+                },
+                {
+                  "x":0,
+                  "y":18,
+                  "w":6,
+                  "h":12,
+                  "i":"6",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValues",
+                    "readMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_net_input_bytes_total",
+                    "meter_redis_net_output_bytes_total"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "metricConfig":[
+                    {
+                      "calculation":"byteToKB"
+                    },
+                    {
+                      "calculation":"byteToKB"
+                    }
+                  ],
+                  "widget":{
+                    "title":"Net Input / Output Bytes (KB)"
+                  }
+                },
+                {
+                  "x":18,
+                  "y":6,
+                  "w":6,
+                  "h":12,
+                  "i":"7",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValues",
+                    "readMetricsValues",
+                    "readMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_db_keys",
+                    "meter_redis_evicted_keys_total",
+                    "meter_redis_expired_keys_total"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "widget":{
+                    "title":"DB Keys"
+                  }
+                },
+                {
+                  "x":18,
+                  "y":0,
+                  "w":6,
+                  "h":6,
+                  "i":"8",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readMetricsValue"
+                  ],
+                  "metrics":[
+                    "meter_redis_blocked_clients"
+                  ],
+                  "graph":{
+                    "type":"Card",
+                    "fontSize":14,
+                    "textAlign":"center",
+                    "showUnit":true
+                  },
+                  "widget":{
+                    "title":"Blocked Clients"
+                  }
+                },
+                {
+                  "x":6,
+                  "y":18,
+                  "w":6,
+                  "h":12,
+                  "i":"9",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readLabeledMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_commands_duration_seconds_total_rate"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "widget":{
+                    "title":"Total Time Spent by Command Trend (sec)"
+                  }
+                },
+                {
+                  "x":6,
+                  "y":6,
+                  "w":6,
+                  "h":12,
+                  "i":"10",
+                  "type":"Widget",
+                  "metricTypes":[
+                    "readLabeledMetricsValues"
+                  ],
+                  "metrics":[
+                    "meter_redis_average_time_spent_by_command"
+                  ],
+                  "graph":{
+                    "type":"Line",
+                    "step":false,
+                    "smooth":false,
+                    "showSymbol":false,
+                    "showXAxis":true,
+                    "showYAxis":true
+                  },
+                  "widget":{
+                    "title":"Average Time Spent by Command / sec"
+                  }
+                }
+              ]
+            },
+            {
+              "name":"Instances",
+              "children":[
+                {
+                  "x":0,
+                  "y":0,
+                  "w":24,
+                  "h":30,
+                  "i":"0",
+                  "type":"Widget",
+                  "graph":{
+                    "type":"InstanceList",
+                    "dashboardName":"Redis-Instance",
+                    "fontSize":12
+                  }
+                }
+              ]
+            }
+          ]
+        }
+      ],
+      "layer":"REDIS",
+      "entity":"Service",
+      "name":"Redis-Service",
+      "id":"redis-service",
+      "isRoot":false
+    }
+  }
+]
\ No newline at end of file
diff --git a/test/e2e-v2/cases/redis/expected/metrics-has-value.yml b/test/e2e-v2/cases/redis/expected/metrics-has-value.yml
new file mode 100644
index 0000000000..baeae56d1c
--- /dev/null
+++ b/test/e2e-v2/cases/redis/expected/metrics-has-value.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:
+    value: 0
+    isemptyvalue: true
+- key: {{ notEmpty .key }}
+  value:
+    value: {{ ge .value.value 1 }}
+    isemptyvalue: false
+  {{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/redis/expected/service.yml b/test/e2e-v2/cases/redis/expected/service.yml
new file mode 100644
index 0000000000..36174561c3
--- /dev/null
+++ b/test/e2e-v2/cases/redis/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 "redis::root[root]" }}.1
+  name: redis::root[root]
+  shortname: root[root]
+  normal: true
+  group: "redis"
+  layers:
+    - REDIS
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e-v2/cases/redis/redis-cases.yaml b/test/e2e-v2/cases/redis/redis-cases.yaml
new file mode 100644
index 0000000000..7aad16d46f
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-cases.yaml
@@ -0,0 +1,65 @@
+# 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 list
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql service ls
+    expected:  expected/service.yml
+  # service metrics
+  - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_redis_uptime --service-name=redis::root[root] |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_redis_connected_clients --service-name=redis::root[root] |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_redis_memory_usage --service-name=redis::root[root] |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_redis_hit_rate --service-name=redis::root[root] |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_redis_net_input_bytes_total --service-name=redis::root[root] |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_redis_net_output_bytes_total --service-name=redis::root[root] |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_redis_db_keys --service-name=redis::root[root] |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_redis_expired_keys_total --service-name=redis::root[root] |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_redis_instance_uptime --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_connected_clients --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_memory_usage --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_memory_max_bytes --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_hit_rate --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_net_input_bytes_total --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_net_output_bytes_total --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_db_keys --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |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_redis_instance_expired_keys_total --service-name=redis::root[root] --instance-name=redis_exporter_1:9121 |yq e 'to_entries' -
+    expected: expected/metrics-has-value.yml
+
diff --git a/test/e2e-v2/cases/redis/redis-exporter/docker-compose.yml b/test/e2e-v2/cases/redis/redis-exporter/docker-compose.yml
new file mode 100644
index 0000000000..6a75808385
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-exporter/docker-compose.yml
@@ -0,0 +1,93 @@
+# 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
+    networks:
+      - e2e
+  redis_1: &redis
+    image: redis:6.0
+    networks:
+      - e2e
+    volumes:
+      - ./redis.conf:/etc/redis/redis.conf
+    ports:
+      - 6379
+    command:
+      redis-server /etc/redis/redis.conf
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/6379"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+  redis_2:
+    <<: *redis
+  redis_3:
+    <<: *redis
+
+  redis_mock:
+    <<: *redis
+    volumes:
+      - ./redis.conf:/etc/redis/redis.conf
+      - ./mock.txt:/etc/redis/mock.txt
+    depends_on:
+      - otel-collector
+      - redis_1
+      - redis_exporter_1
+    entrypoint: bash
+    command:
+      - -c
+      - "cat /etc/redis/mock.txt | redis-cli -h redis_1 -p 6379 &&  redis-server /etc/redis/redis.conf "
+
+  redis_exporter_1: &redis_exporter
+    image: oliver006/redis_exporter:v1.48.0-alpine
+    networks:
+      - e2e
+    ports:
+      - 9121
+    environment:
+      - REDIS_ADDR=redis_1:6379
+  redis_exporter_2:
+    <<: *redis_exporter
+    ports:
+      - 9121
+    environment:
+      - REDIS_ADDR=redis_2:6379
+  redis_exporter_3:
+    <<: *redis_exporter
+    environment:
+      - REDIS_ADDR=redis_3:6379
+  otel-collector:
+    image: otel/opentelemetry-collector:0.50.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
+
+networks:
+  e2e:
diff --git a/test/e2e-v2/cases/redis/redis-exporter/e2e.yaml b/test/e2e-v2/cases/redis/redis-exporter/e2e.yaml
new file mode 100644
index 0000000000..16ec8ad4f5
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-exporter/e2e.yaml
@@ -0,0 +1,38 @@
+# 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:
+        - ../redis-cases.yaml
+ 
\ No newline at end of file
diff --git a/test/e2e-v2/cases/redis/redis-exporter/mock.txt b/test/e2e-v2/cases/redis/redis-exporter/mock.txt
new file mode 100644
index 0000000000..81a6bba064
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-exporter/mock.txt
@@ -0,0 +1,8 @@
+set a b ex 5
+set c d
+get a
+set e f
+debug sleep 10
+get a
+get b
+get c
diff --git a/test/e2e-v2/cases/redis/redis-exporter/otel-collector-config.yaml b/test/e2e-v2/cases/redis/redis-exporter/otel-collector-config.yaml
new file mode 100644
index 0000000000..5f1f4a04ac
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-exporter/otel-collector-config.yaml
@@ -0,0 +1,54 @@
+# 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: 'redis-monitoring'
+         scrape_interval: 5s
+         static_configs:
+           - targets: ['redis_exporter_1:9121', 'redis_exporter_2:9121', 'redis_exporter_3:9121']
+             labels:
+               host_name: root[root]
+processors:
+  batch:
+
+exporters:
+  ####################################################################################
+  # If you want to use otlp exporter please ensure that your OAP version is >= 9.2.0 #
+  # or you can use oc exporter, The config format should be:                         #
+  # opencensus:                                                                      #
+  #   endpoint: "oap:11800"                                                          #
+  #   tls:                                                                           #
+  #      insecure: true                                                              #
+  ####################################################################################
+  otlp:
+    endpoint: oap:11800
+    tls:
+      insecure: true
+service:
+  pipelines:
+    metrics:
+      receivers:
+      - prometheus
+      processors:
+      - batch
+      exporters:
+      #########################################
+      # oc exporter config format:            #
+      # - opencensus                          #
+      #########################################
+      - otlp
diff --git a/test/e2e-v2/cases/redis/redis-exporter/redis.conf b/test/e2e-v2/cases/redis/redis-exporter/redis.conf
new file mode 100644
index 0000000000..aba474a8da
--- /dev/null
+++ b/test/e2e-v2/cases/redis/redis-exporter/redis.conf
@@ -0,0 +1,80 @@
+# 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.
+bind 0.0.0.0
+protected-mode yes
+port 6379
+tcp-backlog 511
+daemonize no
+supervised no
+pidfile /var/run/redis_6379.pid
+loglevel notice
+logfile ""
+databases 16
+always-show-logo yes
+save 900 1
+save 300 10
+save 60 10000
+maxmemory 1G
+stop-writes-on-bgsave-error yes
+rdbcompression yes
+rdbchecksum yes
+dbfilename dump.rdb
+replica-serve-stale-data yes
+repl-diskless-sync no
+repl-diskless-sync-delay 5
+repl-diskless-load disabled
+repl-disable-tcp-nodelay no
+replica-priority 100
+acllog-max-len 128
+lazyfree-lazy-eviction no
+lazyfree-lazy-expire no
+lazyfree-lazy-server-del no
+replica-lazy-flush no
+lazyfree-lazy-user-del no
+oom-score-adj no
+oom-score-adj-values 0 200 800
+appendonly no
+appendfilename "appendonly.aof"
+appendfsync everysec
+no-appendfsync-on-rewrite no
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+aof-load-truncated yes
+aof-use-rdb-preamble yes
+lua-time-limit 5000
+slowlog-log-slower-than 10000
+slowlog-max-len 128
+latency-monitor-threshold 0
+notify-keyspace-events ""
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+list-max-ziplist-size -2
+list-compress-depth 0
+set-max-intset-entries 512
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+hll-sparse-max-bytes 3000
+stream-node-max-bytes 4096
+stream-node-max-entries 100
+activerehashing yes
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit replica 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+hz 10
+dynamic-hz yes
+aof-rewrite-incremental-fsync yes
+rdb-save-incremental-fsync yes
+jemalloc-bg-thread yes
+