Skip to content

Commit

Permalink
support and expose inner metrics data (#737)
Browse files Browse the repository at this point in the history
  [manager] support inner metrics data api

  [manager] export inner metrics data api
  • Loading branch information
tomsun28 authored Mar 15, 2023
1 parent 6308ece commit 5aca895
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -417,28 +417,15 @@ private void parseResponseByDefault(String resp, List<String> aliasFields, HttpP
if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
for (JsonElement jsonElement : array) {
if (jsonElement.isJsonObject()) {
JsonObject object = jsonElement.getAsJsonObject();
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
JsonElement valueElement = object.get(alias);
if (valueElement != null) {
String value = valueElement.getAsString();
valueRowBuilder.addColumns(value);
} else {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
}
builder.addValues(valueRowBuilder.build());
}
getValueFromJson(aliasFields, builder, responseTime, jsonElement, keywordNum);
}
} else if (element.isJsonObject()) {
} else {
getValueFromJson(aliasFields, builder, responseTime, element, keywordNum);
}
}

private void getValueFromJson(List<String> aliasFields, CollectRep.MetricsData.Builder builder, Long responseTime, JsonElement element, int keywordNum) {
if (element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
Expand All @@ -447,7 +434,13 @@ private void parseResponseByDefault(String resp, List<String> aliasFields, HttpP
String value = valueElement.getAsString();
valueRowBuilder.addColumns(value);
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
}
builder.addValues(valueRowBuilder.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

Expand All @@ -51,6 +53,15 @@ public InMemoryCommonDataQueue() {
metricsDataToMemoryStorageQueue = new LinkedBlockingQueue<>();
}

public Map<String, Integer> getQueueSizeMetricsInfo() {
Map<String, Integer> metrics = new HashMap<>(8);
metrics.put("alertDataQueue", alertDataQueue.size());
metrics.put("metricsDataToAlertQueue", metricsDataToAlertQueue.size());
metrics.put("metricsDataToPersistentStorageQueue", metricsDataToPersistentStorageQueue.size());
metrics.put("metricsDataToMemoryStorageQueue", metricsDataToMemoryStorageQueue.size());
return metrics;
}

@Override
public void addAlertData(Alert alert) {
alertDataQueue.offer(alert);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 com.usthe.manager.controller;

import com.usthe.common.entity.dto.Message;
import com.usthe.common.queue.CommonDataQueue;
import com.usthe.common.queue.impl.InMemoryCommonDataQueue;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
* hertzbeat metrics exporter
* @author tom
* @date 2022/03/14 21:40
*/
@Tag(name = "Inner Metrics Exporter API | 内部监控指标API")
@RestController
@RequestMapping(path = "/api/metrics", produces = {APPLICATION_JSON_VALUE})
public class MetricsController {

@Autowired
private CommonDataQueue commonDataQueue;

@GetMapping()
@Operation(summary = "Get Hertzbeat Metrics Data")
public ResponseEntity<Message<Map<String, Object>>> getMetricsInfo() {
Map<String, Object> metricsInfo = new HashMap<>(8);
if (commonDataQueue instanceof InMemoryCommonDataQueue) {
Map<String, Integer> queueInfo = ((InMemoryCommonDataQueue) commonDataQueue).getQueueSizeMetricsInfo();
metricsInfo.putAll(queueInfo);
}
return ResponseEntity.ok(new Message<>(metricsInfo));
}
}
4 changes: 2 additions & 2 deletions manager/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ management:
endpoints:
web:
exposure:
include: '*'
enabled-by-default: off
include: 'metrics'
enabled-by-default: on

sureness:
auths:
Expand Down
131 changes: 128 additions & 3 deletions manager/src/main/resources/define/app-hertzbeat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ metrics:
# 指标组中的具体监控指标
fields:
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
- field: responseTime
type: 0
unit: ms
- field: app
type: 1
instance: true
Expand Down Expand Up @@ -125,3 +122,131 @@ metrics:
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控,我们这里使用jsonpath来解析响应数据
parseType: jsonPath
parseScript: '$.data.apps.*'

- name: inner_queue
priority: 1
fields:
- field: responseTime
type: 0
unit: ms
- field: alertDataQueue
type: 0
- field: metricsDataToAlertQueue
type: 0
- field: metricsDataToPersistentStorageQueue
type: 0
- field: metricsDataToMemoryStorageQueue
type: 0
protocol: http
http:
host: ^_^host^_^
port: ^_^port^_^
url: /api/metrics
timeout: ^_^timeout^_^
method: GET
ssl: ^_^ssl^_^
parseType: jsonPath
parseScript: '$.data'

- name: thread_state
visible: false
priority: 1
fields:
- field: state
type: 1
protocol: http
http:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
# url请求接口路径
url: /actuator/metrics/jvm.threads.states
# 请求方式 GET POST PUT DELETE PATCH
method: GET
# 是否启用ssl/tls,即是http还是https,默认false
ssl: ^_^ssl^_^
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-api可用性指标监控
parseType: jsonPath
parseScript: '$.availableTags[?(@.tag == "state")].values[*]'

- name: threads
priority: 2
fields:
- field: state
type: 1
- field: number
type: 0
aliasFields:
- $.measurements[?(@.statistic == "VALUE")].value
calculates:
- state='^o^state^o^'
- number=#`$.measurements[?(@.statistic == "VALUE")].value`
protocol: http
http:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
# url请求接口路径
url: /actuator/metrics/jvm.threads.states?tag=state:^o^state^o^
# 请求方式 GET POST PUT DELETE PATCH
method: GET
# 是否启用ssl/tls,即是http还是https,默认false
ssl: ^_^ssl^_^
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-api可用性指标监控
parseType: jsonPath
parseScript: '$'

- name: space_name
visible: false
priority: 3
fields:
- field: id
type: 1
protocol: http
http:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
# url请求接口路径
url: /actuator/metrics/jvm.memory.used
# 请求方式 GET POST PUT DELETE PATCH
method: GET
# 是否启用ssl/tls,即是http还是https,默认false
ssl: ^_^ssl^_^
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-api可用性指标监控
parseType: jsonPath
parseScript: '$.availableTags[?(@.tag == "id")].values[*]'

- name: memory_used
priority: 4
fields:
- field: space
type: 1
- field: mem_used
type: 0
unit: MB
aliasFields:
- $.measurements[?(@.statistic == "VALUE")].value
calculates:
- space="^o^id^o^"
- mem_used=#`$.measurements[?(@.statistic == "VALUE")].value`
units:
- mem_used=B->MB
protocol: http
http:
# 主机host: ipv4 ipv6 域名
host: ^_^host^_^
# 端口
port: ^_^port^_^
# url请求接口路径
url: /actuator/metrics/jvm.memory.used?tag=id:^o^id^o^
# 请求方式 GET POST PUT DELETE PATCH
method: GET
# 是否启用ssl/tls,即是http还是https,默认false
ssl: ^_^ssl^_^
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-api可用性指标监控
parseType: jsonPath
parseScript: '$'
Loading

0 comments on commit 5aca895

Please sign in to comment.