Repository: apache/skywalking (language: python)

Issue:
Windows 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

Apache Skywalking does not support windows monitoring. But it will be helpful if this feature is available. What all changes can contribute towards this feature?

### Use case

_No response_

### Related issues

_No response_

### Are you willing to submit a PR?

- [ ] 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:
@wu-sheng I think we need to implement the collection of windows logs and metric data. I think I can realize this function. Can you assign this issue to me?
/assign
> @wu-sheng I think we need to implement the collection of windows logs and metric data. I think I can realize this function. Can you assign this issue to me?

Metrics are required, logs are nice to have. 
> /assign

Just assigned it to you, good luck.
> > /assign
> 
> Just assigned it to you, good luck.

Thanks for trust !
> > > /assign
> 
> > 
> 
> > Just assigned it to you, good luck.
> 
> 
> 
> Thanks for trust !

I had noticed several fixed you made on BanyanDB as starts. It is good to see you are involving more like this.
@mikechengwei One suggestion, once you have done the research, and know how to start, and which components you are going to use(such as which windows agent, which protocol(otlp?)), you could share here, in case of somethings unexpected in the last minute, to waste too much time.
> @mikechengwei One suggestion, once you have done the research, and know how to start, and which components you are going to use(such as which windows agent, which protocol(otlp?)), you could share here, in case of somethings unexpected in the last minute, to waste too much time.

I will make a design and invite you to review it together.
If it is successful, please let me know. Because I am in need of this feature.
@mikechengwei Some discussions from @Donadominic are happening on slack, you are better to join and keep in the loop.
> @mikechengwei Some discussions from @Donadominic are happening on slack, you are better to join and keep in the loop.

ok.
@wu-sheng I have send my slack mail to [dev@skywalking.apache.org](mailto:dev@skywalking.apache.org).
The invitation has been sent to your mail box.
@mikechengwei Any update about this?
Refer to Slack discuisson and Linux Monitoring ,i wrote the design document Windows Monitoring.

