Support the telegraf receiver plugin module (#9620)
* The telegraf receiver plugin module development. * Refactored code of converting telegraf data and fixed some errors. * Support Telegraf receiver plugin module. * Add telegraf-receiver.md, update changes.md and vm-monitoring.md. * Rename YAML file and change code style. * Change receiver-telegraf of application.yml. * The receiver-telegraf e2e test. * The telegraf receiver e2e test. * Fix an issue and delete redundant configs. * Add Unit Test about converting Telegraf metrics. * Adjust Unit Test about converting Telegraf metrics. * Add License Header to Unit Test and change binary.xml. * Change module provider's config initialization mechanism. * Exclude the telegraf-rules in server-starter pom.xml. * Fix telegraf e2e test issues. * Change telegraf e2e test. * Fix issues * Fix issues. * Add Sample convert Unit Test. * Change vm.yaml, related documents and fix some issues. * Change backend-vm-monitoring.md. * Fix SampleConvertTest checkstyle issue. * Change vm.yaml swap MAL. * Update menu.yml and binary.xml. * Update Telegraf Unit test. * Delete telegraf config package, use meter.analyzer.prometheus package to load config file. * Reorder telegraf metrics in menu.yml. * Change e2e, vm, config, linux-service and vm.md. * Update telegraf.conf file. * Change url of telegraf.conf file. * Update e2e.yaml, conf file, menu.yml and delete useless code of provider. * Update grouping sampleFamily by timestamp and name, and add new UTs. * Update vm-monitoring.md and .asf.yaml. Co-authored-by: Superskyyy (ONLINE) <Superskyyy@outlook.com> Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
parent
d32a318637
commit
42f3396b64
|
|
@ -33,6 +33,7 @@ github:
|
||||||
- open-telemetry
|
- open-telemetry
|
||||||
- zabbix
|
- zabbix
|
||||||
- ebpf
|
- ebpf
|
||||||
|
- telegraf
|
||||||
enabled_merge_buttons:
|
enabled_merge_buttons:
|
||||||
squash: true
|
squash: true
|
||||||
merge: false
|
merge: false
|
||||||
|
|
|
||||||
|
|
@ -549,6 +549,8 @@ jobs:
|
||||||
config: test/e2e-v2/cases/vm/zabbix/e2e.yaml
|
config: test/e2e-v2/cases/vm/zabbix/e2e.yaml
|
||||||
- name: VM Prometheus
|
- name: VM Prometheus
|
||||||
config: test/e2e-v2/cases/vm/prometheus-node-exporter/e2e.yaml
|
config: test/e2e-v2/cases/vm/prometheus-node-exporter/e2e.yaml
|
||||||
|
- name: VM Telegraf
|
||||||
|
config: test/e2e-v2/cases/vm/telegraf/e2e.yaml
|
||||||
- name: So11y
|
- name: So11y
|
||||||
config: test/e2e-v2/cases/so11y/e2e.yaml
|
config: test/e2e-v2/cases/so11y/e2e.yaml
|
||||||
- name: MySQL Prometheus and slowsql
|
- name: MySQL Prometheus and slowsql
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
<include>ui-initialized-templates/*/*.json</include>
|
<include>ui-initialized-templates/*/*.json</include>
|
||||||
<include>lal/*</include>
|
<include>lal/*</include>
|
||||||
<include>log-mal-rules/*</include>
|
<include>log-mal-rules/*</include>
|
||||||
|
<include>telegraf-rules/*</include>
|
||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>config</outputDirectory>
|
<outputDirectory>config</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
|
|
|
||||||
|
|
@ -3,38 +3,54 @@ SkyWalking leverages Prometheus node-exporter to collect metrics data from the V
|
||||||
[OpenTelemetry receiver](opentelemetry-receiver.md) and into the [Meter System](./../../concepts-and-designs/meter.md).
|
[OpenTelemetry receiver](opentelemetry-receiver.md) and into the [Meter System](./../../concepts-and-designs/meter.md).
|
||||||
VM entity as a `Service` in OAP and on the `Layer: OS_LINUX`.
|
VM entity as a `Service` in OAP and on the `Layer: OS_LINUX`.
|
||||||
|
|
||||||
|
SkyWalking also provides InfluxDB Telegraf to receive VMs' metrics data by [Telegraf receiver](./telegraf-receiver.md).
|
||||||
|
The telegraf receiver plugin receiver, process and convert the metrics, then it send converted metrics to [Meter System](./../../concepts-and-designs/meter.md).
|
||||||
|
VM entity as a `Service` in OAP and on the `Layer: OS_LINUX`.
|
||||||
|
|
||||||
## Data flow
|
## Data flow
|
||||||
|
**For OpenTelemetry receiver:**
|
||||||
1. The Prometheus node-exporter collects metrics data from the VMs.
|
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 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.
|
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:**
|
||||||
|
1. The InfluxDB Telegraf [input plugins](https://docs.influxdata.com/telegraf/v1.24/plugins/) collects various metrics data from the VMs.
|
||||||
|
2. The cpu, mem, system, disk and diskio input plugins should be set in telegraf.conf file.
|
||||||
|
2. The InfluxDB Telegraf send `JSON` format metrics by `HTTP` messages to Telegraf Receiver, then pushes converted metrics to the SkyWalking OAP Server [Meter System](./../../concepts-and-designs/meter.md).
|
||||||
|
3. The SkyWalking OAP Server parses the expression with [MAL](../../concepts-and-designs/mal.md) to filter/calculate/aggregate ad store the results.
|
||||||
|
4. The meter_vm_cpu_average_used metrics indicates the average usage of each CPU core for telegraf receiver.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
**For OpenTelemetry receiver:**
|
||||||
1. Setup [Prometheus node-exporter](https://prometheus.io/docs/guides/node-exporter/).
|
1. Setup [Prometheus node-exporter](https://prometheus.io/docs/guides/node-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/vm/prometheus-node-exporter/otel-collector-config.yaml).
|
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/vm/prometheus-node-exporter/otel-collector-config.yaml).
|
||||||
3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
|
3. Config SkyWalking [OpenTelemetry receiver](opentelemetry-receiver.md).
|
||||||
|
|
||||||
|
**For Telegraf receiver:**
|
||||||
|
1. Setup InfluxDB Telegraf's `telegraf.conf file` according to [Telegraf office document](https://docs.influxdata.com/telegraf/v1.24/).
|
||||||
|
2. Setup InfluxDB Telegraf's `telegraf.conf file` specific rules according to [Telegraf receiver document](telegraf-receiver.md).
|
||||||
|
3. Config SkyWalking [Telegraf receiver](telegraf-receiver.md).
|
||||||
|
|
||||||
## Supported Metrics
|
## Supported Metrics
|
||||||
|
|
||||||
| Monitoring Panel | Unit | Metric Name | Description | Data Source |
|
| Monitoring Panel | Unit | Metric Name | Description | Data Source |
|
||||||
|-----|-----|-----|-----|-----|
|
|------------------------------|------|-------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||||||
| CPU Usage | % | cpu_total_percentage | The total percentage usage of the CPU core. If there are 2 cores, the maximum usage is 200%. | Prometheus node-exporter |
|
| CPU Usage | % | meter_vm_cpu_total_percentage | The total percentage usage of the CPU core. If there are 2 cores, the maximum usage is 200%. | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Memory RAM Usage | MB | meter_vm_memory_used | The total RAM usage | Prometheus node-exporter |
|
| Memory RAM Usage | MB | meter_vm_memory_used | The total RAM usage | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Memory Swap Usage | % | meter_vm_memory_swap_percentage | The percentage usage of swap memory | Prometheus node-exporter |
|
| Memory Swap Usage | % | meter_vm_memory_swap_percentage | The percentage usage of swap memory | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| CPU Average Used | % | meter_vm_cpu_average_used | The percentage usage of the CPU core in each mode | Prometheus node-exporter |
|
| CPU Average Used | % | meter_vm_cpu_average_used | The percentage usage of the CPU core in each mode | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| CPU Load | | meter_vm_cpu_load1<br />meter_vm_cpu_load5<br />meter_vm_cpu_load15 | The CPU 1m / 5m / 15m average load | Prometheus node-exporter |
|
| CPU Load | | meter_vm_cpu_load1<br />meter_vm_cpu_load5<br />meter_vm_cpu_load15 | The CPU 1m / 5m / 15m average load | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Memory RAM | MB | meter_vm_memory_total<br />meter_vm_memory_available<br />meter_vm_memory_used | The RAM statistics, including Total / Available / Used | Prometheus node-exporter |
|
| Memory RAM | MB | meter_vm_memory_total<br />meter_vm_memory_available<br />meter_vm_memory_used | The RAM statistics, including Total / Available / Used | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Memory Swap | MB | meter_vm_memory_swap_free<br />meter_vm_memory_swap_total | Swap memory statistics, including Free / Total | Prometheus node-exporter |
|
| Memory Swap | MB | meter_vm_memory_swap_free<br />meter_vm_memory_swap_total | Swap memory statistics, including Free / Total | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| File System Mountpoint Usage | % | meter_vm_filesystem_percentage | The percentage usage of the file system at each mount point | Prometheus node-exporter |
|
| File System Mountpoint Usage | % | meter_vm_filesystem_percentage | The percentage usage of the file system at each mount point | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Disk R/W | KB/s | meter_vm_disk_read,meter_vm_disk_written | The disk read and written | Prometheus node-exporter |
|
| Disk R/W | KB/s | meter_vm_disk_read,meter_vm_disk_written | The disk read and written | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Network Bandwidth Usage | KB/s | meter_vm_network_receive<br />meter_vm_network_transmit | The network receive and transmit | Prometheus node-exporter |
|
| Network Bandwidth Usage | KB/s | meter_vm_network_receive<br />meter_vm_network_transmit | The network receive and transmit | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Network Status | | meter_vm_tcp_curr_estab<br />meter_vm_tcp_tw<br />meter_vm_tcp_alloc<br />meter_vm_sockets_used<br />meter_vm_udp_inuse | The number of TCPs established / TCP time wait / TCPs allocated / sockets in use / UDPs in use | Prometheus node-exporter |
|
| Network Status | | meter_vm_tcp_curr_estab<br />meter_vm_tcp_tw<br />meter_vm_tcp_alloc<br />meter_vm_sockets_used<br />meter_vm_udp_inuse | The number of TCPs established / TCP time wait / TCPs allocated / sockets in use / UDPs in use | Prometheus node-exporter<br />Telegraf input plugin |
|
||||||
| Filefd Allocated | | meter_vm_filefd_allocated | The number of file descriptors allocated | Prometheus node-exporter |
|
| Filefd Allocated | | meter_vm_filefd_allocated | The number of file descriptors allocated | Prometheus node-exporter |
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
You can customize your own metrics/expression/dashboard panel.
|
You can customize your own metrics/expression/dashboard panel.
|
||||||
The metrics definition and expression rules are found in `/config/otel-rules/vm.yaml`.
|
The metrics definition and expression rules are found in `/config/otel-rules/vm.yaml` and `/config/telegraf-rules/vm.yaml`.
|
||||||
The dashboard panel confirmations are found in `/config/ui-initialized-templates/os_linux`.
|
The dashboard panel confirmations are found in `/config/ui-initialized-templates/os_linux`.
|
||||||
|
|
||||||
## Blog
|
## Blog
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Telegraf receiver
|
||||||
|
|
||||||
|
The Telegraf receiver supports receiving InfluxDB Telegraf's metrics by meter-system.
|
||||||
|
The OAP can load the configuration at bootstrap. The files are located at `$CLASSPATH/telegraf-rules`.
|
||||||
|
If the new configuration is not well-formed, the OAP may fail to start up.
|
||||||
|
|
||||||
|
This is the [InfluxDB Telegraf](https://docs.influxdata.com/telegraf/v1.24/) Document,
|
||||||
|
the Telegraf receiver can handle Telegraf's [CPU Input Plugin](https://github.com/influxdata/telegraf/blob/release-1.24/plugins/inputs/cpu/README.md),
|
||||||
|
[Memory Input Plugin](https://github.com/influxdata/telegraf/blob/release-1.24/plugins/inputs/mem/README.md).
|
||||||
|
|
||||||
|
There are many other telegraf input plugins, users can customize different input plugins' rule files.
|
||||||
|
The rule file should be in YAML format, defined by the scheme described in [MAL](../../concepts-and-designs/mal.md).
|
||||||
|
Please see the [telegraf plugin directory](https://docs.influxdata.com/telegraf/v1.24/plugins/) for more input plugins information.
|
||||||
|
|
||||||
|
**Notice:**
|
||||||
|
* The Telegraf receiver module uses `HTTP` to receive telegraf's metrics,
|
||||||
|
so the outputs method should be set `[[outputs.http]]` in telegraf.conf file.
|
||||||
|
Please see the [http outputs](https://github.com/influxdata/telegraf/blob/release-1.24/plugins/outputs/http/README.md)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
* The Telegraf receiver module **only** process telegraf's `JSON` metrics format,
|
||||||
|
the data format should be set `data_format = "json"` in telegraf.conf file.
|
||||||
|
Please see the [JSON data format](https://docs.influxdata.com/telegraf/v1.24/data_formats/output/json/)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
* The default `json_timestamp_units` is second in JSON output,
|
||||||
|
and the Telegraf receiver module **only** process `second` timestamp unit.
|
||||||
|
If users configure `json_timestamp_units` in telegraf.conf file, `json_timestamp_units = "1s"` is feasible.
|
||||||
|
Please see the [JSON data format](https://docs.influxdata.com/telegraf/v1.24/data_formats/output/json/)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
The following is the default telegraf receiver YAML rule file in the `application.yml`,
|
||||||
|
Set `SW_RECEIVER_TELEGRAF:default` through system environment or change `SW_RECEIVER_TELEGRAF_ACTIVE_FILES:vm`
|
||||||
|
to activate the OpenTelemetry receiver with `vm.yml` in telegraf-rules.
|
||||||
|
```yaml
|
||||||
|
receiver-telegraf:
|
||||||
|
selector: ${SW_RECEIVER_TELEGRAF:default}
|
||||||
|
default:
|
||||||
|
activeFiles: ${SW_RECEIVER_TELEGRAF_ACTIVE_FILES:vm}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Rule Name | Description | Configuration File | Data Source |
|
||||||
|
|-----------|----------------|------------------------|-------------------------------------------------------------------------|
|
||||||
|
| vm | Metrics of VMs | telegraf-rules/vm.yaml | Telegraf inputs plugins --> Telegraf Receiver --> SkyWalking OAP Server |
|
||||||
|
|
||||||
|
|
@ -119,6 +119,8 @@ catalog:
|
||||||
path: "/en/setup/backend/backend-zabbix"
|
path: "/en/setup/backend/backend-zabbix"
|
||||||
- name: "Meter Analysis"
|
- name: "Meter Analysis"
|
||||||
path: "/en/setup/backend/backend-meter"
|
path: "/en/setup/backend/backend-meter"
|
||||||
|
- name: "Telegraf Metrics"
|
||||||
|
path: "/en/setup/backend/telegraf-receiver"
|
||||||
- name: "Apdex Threshold"
|
- name: "Apdex Threshold"
|
||||||
path: "/en/setup/backend/apdex-threshold"
|
path: "/en/setup/backend/apdex-threshold"
|
||||||
- name: "Spring Sleuth Metrics Analysis"
|
- name: "Spring Sleuth Metrics Analysis"
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
<module>skywalking-event-receiver-plugin</module>
|
<module>skywalking-event-receiver-plugin</module>
|
||||||
<module>skywalking-zabbix-receiver-plugin</module>
|
<module>skywalking-zabbix-receiver-plugin</module>
|
||||||
<module>skywalking-ebpf-receiver-plugin</module>
|
<module>skywalking-ebpf-receiver-plugin</module>
|
||||||
|
<module>skywalking-telegraf-receiver-plugin</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>server-receiver-plugin</artifactId>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<version>9.3.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>skywalking-telegraf-receiver-plugin</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>agent-analyzer</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>skywalking-sharing-server-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.module;
|
||||||
|
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||||
|
|
||||||
|
public class TelegrafReceiverModule extends ModuleDefine {
|
||||||
|
|
||||||
|
public TelegrafReceiverModule() {
|
||||||
|
super("receiver-telegraf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class[] services() {
|
||||||
|
return new Class[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.provider;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.skywalking.oap.server.core.Const;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class TelegrafModuleConfig extends ModuleConfig {
|
||||||
|
|
||||||
|
public static final String CONFIG_PATH = "telegraf-rules";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* active receive configs, files split by ","
|
||||||
|
*/
|
||||||
|
private String activeFiles = Const.EMPTY_STRING;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.provider;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.linecorp.armeria.common.HttpMethod;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rule;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rules;
|
||||||
|
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
|
||||||
|
import org.apache.skywalking.oap.server.core.server.HTTPHandlerRegister;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
|
||||||
|
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
|
||||||
|
import org.apache.skywalking.oap.server.library.util.StringUtil;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.module.TelegrafReceiverModule;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.TelegrafServiceHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TelegrafReceiverProvider extends ModuleProvider {
|
||||||
|
private List<Rule> configs;
|
||||||
|
private TelegrafModuleConfig moduleConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ModuleDefine> module() {
|
||||||
|
return TelegrafReceiverModule.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigCreator newConfigCreator() {
|
||||||
|
return new ConfigCreator<TelegrafModuleConfig>() {
|
||||||
|
@Override
|
||||||
|
public Class type() {
|
||||||
|
return TelegrafModuleConfig.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitialized(final TelegrafModuleConfig initialized) {
|
||||||
|
moduleConfig = initialized;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
|
||||||
|
try {
|
||||||
|
configs = Rules.loadRules(TelegrafModuleConfig.CONFIG_PATH,
|
||||||
|
StringUtil.isEmpty(moduleConfig.getActiveFiles()) ? Collections.emptyList() : Splitter.on(",").splitToList(moduleConfig.getActiveFiles()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ModuleStartException("Failed to load MAL rules", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() throws ServiceNotProvidedException, ModuleStartException {
|
||||||
|
if (CollectionUtils.isNotEmpty(configs)) {
|
||||||
|
HTTPHandlerRegister httpHandlerRegister = getManager().find(SharingServerModule.NAME)
|
||||||
|
.provider()
|
||||||
|
.getService(HTTPHandlerRegister.class);
|
||||||
|
MeterSystem meterSystem = getManager().find(CoreModule.NAME)
|
||||||
|
.provider()
|
||||||
|
.getService(MeterSystem.class);
|
||||||
|
httpHandlerRegister.addHandler(new TelegrafServiceHandler(getManager(), meterSystem, configs),
|
||||||
|
Collections.singletonList(HttpMethod.POST));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyAfterCompleted() throws ServiceNotProvidedException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] requiredModules() {
|
||||||
|
return new String[] {
|
||||||
|
CoreModule.NAME,
|
||||||
|
SharingServerModule.NAME
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.provider.handler;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.linecorp.armeria.server.annotation.Post;
|
||||||
|
import com.linecorp.armeria.server.annotation.RequestConverter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.skywalking.apm.network.common.v3.Commands;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.MetricConvert;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.dsl.Sample;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.dsl.SampleFamily;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.dsl.SampleFamilyBuilder;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rule;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo.TelegrafData;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo.TelegrafDatum;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.api.CounterMetrics;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.api.HistogramMetrics;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.api.MetricsCreator;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.api.MetricsTag;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class TelegrafServiceHandler {
|
||||||
|
|
||||||
|
private final HistogramMetrics histogram;
|
||||||
|
private final CounterMetrics errorCounter;
|
||||||
|
private List<MetricConvert> metricConvert;
|
||||||
|
|
||||||
|
public TelegrafServiceHandler(ModuleManager moduleManager, MeterSystem meterSystem, List<Rule> rules) {
|
||||||
|
|
||||||
|
this.metricConvert = rules.stream().map(r -> new MetricConvert(r, meterSystem)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
final MetricsCreator metricsCreator = moduleManager.find(TelemetryModule.NAME)
|
||||||
|
.provider()
|
||||||
|
.getService(MetricsCreator.class);
|
||||||
|
|
||||||
|
histogram = metricsCreator.createHistogramMetric(
|
||||||
|
"telegraf_in_latency", "The process latency of telegraf data",
|
||||||
|
new MetricsTag.Keys("protocol"), new MetricsTag.Values("http")
|
||||||
|
);
|
||||||
|
|
||||||
|
errorCounter = metricsCreator.createCounter(
|
||||||
|
"telegraf_error_count", "The error number of telegraf analysis",
|
||||||
|
new MetricsTag.Keys("protocol"), new MetricsTag.Values("http")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the TelegrafData object to meter {@link Sample}
|
||||||
|
**/
|
||||||
|
public List<Sample> convertTelegraf(TelegrafDatum telegrafData) {
|
||||||
|
|
||||||
|
List<Sample> sampleList = new ArrayList<>();
|
||||||
|
|
||||||
|
Map<String, Object> fields = telegrafData.getFields();
|
||||||
|
String name = telegrafData.getName();
|
||||||
|
Map<String, String> tags = telegrafData.getTags();
|
||||||
|
ImmutableMap<String, String> immutableTags = ImmutableMap.copyOf(tags);
|
||||||
|
long timestamp = telegrafData.getTimestamp();
|
||||||
|
|
||||||
|
fields.forEach((key, value) -> {
|
||||||
|
if (value instanceof Number) {
|
||||||
|
Sample.SampleBuilder builder = Sample.builder();
|
||||||
|
Sample sample = builder.name(name + "_" + key)
|
||||||
|
.timestamp(timestamp * 1000L)
|
||||||
|
.value(((Number) value).doubleValue())
|
||||||
|
.labels(immutableTags).build();
|
||||||
|
|
||||||
|
sampleList.add(sample);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sampleList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ImmutableMap<String, SampleFamily>> convertSampleFamily(TelegrafData telegrafData) {
|
||||||
|
List<Sample> allSamples = new ArrayList<>();
|
||||||
|
|
||||||
|
List<TelegrafDatum> metrics = telegrafData.getMetrics();
|
||||||
|
for (TelegrafDatum m : metrics) {
|
||||||
|
List<Sample> samples = convertTelegraf(m);
|
||||||
|
allSamples.addAll(samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ImmutableMap<String, SampleFamily>> res = new ArrayList<>();
|
||||||
|
|
||||||
|
// Grouping all samples by timestamp name
|
||||||
|
Map<Long, List<Sample>> sampleFamilyByTime = allSamples.stream()
|
||||||
|
.collect(Collectors.groupingBy(Sample::getTimestamp));
|
||||||
|
|
||||||
|
// Grouping all samples with the same timestamp by name
|
||||||
|
for (List<Sample> s : sampleFamilyByTime.values()) {
|
||||||
|
ImmutableMap.Builder<String, SampleFamily> builder = ImmutableMap.builder();
|
||||||
|
Map<String, List<Sample>> sampleFamilyByName = s.stream()
|
||||||
|
.collect(Collectors.groupingBy(Sample::getName));
|
||||||
|
sampleFamilyByName.forEach((k, v) ->
|
||||||
|
builder.put(k, SampleFamilyBuilder.newBuilder(v.toArray(new Sample[0])).build()));
|
||||||
|
res.add(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post("/telegraf")
|
||||||
|
@RequestConverter(TelegrafData.class)
|
||||||
|
public Commands collectData(TelegrafData telegrafData) {
|
||||||
|
try (HistogramMetrics.Timer ignored = histogram.createTimer()) {
|
||||||
|
List<ImmutableMap<String, SampleFamily>> sampleFamily = convertSampleFamily(telegrafData);
|
||||||
|
sampleFamily.forEach(s -> metricConvert.forEach(m -> m.toMeter(s)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorCounter.inc();
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return Commands.newBuilder().build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.linecorp.armeria.common.AggregatedHttpRequest;
|
||||||
|
import com.linecorp.armeria.common.annotation.Nullable;
|
||||||
|
import com.linecorp.armeria.server.ServiceRequestContext;
|
||||||
|
import com.linecorp.armeria.server.annotation.RequestConverterFunction;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class TelegrafData implements RequestConverterFunction {
|
||||||
|
private List<TelegrafDatum> metrics;
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Object convertRequest(ServiceRequestContext ctx, AggregatedHttpRequest request, Class<?> expectedResultType,
|
||||||
|
@Nullable ParameterizedType expectedParameterizedResultType) throws Exception {
|
||||||
|
|
||||||
|
if (expectedResultType == TelegrafData.class) {
|
||||||
|
// Convert the request to a TelegrafData object
|
||||||
|
return MAPPER.readValue(request.contentUtf8(), TelegrafData.class);
|
||||||
|
}
|
||||||
|
return RequestConverterFunction.fallthrough();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class TelegrafDatum {
|
||||||
|
private Map<String, Object> fields;
|
||||||
|
private String name;
|
||||||
|
private Map<String, String> tags;
|
||||||
|
private long timestamp;
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
org.apache.skywalking.oap.server.receiver.telegraf.module.TelegrafReceiverModule
|
||||||
|
|
@ -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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
org.apache.skywalking.oap.server.receiver.telegraf.provider.TelegrafReceiverProvider
|
||||||
|
|
@ -0,0 +1,490 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.dsl.Sample;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.dsl.SampleFamily;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rule;
|
||||||
|
import org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rules;
|
||||||
|
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||||
|
import org.apache.skywalking.oap.server.core.CoreModuleProvider;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.StreamDefinition;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue;
|
||||||
|
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||||
|
import org.apache.skywalking.oap.server.core.config.NamingControl;
|
||||||
|
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGrouping;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.mock.MockModuleManager;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.mock.MockModuleProvider;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.TelegrafModuleConfig;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.TelegrafServiceHandler;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo.TelegrafData;
|
||||||
|
import org.apache.skywalking.oap.server.receiver.telegraf.provider.handler.pojo.TelegrafDatum;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.api.MetricsCreator;
|
||||||
|
import org.apache.skywalking.oap.server.telemetry.none.MetricsCreatorNoop;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.powermock.reflect.Whitebox;
|
||||||
|
import org.testcontainers.shaded.com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||||
|
public class TelegrafMetricsTest {
|
||||||
|
|
||||||
|
protected CoreModuleProvider moduleProvider;
|
||||||
|
protected ModuleManager moduleManager;
|
||||||
|
protected MeterSystem meterSystem;
|
||||||
|
protected TelegrafServiceHandler telegrafServiceHandler;
|
||||||
|
|
||||||
|
private List<AcceptableValue> values = new ArrayList<>();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
MeterEntity.setNamingControl(
|
||||||
|
new NamingControl(512, 512, 512, new EndpointNameGrouping()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDown() {
|
||||||
|
MeterEntity.setNamingControl(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupMetrics() throws Throwable {
|
||||||
|
moduleProvider = Mockito.mock(CoreModuleProvider.class);
|
||||||
|
moduleManager = new MockModuleManager() {
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
register(CoreModule.NAME, () -> new MockModuleProvider() {
|
||||||
|
@Override
|
||||||
|
protected void register() {
|
||||||
|
registerServiceImplementation(NamingControl.class, new NamingControl(
|
||||||
|
512, 512, 512, new EndpointNameGrouping()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
register(TelemetryModule.NAME, () -> new MockModuleProvider() {
|
||||||
|
@Override
|
||||||
|
protected void register() {
|
||||||
|
registerServiceImplementation(MetricsCreator.class, new MetricsCreatorNoop());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// prepare the context
|
||||||
|
meterSystem = Mockito.mock(MeterSystem.class);
|
||||||
|
Whitebox.setInternalState(MetricsStreamProcessor.class, "PROCESSOR",
|
||||||
|
Mockito.spy(MetricsStreamProcessor.getInstance()));
|
||||||
|
doNothing().when(MetricsStreamProcessor.getInstance()).create(any(), (StreamDefinition) any(), any());
|
||||||
|
CoreModule coreModule = Mockito.spy(CoreModule.class);
|
||||||
|
|
||||||
|
Whitebox.setInternalState(coreModule, "loadedProvider", moduleProvider);
|
||||||
|
when(moduleProvider.getService(MeterSystem.class)).thenReturn(meterSystem);
|
||||||
|
|
||||||
|
telegrafServiceHandler = buildTelegrafServiceHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TelegrafServiceHandler buildTelegrafServiceHandler() throws Exception {
|
||||||
|
// Notifies meter system received metric
|
||||||
|
doAnswer(invocationOnMock -> {
|
||||||
|
values.add(invocationOnMock.getArgument(0, AcceptableValue.class));
|
||||||
|
return null;
|
||||||
|
}).when(meterSystem).doStreamingCalculation(any());
|
||||||
|
|
||||||
|
// load context
|
||||||
|
List<Rule> telegrafConfigs = Rules.loadRules(TelegrafModuleConfig.CONFIG_PATH, Arrays.asList("vm"));
|
||||||
|
return new TelegrafServiceHandler(moduleManager, meterSystem, telegrafConfigs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TelegrafData assertTelegrafJSONConvert(String jsonMessage) throws Exception {
|
||||||
|
Assert.assertNotNull(jsonMessage);
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
TelegrafData telegrafData = mapper.readValue(jsonMessage, TelegrafData.class);
|
||||||
|
Assert.assertNotNull(telegrafData);
|
||||||
|
return telegrafData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertSample(Sample sample, String... name) {
|
||||||
|
Assert.assertNotNull(sample);
|
||||||
|
Assert.assertTrue(Arrays.asList(name).contains(sample.getName()));
|
||||||
|
Assert.assertEquals(sample.getLabels(), ImmutableMap.copyOf(Collections.singletonMap("host", "localHost")));
|
||||||
|
Assert.assertTrue(sample.getValue() >= 0);
|
||||||
|
Assert.assertTrue(sample.getTimestamp() >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertConvertToSample(TelegrafData telegrafData, int totalSamplesPerMetrics, String... name) {
|
||||||
|
Assert.assertNotNull(telegrafData);
|
||||||
|
List<TelegrafDatum> metrics = telegrafData.getMetrics();
|
||||||
|
Assert.assertNotNull(metrics);
|
||||||
|
for (TelegrafDatum t : metrics) {
|
||||||
|
boolean convert = false;
|
||||||
|
List<Sample> samples = telegrafServiceHandler.convertTelegraf(t);
|
||||||
|
Assert.assertEquals(samples.size(), totalSamplesPerMetrics);
|
||||||
|
for (Sample s : samples) {
|
||||||
|
assertSample(s, name);
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
if (!convert) {
|
||||||
|
// Throw exception when key not found
|
||||||
|
throw new AssertionError("Failed to convert json telegraf message to Sample.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertConvertToSampleFamily(TelegrafData telegrafData, int sampleFamilySize, int samplePerSampleFamily, String... name) {
|
||||||
|
Assert.assertNotNull(telegrafData);
|
||||||
|
List<ImmutableMap<String, SampleFamily>> sampleFamilyCollections = telegrafServiceHandler.convertSampleFamily(telegrafData);
|
||||||
|
Assert.assertNotNull(sampleFamilyCollections);
|
||||||
|
int actualSize = 0;
|
||||||
|
for (ImmutableMap<String, SampleFamily> samples : sampleFamilyCollections) {
|
||||||
|
samples.forEach((k, v) -> Assert.assertEquals(v.samples.length, samplePerSampleFamily));
|
||||||
|
actualSize += samples.size();
|
||||||
|
}
|
||||||
|
Assert.assertEquals(actualSize, sampleFamilySize);
|
||||||
|
sampleFamilyCollections.forEach(sampleFamily -> {
|
||||||
|
for (Map.Entry<String, SampleFamily> entry : sampleFamily.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
SampleFamily value = entry.getValue();
|
||||||
|
boolean convert = false;
|
||||||
|
Assert.assertTrue(Arrays.asList(name).contains(key));
|
||||||
|
for (Sample s : value.samples) {
|
||||||
|
assertSample(s, name);
|
||||||
|
convert = true;
|
||||||
|
}
|
||||||
|
if (!convert) {
|
||||||
|
// Throw exception when key not found
|
||||||
|
throw new AssertionError("Failed to convert json telegraf message to Sample.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneMemMetrics() throws Throwable {
|
||||||
|
String oneMemMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"available\":6047739904,\"available_percent\":35.41215070500567,\"total\":17078149120,\"used\":11030409216,\"used_percent\":64.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(oneMemMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 5, 1, metricsNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleMemMetrics() throws Throwable {
|
||||||
|
String threeMemMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"available\":6047739904,\"available_percent\":35.41215070500567,\"total\":17078149120,\"used\":11030409216,\"used_percent\":64.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":6047563904,\"available_percent\":56.41215070500567,\"total\":27048549120,\"used\":340364409216,\"used_percent\":44.58454929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663491390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":5047739904,\"available_percent\":43.41215070500567,\"total\":46078149120,\"used\":45030409216,\"used_percent\":23.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1453365320}]}";
|
||||||
|
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(threeMemMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 15, 1, metricsNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneCpuMetrics() throws Throwable {
|
||||||
|
String oneCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(oneCpuMetrics);
|
||||||
|
String[] metricsNames = {"cpu_usage_idle", "cpu_usage_irq", "cpu_usage_system", "cpu_usage_user"};
|
||||||
|
assertConvertToSample(telegrafData, 4, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 4, 1, metricsNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleCpuMetrics() throws Throwable {
|
||||||
|
String twoCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":45.32710280373831,\"usage_irq\":0.4515344797507788,\"usage_system\":3.4533956386292835,\"usage_user\":45.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1453365320}]}";
|
||||||
|
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(twoCpuMetrics);
|
||||||
|
String[] metricsNames = {"cpu_usage_idle", "cpu_usage_irq", "cpu_usage_system", "cpu_usage_user"};
|
||||||
|
assertConvertToSample(telegrafData, 4, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 8, 1, metricsNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleCpuMetricsWithSameTimestamp() throws Throwable {
|
||||||
|
String twoCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":67.32710280373831,\"usage_irq\":0.5415264797507788,\"usage_system\":1.6533956386292835,\"usage_user\":76.54797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":74.32710280373831,\"usage_irq\":1.2535264797507788,\"usage_system\":4.5633956386292835,\"usage_user\":54.23797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":45.32710280373831,\"usage_irq\":0.4515344797507788,\"usage_system\":3.4533956386292835,\"usage_user\":45.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(twoCpuMetrics);
|
||||||
|
String[] metricsNames = {"cpu_usage_idle", "cpu_usage_irq", "cpu_usage_system", "cpu_usage_user"};
|
||||||
|
assertConvertToSample(telegrafData, 4, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 4, 4, metricsNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidJSONConvert() {
|
||||||
|
String invalidMetrics = "This is a invalid metrics message";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected JsonParseException to throw, but it didn't.",
|
||||||
|
JsonParseException.class, () -> assertTelegrafJSONConvert(invalidMetrics));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidSampleNames() {
|
||||||
|
String oneCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(oneCpuMetrics);
|
||||||
|
String[] wrongMetricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 4, wrongMetricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidSampleFamilyNames() {
|
||||||
|
String oneMemMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"available\":6047739904,\"available_percent\":35.41215070500567,\"total\":17078149120,\"used\":11030409216,\"used_percent\":64.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(oneMemMetrics);
|
||||||
|
String[] wrongMetricsNames = {"cpu_usage_idle", "cpu_usage_irq", "cpu_usage_system", "cpu_usage_user"};
|
||||||
|
assertConvertToSampleFamily(telegrafData, 5, 1, wrongMetricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongSampleNumbers() {
|
||||||
|
String twoCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":45.32710280373831,\"usage_irq\":0.4515344797507788,\"usage_system\":3.4533956386292835,\"usage_user\":45.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1453365320}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(twoCpuMetrics);
|
||||||
|
String[] metricsNames = {"cpu_usage_idle", "cpu_usage_irq", "cpu_usage_system", "cpu_usage_user"};
|
||||||
|
assertConvertToSample(telegrafData, 6, metricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongSampleFamilySize() {
|
||||||
|
String threeMemMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"available\":6047739904,\"available_percent\":35.41215070500567,\"total\":17078149120,\"used\":11030409216,\"used_percent\":64.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":6047563904,\"available_percent\":56.41215070500567,\"total\":27048549120,\"used\":340364409216,\"used_percent\":44.58454929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663491390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":5047739904,\"available_percent\":43.41215070500567,\"total\":46078149120,\"used\":45030409216,\"used_percent\":23.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1453365320}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(threeMemMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 3, 1, metricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongSampleNumbersOfSampleFamily() {
|
||||||
|
String threeMemMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"available\":6047739904,\"available_percent\":35.41215070500567,\"total\":17078149120,\"used\":11030409216,\"used_percent\":64.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":6047563904,\"available_percent\":56.41215070500567,\"total\":27048549120,\"used\":340364409216,\"used_percent\":44.58454929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663491390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"available\":5047739904,\"available_percent\":43.41215070500567,\"total\":46078149120,\"used\":45030409216,\"used_percent\":23.58784929499433}," +
|
||||||
|
"\"name\":\"mem\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1453365320}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(threeMemMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 15, 2, metricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongSampleFamilySizeWithSameTimestamp() {
|
||||||
|
String fourCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":67.32710280373831,\"usage_irq\":0.5415264797507788,\"usage_system\":1.6533956386292835,\"usage_user\":76.54797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":74.32710280373831,\"usage_irq\":1.2535264797507788,\"usage_system\":4.5633956386292835,\"usage_user\":54.23797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":45.32710280373831,\"usage_irq\":0.4515344797507788,\"usage_system\":3.4533956386292835,\"usage_user\":45.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(fourCpuMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 3, 4, metricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongSampleNumbersOfSampleFamilyWithSameTimestamp() {
|
||||||
|
String fourCpuMetrics = "{\"metrics\":" +
|
||||||
|
"[{\"fields\":" +
|
||||||
|
"{\"usage_idle\":95.32710280373831,\"usage_irq\":0.3115264797507788,\"usage_system\":1.7133956386292835,\"usage_user\":2.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":67.32710280373831,\"usage_irq\":0.5415264797507788,\"usage_system\":1.6533956386292835,\"usage_user\":76.54797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":74.32710280373831,\"usage_irq\":1.2535264797507788,\"usage_system\":4.5633956386292835,\"usage_user\":54.23797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}, " +
|
||||||
|
"{\"fields\":" +
|
||||||
|
"{\"usage_idle\":45.32710280373831,\"usage_irq\":0.4515344797507788,\"usage_system\":3.4533956386292835,\"usage_user\":45.64797507788162}," +
|
||||||
|
"\"name\":\"cpu\"," +
|
||||||
|
"\"tags\":{\"host\":\"localHost\"}," +
|
||||||
|
"\"timestamp\":1663391390}]}";
|
||||||
|
|
||||||
|
Assert.assertThrows("Expected AssertionError to throw, but it didn't.",
|
||||||
|
AssertionError.class, () -> {
|
||||||
|
TelegrafData telegrafData = assertTelegrafJSONConvert(fourCpuMetrics);
|
||||||
|
String[] metricsNames = {"mem_available", "mem_available_percent", "mem_total", "mem_used", "mem_used_percent"};
|
||||||
|
assertConvertToSample(telegrafData, 5, metricsNames);
|
||||||
|
assertConvertToSampleFamily(telegrafData, 4, 2, metricsNames);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.mock;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleNotFoundRuntimeException;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleProviderHolder;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class MockModuleManager extends ModuleManager {
|
||||||
|
private final Map<String, ModuleProviderHolder> moduleProviderHolderMap = Maps.newHashMap();
|
||||||
|
|
||||||
|
public MockModuleManager() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void init();
|
||||||
|
|
||||||
|
protected void register(String name, ModuleProviderHolder provider) {
|
||||||
|
moduleProviderHolderMap.put(name, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(String moduleName) {
|
||||||
|
return moduleProviderHolderMap.containsKey(moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleProviderHolder find(String moduleName) throws ModuleNotFoundRuntimeException {
|
||||||
|
if (!moduleProviderHolderMap.containsKey(moduleName)) {
|
||||||
|
throw new ModuleNotFoundRuntimeException("ModuleProviderHolder[" + moduleName + "] cannot found in MOCK.");
|
||||||
|
}
|
||||||
|
return moduleProviderHolderMap.get(moduleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.skywalking.oap.server.receiver.telegraf.mock;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleServiceHolder;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.Service;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class MockModuleProvider implements ModuleServiceHolder {
|
||||||
|
protected Map<Class<? extends Service>, Service> serviceMap = Maps.newHashMap();
|
||||||
|
|
||||||
|
public MockModuleProvider() {
|
||||||
|
register();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void register();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerServiceImplementation(final Class<? extends Service> serviceType,
|
||||||
|
final Service service) throws ServiceNotProvidedException {
|
||||||
|
serviceMap.put(serviceType, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Service> T getService(final Class<T> serviceType) throws ServiceNotProvidedException {
|
||||||
|
return (T) serviceMap.get(serviceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
expSuffix: service(['host'], Layer.OS_LINUX)
|
||||||
|
metricPrefix: meter_vm
|
||||||
|
metricsRules:
|
||||||
|
|
||||||
|
# cpu
|
||||||
|
- name: cpu_total_percentage
|
||||||
|
exp: cpu_usage_active.tagEqual('cpu', 'cpu-total')
|
||||||
|
- name: cpu_average_used
|
||||||
|
exp: cpu_usage_active.tagNotEqual('cpu', 'cpu-total').avg(['host', 'cpu'])
|
||||||
|
- name: cpu_load1
|
||||||
|
exp: system_load1
|
||||||
|
- name: cpu_load5
|
||||||
|
exp: system_load5
|
||||||
|
- name: cpu_load15
|
||||||
|
exp: system_load15
|
||||||
|
|
||||||
|
# memory
|
||||||
|
- name: memory_total
|
||||||
|
exp: mem_total
|
||||||
|
- name: memory_available
|
||||||
|
exp: mem_available
|
||||||
|
- name: memory_used
|
||||||
|
exp: mem_used
|
||||||
|
|
||||||
|
# swap
|
||||||
|
- name: memory_swap_free
|
||||||
|
exp: mem_swap_free
|
||||||
|
- name: memory_swap_total
|
||||||
|
exp: mem_swap_total
|
||||||
|
- name: memory_swap_percentage
|
||||||
|
exp: 100 - ((mem_swap_free / mem_swap_total) * 100)
|
||||||
|
|
||||||
|
#node filesystem
|
||||||
|
- name: filesystem_percentage
|
||||||
|
exp: disk_used_percent.avg(['host','device'])
|
||||||
|
|
||||||
|
#node disk
|
||||||
|
- name: disk_read
|
||||||
|
exp: diskio_read_bytes.rate('PT1M')
|
||||||
|
- name: disk_written
|
||||||
|
exp: diskio_write_bytes.rate('PT1M')
|
||||||
|
|
||||||
|
#node net
|
||||||
|
- name: network_receive
|
||||||
|
exp: net_bytes_recv.irate()
|
||||||
|
- name: network_transmit
|
||||||
|
exp: net_bytes_sent.irate()
|
||||||
|
|
||||||
|
#node netstat
|
||||||
|
- name: tcp_curr_estab
|
||||||
|
exp: netstat_tcp_established
|
||||||
|
- name: tcp_tw
|
||||||
|
exp: netstat_tcp_time_wait
|
||||||
|
- name: tcp_alloc
|
||||||
|
exp: netstat_tcp_listen
|
||||||
|
- name: udp_inuse
|
||||||
|
exp: netstat_udp_socket
|
||||||
|
|
@ -166,6 +166,11 @@
|
||||||
<artifactId>skywalking-ebpf-receiver-plugin</artifactId>
|
<artifactId>skywalking-ebpf-receiver-plugin</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>skywalking-telegraf-receiver-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- receiver module -->
|
<!-- receiver module -->
|
||||||
|
|
||||||
<!-- fetcher module -->
|
<!-- fetcher module -->
|
||||||
|
|
@ -314,6 +319,7 @@
|
||||||
<exclude>zabbix-rules/</exclude>
|
<exclude>zabbix-rules/</exclude>
|
||||||
<exclude>lal/</exclude>
|
<exclude>lal/</exclude>
|
||||||
<exclude>log-mal-rules/</exclude>
|
<exclude>log-mal-rules/</exclude>
|
||||||
|
<exclude>telegraf-rules/</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
||||||
|
|
@ -536,3 +536,8 @@ receiver-event:
|
||||||
receiver-ebpf:
|
receiver-ebpf:
|
||||||
selector: ${SW_RECEIVER_EBPF:default}
|
selector: ${SW_RECEIVER_EBPF:default}
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
receiver-telegraf:
|
||||||
|
selector: ${SW_RECEIVER_TELEGRAF:default}
|
||||||
|
default:
|
||||||
|
activeFiles: ${SW_RECEIVER_TELEGRAF_ACTIVE_FILES:vm}
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
expSuffix: service(['host'], Layer.OS_LINUX)
|
||||||
|
metricPrefix: meter_vm
|
||||||
|
metricsRules:
|
||||||
|
|
||||||
|
# cpu
|
||||||
|
- name: cpu_total_percentage
|
||||||
|
exp: cpu_usage_active.tagEqual('cpu', 'cpu-total')
|
||||||
|
- name: cpu_average_used
|
||||||
|
exp: cpu_usage_active.tagNotEqual('cpu', 'cpu-total').avg(['host', 'cpu'])
|
||||||
|
- name: cpu_load1
|
||||||
|
exp: system_load1
|
||||||
|
- name: cpu_load5
|
||||||
|
exp: system_load5
|
||||||
|
- name: cpu_load15
|
||||||
|
exp: system_load15
|
||||||
|
|
||||||
|
# memory
|
||||||
|
- name: memory_total
|
||||||
|
exp: mem_total
|
||||||
|
- name: memory_available
|
||||||
|
exp: mem_available
|
||||||
|
- name: memory_used
|
||||||
|
exp: mem_used
|
||||||
|
|
||||||
|
# swap
|
||||||
|
- name: memory_swap_free
|
||||||
|
exp: mem_swap_free
|
||||||
|
- name: memory_swap_total
|
||||||
|
exp: mem_swap_total
|
||||||
|
- name: memory_swap_percentage
|
||||||
|
exp: 100 - ((mem_swap_free / mem_swap_total) * 100)
|
||||||
|
|
||||||
|
#node filesystem
|
||||||
|
- name: filesystem_percentage
|
||||||
|
exp: disk_used_percent.avg(['host','device'])
|
||||||
|
|
||||||
|
#node disk
|
||||||
|
- name: disk_read
|
||||||
|
exp: diskio_read_bytes.rate('PT1M')
|
||||||
|
- name: disk_written
|
||||||
|
exp: diskio_write_bytes.rate('PT1M')
|
||||||
|
|
||||||
|
#node net
|
||||||
|
- name: network_receive
|
||||||
|
exp: net_bytes_recv.irate()
|
||||||
|
- name: network_transmit
|
||||||
|
exp: net_bytes_sent.irate()
|
||||||
|
|
||||||
|
#node netstat
|
||||||
|
- name: tcp_curr_estab
|
||||||
|
exp: netstat_tcp_established
|
||||||
|
- name: tcp_tw
|
||||||
|
exp: netstat_tcp_time_wait
|
||||||
|
- name: tcp_alloc
|
||||||
|
exp: netstat_tcp_listen
|
||||||
|
- name: udp_inuse
|
||||||
|
exp: netstat_udp_socket
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
# 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
|
||||||
|
environment:
|
||||||
|
SW_RECEIVER_TELEGRAF: default
|
||||||
|
SW_RECEIVER_TELEGRAF_ACTIVE_FILES: vm
|
||||||
|
ports:
|
||||||
|
- 12800
|
||||||
|
|
||||||
|
telegraf:
|
||||||
|
image: telegraf:1.24
|
||||||
|
networks:
|
||||||
|
- e2e
|
||||||
|
volumes:
|
||||||
|
- ./telegraf.conf:/etc/telegraf/telegraf.conf
|
||||||
|
depends_on:
|
||||||
|
oap:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
e2e:
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
# contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright ownership.
|
||||||
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
# (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# 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: 20
|
||||||
|
interval: 3s
|
||||||
|
cases:
|
||||||
|
# service list
|
||||||
|
- query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql service ls
|
||||||
|
expected: ../expected/service.yml
|
||||||
|
# linear metrics
|
||||||
|
- query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=meter_vm_memory_used --service-name=vm-service |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_vm_memory_total --service-name=vm-service |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_vm_memory_available --service-name=vm-service |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_vm_cpu_total_percentage --service-name=vm-service |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_vm_cpu_load1 --service-name=vm-service |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_vm_cpu_load5 --service-name=vm-service |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_vm_cpu_load15 --service-name=vm-service |yq e 'to_entries' -
|
||||||
|
expected: ../expected/metrics-has-value.yml
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
# Global tags can be specified here in key="value" format.
|
||||||
|
[global_tags]
|
||||||
|
# dc = "us-east-1" # will tag all metrics with dc=us-east-1
|
||||||
|
# rack = "1a"
|
||||||
|
## Environment variables can be used as tags, and throughout the config file
|
||||||
|
# user = "$USER"
|
||||||
|
|
||||||
|
|
||||||
|
# Configuration for telegraf agent
|
||||||
|
[agent]
|
||||||
|
## Default data collection interval for all inputs
|
||||||
|
interval = "10s"
|
||||||
|
## Rounds collection interval to 'interval'
|
||||||
|
## ie, if interval="10s" then always collect on :00, :10, :20, etc.
|
||||||
|
round_interval = true
|
||||||
|
|
||||||
|
## Telegraf will send metrics to outputs in batches of at most
|
||||||
|
## metric_batch_size metrics.
|
||||||
|
## This controls the size of writes that Telegraf sends to output plugins.
|
||||||
|
metric_batch_size = 1000
|
||||||
|
|
||||||
|
## Maximum number of unwritten metrics per output. Increasing this value
|
||||||
|
## allows for longer periods of output downtime without dropping metrics at the
|
||||||
|
## cost of higher maximum memory usage.
|
||||||
|
metric_buffer_limit = 10000
|
||||||
|
|
||||||
|
## Collection jitter is used to jitter the collection by a random amount.
|
||||||
|
## Each plugin will sleep for a random time within jitter before collecting.
|
||||||
|
## This can be used to avoid many plugins querying things like sysfs at the
|
||||||
|
## same time, which can have a measurable effect on the system.
|
||||||
|
collection_jitter = "0s"
|
||||||
|
|
||||||
|
## Collection offset is used to shift the collection by the given amount.
|
||||||
|
## This can be be used to avoid many plugins querying constraint devices
|
||||||
|
## at the same time by manually scheduling them in time.
|
||||||
|
# collection_offset = "0s"
|
||||||
|
|
||||||
|
## Default flushing interval for all outputs. Maximum flush_interval will be
|
||||||
|
## flush_interval + flush_jitter
|
||||||
|
flush_interval = "3s"
|
||||||
|
## Jitter the flush interval by a random amount. This is primarily to avoid
|
||||||
|
## large write spikes for users running a large number of telegraf instances.
|
||||||
|
## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
|
||||||
|
flush_jitter = "0s"
|
||||||
|
|
||||||
|
## Collected metrics are rounded to the precision specified. Precision is
|
||||||
|
## specified as an interval with an integer + unit (e.g. 0s, 10ms, 2us, 4s).
|
||||||
|
## Valid time units are "ns", "us" (or "µs"), "ms", "s".
|
||||||
|
##
|
||||||
|
## By default or when set to "0s", precision will be set to the same
|
||||||
|
## timestamp order as the collection interval, with the maximum being 1s:
|
||||||
|
## ie, when interval = "10s", precision will be "1s"
|
||||||
|
## when interval = "250ms", precision will be "1ms"
|
||||||
|
##
|
||||||
|
## Precision will NOT be used for service inputs. It is up to each individual
|
||||||
|
## service input to set the timestamp at the appropriate precision.
|
||||||
|
precision = "0s"
|
||||||
|
|
||||||
|
## Override default hostname, if empty use os.Hostname()
|
||||||
|
hostname = "vm-service"
|
||||||
|
## If set to true, do no set the "host" tag in the telegraf agent.
|
||||||
|
omit_hostname = false
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OUTPUT PLUGINS #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# # A plugin that can transmit metrics over HTTP
|
||||||
|
[[outputs.http]]
|
||||||
|
# ## URL is the address to send metrics to
|
||||||
|
url = "http://oap:12800/telegraf"
|
||||||
|
#
|
||||||
|
# ## Timeout for HTTP message
|
||||||
|
timeout = "10s"
|
||||||
|
#
|
||||||
|
# ## HTTP method, one of: "POST" or "PUT"
|
||||||
|
method = "POST"
|
||||||
|
#
|
||||||
|
# ## Data format to output.
|
||||||
|
# ## Each data format has it's own unique set of configuration options, read
|
||||||
|
# ## more about them here:
|
||||||
|
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
|
||||||
|
data_format = "json"
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# INPUT PLUGINS #
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
[[outputs.file]]
|
||||||
|
## Files to write to, "stdout" is a specially handled file.
|
||||||
|
files = ["stdout", "/tmp/metrics.out"]
|
||||||
|
|
||||||
|
# Read metrics about cpu usage
|
||||||
|
[[inputs.cpu]]
|
||||||
|
## Whether to report per-cpu stats or not
|
||||||
|
percpu = true
|
||||||
|
## Whether to report total system cpu stats or not
|
||||||
|
totalcpu = true
|
||||||
|
## If true, collect raw CPU time metrics
|
||||||
|
collect_cpu_time = false
|
||||||
|
## If true, compute and report the sum of all non-idle CPU states
|
||||||
|
report_active = true
|
||||||
|
|
||||||
|
|
||||||
|
# Read metrics about memory usage
|
||||||
|
[[inputs.mem]]
|
||||||
|
# no configuration
|
||||||
|
|
||||||
|
|
||||||
|
[[inputs.system]]
|
||||||
|
# no configuration
|
||||||
|
|
||||||
|
[[inputs.disk]]
|
||||||
|
# no configuration
|
||||||
|
|
||||||
|
[[inputs.diskio]]
|
||||||
|
# no configuration
|
||||||
|
|
||||||
|
[[inputs.net]]
|
||||||
|
## By default, telegraf gathers stats from any up interface (excluding loopback)
|
||||||
|
## Setting interfaces will tell it to gather these explicit interfaces,
|
||||||
|
## regardless of status. When specifying an interface, glob-style
|
||||||
|
## patterns are also supported.
|
||||||
|
##
|
||||||
|
# interfaces = ["eth*", "enp0s[0-1]", "lo"]
|
||||||
|
##
|
||||||
|
## On linux systems telegraf also collects protocol stats.
|
||||||
|
## Setting ignore_protocol_stats to true will skip reporting of protocol metrics.
|
||||||
|
##
|
||||||
|
# ignore_protocol_stats = false
|
||||||
|
##
|
||||||
|
|
||||||
|
[[inputs.netstat]]
|
||||||
Loading…
Reference in New Issue