We can leverages Prometheus [windows_exporter](https://github.com/prometheus-community/windows_exporter) to collect metrics data from the windows machine and leverages OpenTelemetry Collector to transfer the metrics to OpenTelemetry receiver and into the Meter System. VM entity as a Service in OAP and on the Layer: `OS_WINDOWS`.

We can also use InfluxDB  Telegraf to collect windows metric,and use [Telegraf receiver](https://skywalking.apache.org/docs/main/next/en/setup/backend/telegraf-receiver/) plugin to store to the [Meter System](https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/meter/)

## detailed step
For OpenTelemetry receiver:

1. Setup Prometheus windows-exporter.
2. Setup OpenTelemetry Collector . Provide otel configuration example  `otel-collector-config.yaml`.
3. Config SkyWalking OpenTelemetry receiver.

For Telegraf receiver:

1. Setup telegraf collect metrics to influxDB, telegraf support [Windows Services Input Plugin](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/win_services/README.md).
2. Setup InfluxDB Telegraf’s telegraf.conf file specific rules according to Telegraf receiver document.
3. Config SkyWalking Telegraf receiver.

We need provdie supported Metrics detail on promethues windows exporter and telegraf windows input plugin.

## Develop Plan
1. Run and test the windows exporter collection process
	- provide windows metric otel configuration file example   `otel-collector-config.yaml`. 
	- provide otel metric handle rule file.
2. Run and test the telegraf collection process
	- provide telegraf windows input configuration example file `telegraf.conf `
	- provide telgraf receiver metric handle rule file 
> Refer to Slack discuisson and Linux Monitoring ,i wrote the design document Windows Monitoring.
> 
> We can leverages Prometheus [windows_exporter](https://github.com/prometheus-community/windows_exporter) to collect metrics data from the windows machine and leverages OpenTelemetry Collector to transfer the metrics to OpenTelemetry receiver and into the Meter System. VM entity as a Service in OAP and on the Layer: `OS_WINDOWS`.
> 
> We can also use InfluxDB Telegraf to collect windows metric,and use [Telegraf receiver](https://skywalking.apache.org/docs/main/next/en/setup/backend/telegraf-receiver/) plugin to store to the [Meter System](https://skywalking.apache.org/docs/main/next/en/concepts-and-designs/meter/)
> 
> ## detailed step
> For OpenTelemetry receiver:
> 
> 1. Setup Prometheus windows-exporter.
> 2. Setup OpenTelemetry Collector . Provide otel configuration example  `otel-collector-config.yaml`.
> 3. Config SkyWalking OpenTelemetry receiver.
> 
> For Telegraf receiver:
> 
> 1. Setup telegraf collect metrics to influxDB, telegraf support [Windows Services Input Plugin](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/win_services/README.md).
> 2. Setup InfluxDB Telegraf’s telegraf.conf file specific rules according to Telegraf receiver document.
> 3. Config SkyWalking Telegraf receiver.
> 
> We need provdie supported Metrics detail on promethues windows exporter and telegraf windows input plugin.
> 
> ## Develop Plan
> 1. Run and test the windows exporter collection process
>    
>    * provide windows metric otel configuration file example   `otel-collector-config.yaml`.
>    * provide otel metric handle rule file.
> 2. Run and test the telegraf collection process
>    
>    * provide telegraf windows input configuration example file `telegraf.conf `
>    * provide telgraf receiver metric handle rule file

@wu-sheng WDYT?
From official perspective, Prometheus to OTEL collector to OAP should be good enough.
> From official perspective, Prometheus to OTEL collector to OAP should be good enough.

ok,i will finish this feature firstly.
Oh, there is one step, you need to update UI to add a new menu item for Windows side by side with Linux.

Fix patch:
diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml
index a080ae676f2d..9c025568510e 100644
--- a/.github/workflows/skywalking.yaml
+++ b/.github/workflows/skywalking.yaml
@@ -663,6 +663,8 @@ jobs:
             config: test/e2e-v2/cases/virtual-mq/e2e.yaml
           - name: AWS Cloud EKS
             config: test/e2e-v2/cases/aws/eks/e2e.yaml
+          - name: Windows
+            config: test/e2e-v2/cases/win/e2e.yaml
     steps:
       - uses: actions/checkout@v3
         with:
diff --git a/docs/en/setup/backend/backend-win-monitoring.md b/docs/en/setup/backend/backend-win-monitoring.md
new file mode 100644
index 000000000000..6ecf4135a652
--- /dev/null
+++ b/docs/en/setup/backend/backend-win-monitoring.md
@@ -0,0 +1,34 @@
+# Windows Monitoring
+SkyWalking leverages Prometheus windows_exporter to collect metrics data from the Windows and leverages OpenTelemetry Collector to transfer the metrics to
+[OpenTelemetry receiver](opentelemetry-receiver.md) and into the [Meter System](./../../concepts-and-designs/meter.md).
+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.
+3. The SkyWalking OAP Server parses the expression with [MAL](../../concepts-and-designs/mal.md) to filter/calculate/aggregate and store the results.
+
+## Setup
+**For OpenTelemetry receiver:**
+1. Setup [Prometheus windows_exporter](https://github.com/prometheus-community/windows_exporter).
+2. Setup [OpenTelemetry Collector ](https://opentelemetry.io/docs/collector/). This is an example for OpenTelemetry Collector configuration [otel-collector-config.yaml](../../../../test/e2e-v2/cases/win/prometheus-windows_exporter/otel-collector-config.yaml).
+3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
+
+## Supported Metrics
+
+| Monitoring Panel             | Unit | Metric Name                                                                                                             | Description                                                                                    | Data Source                                         |
+|------------------------------|------|-------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|-----------------------------------------------------|
+| CPU Usage                    | %    | meter_win_cpu_total_percentage                                                                                           | The total percentage usage of the CPU core. If there are 2 cores, the maximum usage is 200%.   | Prometheus windows_exporter |
+| Memory RAM Usage             | MB   | meter_win_memory_used                                                                                                  | The total RAM usage                                                                            | Prometheus windows_exporter |
+| Memory Swap Usage            | %    | meter_win_memory_swap_percentage                                                                                    | The percentage usage of swap memory                                                            | Prometheus windows_exporter |
+| CPU Average Used             | %    | meter_win_cpu_average_used                                                                                              | The percentage usage of the CPU core in each mode                                              | Prometheus windows_exporter |
+| Memory RAM                   | MB   | meter_win_memory_total<br />meter_win_memory_available<br />meter_win_memory_used                                          | The RAM statistics, including Total / Available / Used                                         | Prometheus windows_exporter |
+| Memory Swap                  | MB   | meter_win_memory_swap_free<br />meter_win_memory_swap_total                                                               | Swap memory statistics, including Free / Total                                                 | Prometheus windows_exporter |                                                                                         | The percentage usage of the file system at each mount point                                    | Prometheus windows_exporter |
+| Disk R/W                     | KB/s | meter_win_disk_read,meter_win_disk_written                                                                                | The disk read and written                                                                      | Prometheus windows_exporter |
+| Network Bandwidth Usage      | KB/s | meter_win_network_receive<br />meter_win_network_transmit                                                                 | The network receive and transmit                                                               | Prometheus windows_exporter |                                                                                     | The number of file descriptors allocated                                                       | Prometheus windows_exporter |
+
+## Customizing
+You can customize your own metrics/expression/dashboard panel.
+The metrics definition and expression rules are found in `/config/otel-rules/windows.yaml`.
+The dashboard panel confirmations are found in `/config/ui-initialized-templates/os_windows`.
diff --git a/docs/menu.yml b/docs/menu.yml
index 87b79e37fa61..1a74b095b762 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -183,6 +183,8 @@ catalog:
             catalog:
               - name: "Linux Monitoring"
                 path: "/en/setup/backend/backend-vm-monitoring"
+              - name: "Windows Monitoring"
+                path: "/en/setup/backend/backend-win-monitoring"
           - name: "AWS Cloud Monitoring"
             catalog:
               - name: "EKS Monitoring"
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 daaa9f04e363..dd4da5ad0592 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
@@ -141,7 +141,13 @@ public enum Layer {
     /**
      * EKS (Amazon Elastic Kubernetes Service) is k8s service provided by AWS Cloud
      */
-    AWS_EKS(22, true);
+    AWS_EKS(22, true),
+
+    /**
+     * Windows Machine
+     */
+    OS_WINDOWS(23, 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 1183a848a5d1..49539ff305a3 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
@@ -61,6 +61,7 @@ public class UITemplateInitializer {
         Layer.APISIX.name(),
         Layer.VIRTUAL_MQ.name(),
         Layer.AWS_EKS.name(),
+        Layer.OS_WINDOWS.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 b4520060327e..a08843be1d9c 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -356,7 +356,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/*"}
+    enabledOtelRules: ${SW_OTEL_RECEIVER_ENABLED_OTEL_RULES:"apisix,k8s/*,istio-controlplane,vm,mysql/*,postgresql/*,oap,aws-eks/*,windows"}
 
 receiver-zipkin:
   selector: ${SW_RECEIVER_ZIPKIN:-}
diff --git a/oap-server/server-starter/src/main/resources/otel-rules/windows.yaml b/oap-server/server-starter/src/main/resources/otel-rules/windows.yaml
new file mode 100644
index 000000000000..ee667bdce3e0
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/otel-rules/windows.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 == 'windows-monitoring' }" # The OpenTelemetry job name
+expSuffix: service(['node_identifier_host_name'] , Layer.OS_WINDOWS)
+metricPrefix: meter_win
+metricsRules:
+  #cpu windows don't expose cpu load metrics
+  - name: cpu_total_percentage
+    exp: (windows_cpu_time_total * 100).tagNotEqual('mode' , 'idle').sum(['node_identifier_host_name']).rate('PT1M')
+  - name: cpu_average_used
+    exp: (windows_cpu_time_total * 100).sum(['node_identifier_host_name' , 'mode']).rate('PT1M')
+
+  #memory
+  - name: memory_total
+    exp: windows_cs_physical_memory_bytes
+  - name: memory_available
+    exp: windows_os_physical_memory_free_bytes
+  - name: memory_used
+    exp: windows_cs_physical_memory_bytes - windows_os_physical_memory_free_bytes
+  - name: memory_swap_free
+    exp: windows_os_virtual_memory_free_bytes
+  - name: memory_swap_total
+    exp: windows_os_virtual_memory_bytes
+  - name: memory_swap_percentage
+    exp: 100 - ((windows_os_virtual_memory_free_bytes * 100) / windows_os_virtual_memory_bytes)
+
+  #disk
+  - name: disk_read
+    exp: windows_logical_disk_read_bytes_total.sum(['node_identifier_host_name']).rate('PT1M')
+  - name: disk_written
+    exp: windows_logical_disk_write_bytes_total.sum(['node_identifier_host_name']).rate('PT1M')
+
+  #network
+  - name: network_receive
+    exp: windows_net_bytes_received_total.sum(['node_identifier_host_name']).irate()
+  - name: network_transmit
+    exp: windows_net_bytes_sent_total.sum(['node_identifier_host_name']).irate()
+  
+  
+  
+  
+
+
+
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-root.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-root.json
new file mode 100644
index 000000000000..a6625bc7f763
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-root.json
@@ -0,0 +1,87 @@
+/**
+ * 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": "Windows-Root",
+    "configuration": {
+      "children": [
+        {
+          "x": 0,
+          "y": 2,
+          "w": 24,
+          "h": 51,
+          "i": "0",
+          "type": "Widget",
+          "widget": {
+            "title": ""
+          },
+          "graph": {
+            "type": "ServiceList",
+            "dashboardName": "Windows-Service",
+            "fontSize": 12,
+            "showXAxis": false,
+            "showYAxis": false,
+            "showGroup": false
+          },
+          "metrics": [
+            "meter_win_cpu_total_percentage"
+          ],
+          "metricTypes": [
+            "readMetricsValues"
+          ],
+          "moved": false,
+          "metricConfig": [
+            {
+              "label": "CPU Usage",
+              "unit": "%",
+              "calculation": "average"
+            }
+          ]
+        },
+        {
+          "x": 0,
+          "y": 0,
+          "w": 24,
+          "h": 2,
+          "i": "100",
+          "type": "Text",
+          "metricTypes": [
+            ""
+          ],
+          "metrics": [
+            ""
+          ],
+          "graph": {
+            "fontColor": "blue",
+            "backgroundColor": "white",
+            "content": "Provide Windows OS monitoring.",
+            "fontSize": 14,
+            "textAlign": "left",
+            "url": "https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-win-monitoring/"
+          },
+          "moved": false
+        }
+      ],
+      "id": "Windows-Root",
+      "layer": "OS_WINDOWS",
+      "entity": "All",
+      "name": "Windows-Root",
+      "isRoot": true
+    }
+  }
+]
diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-service.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-service.json
new file mode 100644
index 000000000000..58154755a4a8
--- /dev/null
+++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/os_windows/windows-service.json
@@ -0,0 +1,202 @@
+/**
+ * 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": "Windows-Service",
+  "configuration": {
+    "children": [{
+      "x": 8,
+      "y": 19,
+      "w": 8,
+      "h": 13,
+      "i": "2",
+      "type": "Widget",
+      "widget": {
+        "title": "Network Bandwidth Usage (KB/s)"
+      },
+      "graph": {
+        "type": "Area",
+        "opacity": 0.4,
+        "showXAxis": true,
+        "showYAxis": true
+      },
+      "metrics": ["meter_win_network_receive", "meter_win_network_transmit"],
+      "metricTypes": ["readMetricsValues", "readMetricsValues"]
+    }, {
+      "x": 8,
+      "y": 6,
+      "w": 8,
+      "h": 13,
+      "i": "3",
+      "type": "Widget",
+      "widget": {
+        "title": "Disk R/W (KB/s - OTEL, ops - Zabbix)"
+      },
+      "graph": {
+        "type": "Line",
+        "opacity": 0.4,
+        "showXAxis": true,
+        "showYAxis": true
+      },
+      "metrics": ["meter_win_disk_read", "meter_win_disk_written"],
+      "metricTypes": ["readMetricsValues", "readMetricsValues"],
+      "metricConfig": [{
+        "calculation": "byteToKB"
+      }, {
+        "calculation": "byteToKB"
+      }]
+    }, {
+      "x": 0,
+      "y": 6,
+      "w": 8,
+      "h": 13,
+      "i": "5",
+      "type": "Widget",
+      "widget": {
+        "title": "CPU Average Used (%)"
+      },
+      "graph": {
+        "type": "Line",
+        "step": false,
+        "smooth": false,
+        "showSymbol": false,
+        "showXAxis": true,
+        "showYAxis": true
+      },
+      "metrics": ["meter_win_cpu_average_used"],
+      "metricTypes": ["readLabeledMetricsValues"]
+    }, {
+      "x": 16,
+      "y": 6,
+      "w": 8,
+      "h": 13,
+      "i": "6",
+      "type": "Widget",
+      "widget": {
+        "title": "Memory RAM (MB)"
+      },
+      "graph": {
+        "type": "Area",
+        "opacity": 0.4,
+        "showXAxis": true,
+        "showYAxis": true
+      },
+      "metrics": ["meter_win_memory_used", "meter_win_memory_total", "meter_win_memory_available"],
+      "metricTypes": ["readMetricsValues", "readMetricsValues", "readMetricsValues"],
+      "metricConfig": [{
+        "calculation": "byteToMB"
+      }, {
+        "calculation": "byteToMB"
+      }, {
+        "calculation": "byteToMB"
+      }]
+    }, {
+      "x": 0,
+      "y": 19,
+      "w": 8,
+      "h": 13,
+      "i": "8",
+      "type": "Widget",
+      "widget": {
+        "title": "Memory Swap (MB)"
+      },
+      "graph": {
+        "type": "Area",
+        "opacity": 0.4,
+        "showXAxis": true,
+        "showYAxis": true
+      },
+      "metrics": ["meter_win_memory_swap_free", "meter_win_memory_swap_total"],
+      "metricTypes": ["readMetricsValues", "readMetricsValues"],
+      "metricConfig": [{
+        "calculation": "byteToMB"
+      }, {
+        "calculation": "byteToMB"
+      }]
+    }, {
+      "x": 16,
+      "y": 0,
+      "w": 8,
+      "h": 6,
+      "i": "9",
+      "type": "Widget",
+      "widget": {
+        "title": "Memory Swap Usage"
+      },
+      "graph": {
+        "type": "Card",
+        "fontSize": 14,
+        "textAlign": "center",
+        "showUnit": true
+      },
+      "metrics": ["meter_win_memory_swap_percentage"],
+      "metricTypes": ["readMetricsValue"],
+      "metricConfig": [{
+        "calculation": "percentage",
+        "unit": "%"
+      }]
+    }, {
+      "x": 8,
+      "y": 0,
+      "w": 8,
+      "h": 6,
+      "i": "10",
+      "type": "Widget",
+      "widget": {
+        "title": "Memory RAM Usage"
+      },
+      "graph": {
+        "type": "Card",
+        "fontSize": 14,
+        "textAlign": "center",
+        "showUnit": true
+      },
+      "metrics": ["meter_win_memory_used"],
+      "metricTypes": ["readMetricsValue"],
+      "metricConfig": [{
+        "calculation": "byteToMB",
+        "unit": "MB"
+      }]
+    }, {
+      "x": 0,
+      "y": 0,
+      "w": 8,
+      "h": 6,
+      "i": "11",
+      "type": "Widget",
+      "widget": {
+        "title": "CPU Usage"
+      },
+      "graph": {
+        "type": "Card",
+        "fontSize": 14,
+        "textAlign": "center",
+        "showUnit": true
+      },
+      "metrics": ["meter_win_cpu_total_percentage"],
+      "metricTypes": ["readMetricsValue"],
+      "metricConfig": [{
+        "unit": "%"
+      }]
+    }],
+    "layer": "OS_WINDOWS",
+    "entity": "Service",
+    "name": "Windows-Service",
+    "id": "Windows-Service",
+    "isRoot": false
+  }
+}]
\ No newline at end of file


Test patch:
diff --git a/test/e2e-v2/cases/win/docker-compose.yml b/test/e2e-v2/cases/win/docker-compose.yml
new file mode 100644
index 000000000000..d2544f61ba1d
--- /dev/null
+++ b/test/e2e-v2/cases/win/docker-compose.yml
@@ -0,0 +1,51 @@
+# 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:
+
+  sender:
+    image: "eclipse-temurin:8-jre"
+    volumes:
+      - ./../../java-test-service/e2e-mock-sender/target/e2e-mock-sender-2.0.0.jar:/e2e-mock-sender-2.0.0.jar
+      - ./mock-data:/data/otel-metrics
+    command: [ "java", "-jar", "/e2e-mock-sender-2.0.0.jar" ]
+    environment:
+      OAP_HOST: oap
+      OAP_GRPC_PORT: 11800
+      OTEL_METRICS_DATA_PATH: /data/otel-metrics
+    networks:
+      - e2e
+    ports:
+      - 9093
+    healthcheck:
+      test: ["CMD", "sh", "-c", "nc -nz 127.0.0.1 9093"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+    depends_on:
+      oap:
+        condition: service_healthy
+networks:
+  e2e:
diff --git a/test/e2e-v2/cases/win/e2e.yaml b/test/e2e-v2/cases/win/e2e.yaml
new file mode 100644
index 000000000000..49fd45b9a8d1
--- /dev/null
+++ b/test/e2e-v2/cases/win/e2e.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.
+
+# 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
+
+trigger:
+  action: http
+  interval: 3s
+  times: 10
+  url: http://${sender_host}:${sender_9093}/otel-metrics/send
+  method: GET
+
+verify:
+  retry:
+    count: 10
+    interval: 3s
+  cases:
+    - includes:
+        - ./win-cases.yaml
diff --git a/test/e2e-v2/cases/win/expected/metrics-has-value.yml b/test/e2e-v2/cases/win/expected/metrics-has-value.yml
new file mode 100644
index 000000000000..ce1f3d83c82f
--- /dev/null
+++ b/test/e2e-v2/cases/win/expected/metrics-has-value.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 . }}
+- key: {{ notEmpty .key }}
+  value: {{ ge .value 0 }}
+{{- end }}
diff --git a/test/e2e-v2/cases/win/expected/service.yml b/test/e2e-v2/cases/win/expected/service.yml
new file mode 100644
index 000000000000..a3aec14d8d07
--- /dev/null
+++ b/test/e2e-v2/cases/win/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 "10.211.55.3" }}.1
+  name: 10.211.55.3
+  group: ""
+  shortname: 10.211.55.3
+  normal: true
+  layers:
+    - OS_WINDOWS
+  {{- end }}
diff --git a/test/e2e-v2/cases/win/mock-data/otel-mock-metrics.json b/test/e2e-v2/cases/win/mock-data/otel-mock-metrics.json
new file mode 100644
index 000000000000..4cb9c82d67ae
--- /dev/null
+++ b/test/e2e-v2/cases/win/mock-data/otel-mock-metrics.json
@@ -0,0 +1,177 @@
+{
+  "resourceMetrics": [
+    {
+      "resource": {
+        "attributes": [
+          {
+            "key": "service.name",
+            "value": {
+              "stringValue": "windows-monitoring"
+            }
+          },
+          {
+            "key": "net.host.name",
+            "value": {
+              "stringValue": "10.211.55.3"
+            }
+          },
+          {
+            "key": "service.instance.id",
+            "value": {
+              "stringValue": "10.211.55.3:9182"
+            }
+          },
+          {
+            "key": "net.host.port",
+            "value": {
+              "stringValue": "9182"
+            }
+          },
+          {
+            "key": "http.scheme",
+            "value": {
+              "stringValue": "http"
+            }
+          }
+        ]
+      },
+      "scopeMetrics": [
+        {
+          "scope": {},
+          "metrics": [
+            {
+              "name": "windows_cpu_time_total",
+              "description": "Time that processor spent in different modes (dpc, idle, interrupt, privileged, user)",
+              "sum": {
+                "dataPoints": [
+                  {
+                    "startTimeUnixNano": "1676140244999000000",
+                    "timeUnixNano": "1676140395007000000",
+                    "asDouble": 3.4375,
+                    "attributes": [
+                      {
+                        "key": "core",
+                        "value": {
+                          "stringValue": "0.0"
+                        }
+                      }
+                    ]
+                  },
+                  {
+                    "startTimeUnixNano": "1676140244999000000",
+                    "timeUnixNano": "1676140395007000000",
+                    "asDouble": 707.984375,
+                    "attributes": [
+                      {
+                        "key": "core",
+                        "value": {
+                          "stringValue": "0.0"
+                        }
+                      },
+                      {
+                        "key": "mode",
+                        "value": {
+                          "stringValue": "idle"
+                        }
+                      }
+                    ]
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "resource": {
+        "attributes": [
+          {
+            "key": "service.name",
+            "value": {
+              "stringValue": "windows-monitoring"
+            }
+          },
+          {
+            "key": "net.host.name",
+            "value": {
+              "stringValue": "10.211.55.3"
+            }
+          },
+          {
+            "key": "service.instance.id",
+            "value": {
+              "stringValue": "10.211.55.3:9182"
+            }
+          },
+          {
+            "key": "net.host.port",
+            "value": {
+              "stringValue": "9182"
+            }
+          },
+          {
+            "key": "http.scheme",
+            "value": {
+              "stringValue": "http"
+            }
+          }
+        ]
+      },
+      "scopeMetrics": [
+        {
+          "scope": {},
+          "metrics": [
+            {
+              "name": "windows_os_virtual_memory_bytes",
+              "description": "OperatingSystem.TotalVirtualMemorySize",
+              "gauge": {
+                "dataPoints": [
+                  {
+                    "timeUnixNano": "1676140375004000000",
+                    "asDouble": 8.8387584E9
+                  }
+                ]
+              }
+            },
+            {
+              "name": "windows_logical_disk_write_seconds_total",
+              "description": "Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)",
+              "sum": {
+                "dataPoints": [
+                  {
+                    "startTimeUnixNano": "1676140244999000000",
+                    "timeUnixNano": "1676140375004000000",
+                    "asDouble": 9.669203699999999,
+                    "attributes": [
+                      {
+                        "key": "volume",
+                        "value": {
+                          "stringValue": "C:"
+                        }
+                      }
+                    ]
+                  },
+                  {
+                    "startTimeUnixNano": "1676140244999000000",
+                    "timeUnixNano": "1676140375004000000",
+                    "asDouble": 8.321E-4,
+                    "attributes": [
+                      {
+                        "key": "volume",
+                        "value": {
+                          "stringValue": "HarddiskVolume1"
+                        }
+                      }
+                    ]
+                  }
+                ]
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/test/e2e-v2/cases/win/prometheus-windows_exporter/otel-collector-config.yaml b/test/e2e-v2/cases/win/prometheus-windows_exporter/otel-collector-config.yaml
new file mode 100644
index 000000000000..373996186f78
--- /dev/null
+++ b/test/e2e-v2/cases/win/prometheus-windows_exporter/otel-collector-config.yaml
@@ -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.
+
+receivers:
+  prometheus:
+    config:
+      scrape_configs:
+        - job_name: "windows-monitoring" # make sure to use this in the vm.yaml to filter only VM metrics
+          scrape_interval: 10s
+          static_configs:
+            - targets: ["win-service:9182"]
+
+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" # The OAP Server address
+    ###############################################################################
+    # OTEL previous version before 0.34.0 the config format, eg. 0.29.0 should be:#
+    # insecure: true                                                              #
+    # The new version should be:                                                  #
+    # tls:                                                                        #
+    #   insecure: true                                                            #
+    ###############################################################################
+    tls:
+      insecure: true
+    #insecure: true
+  # Exports data to the console
+  logging:
+    logLevel: debug
+
+service:
+  pipelines:
+    metrics:
+      receivers: [prometheus]
+      processors: [batch]
+      #########################################
+      # oc exporter config format:            #
+      # exporters: [opencensus,logging]       #
+      #########################################
+      exporters: [otlp, logging]
diff --git a/test/e2e-v2/cases/win/win-cases.yaml b/test/e2e-v2/cases/win/win-cases.yaml
new file mode 100644
index 000000000000..c41b102a958a
--- /dev/null
+++ b/test/e2e-v2/cases/win/win-cases.yaml
@@ -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.
+
+# This file is used to show how to write configuration files and can be used to test.
+
+  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 linear --name=meter_win_cpu_total_percentage --service-name=10.211.55.3 | yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml