Compare commits

..
Author SHA1 Message Date
tomsun28 bf21538062 [improve] common metric data query design
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-02-28 16:36:19 +08:00
tomsun28 3688974610 [bugfix] fix alert sse illegal state exception (#3106) 2025-02-25 15:27:53 +08:00
af35043663 [feature] adding-ptBR-translation (#3098)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-25 09:37:21 +08:00
Jastandshown 84c28229b2 [Feature] Add deepseek Api Monitor (#3096)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-02-24 15:39:53 +08:00
tomsun28 1a3e614209 [webapp] fix web oom crash when backend api can not access (#3100) 2025-02-23 21:22:37 +08:00
Jast 3df0e56da9 [Improve] Message notification prompt optimization (#3095) 2025-02-23 21:19:10 +08:00
Jast b5b4771e1a [Doc]Improve openai doc (#3097) 2025-02-22 10:30:25 +08:00
b8c5ae4d40 [bugfix] kafka client detect error (#3088)
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-21 22:05:12 +08:00
淞筱 207f2d958c [doc] correct home's new_committer_process (#3094) 2025-02-21 20:59:51 +08:00
20 changed files with 1486 additions and 40 deletions
@@ -19,6 +19,7 @@
package org.apache.hertzbeat.alert.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@@ -30,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* SSE manager for alert
*/
@Slf4j
@Component
public class AlertSseManager {
private final Map<Long, SseEmitter> emitters = new ConcurrentHashMap<>();
@@ -38,6 +40,7 @@ public class AlertSseManager {
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
emitter.onCompletion(() -> removeEmitter(clientId));
emitter.onTimeout(() -> removeEmitter(clientId));
emitter.onError((ex) -> removeEmitter(clientId));
emitters.put(clientId, emitter);
return emitter;
}
@@ -50,7 +53,11 @@ public class AlertSseManager {
.id(String.valueOf(System.currentTimeMillis()))
.name("ALERT_EVENT")
.data(data));
} catch (IOException e) {
} catch (IOException | IllegalStateException e) {
emitter.complete();
removeEmitter(clientId);
} catch (Exception exception) {
log.error("Failed to broadcast alert data to client: {}", exception.getMessage());
emitter.complete();
removeEmitter(clientId);
}
@@ -60,4 +67,4 @@ public class AlertSseManager {
private void removeEmitter(Long clientId) {
emitters.remove(clientId);
}
}
}
@@ -267,6 +267,8 @@ public class KafkaCollectImpl extends AbstractCollect {
break;
}
} catch (InterruptedException | ExecutionException e) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Kafka collect error: " + e.getMessage());
log.error("Kafka collect error", e);
}
}
@@ -0,0 +1,81 @@
/*
* 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.hertzbeat.common.entity.dto.query;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Metric History Range Query Data
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "Metric Query Data")
public class MetricQueryData {
@Schema(title = "Metric Schema")
private MetricSchema schema;
@Schema(title = "metrics row values, first is the timestamp-ts", example = "[[29,32,44],[32,34,true]]")
private List<List<Object>> values;
/**
* Metric Schema
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static final class MetricSchema {
@Schema(title = "Metrics Field")
private List<MetricField> fields;
@Schema(title = "Meta Information")
private Map<String, String> meta;
}
/**
* Metric Field
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static final class MetricField {
@Schema(title = "Metric Field Name")
private String name;
@Schema(title = "Field Type: number, string, time, bool")
private String type;
@Schema(title = "Field Unit: %, Mb, Kbps etc.")
private String unit;
@Schema(title = "Whether is a label")
private Boolean label;
}
}
@@ -0,0 +1,100 @@
# 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.
# The monitoring type categoryservice-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
category: llm
# The monitoring type eg: linux windows tomcat mysql aws...
app: deepseek
# The monitoring i18n name
name:
zh-CN: Deepseek
en-US: Deepseek
# The description and help of this monitoring type
help:
zh-CN: Hertzbeat 对 Deepseek Api进行测量监控。<br>您可以点击 “<i>新建 Deepseek</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
en-US: Hertzbeat monitors Deepseek Api. You could click the "<i>New Deepseek</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
zh-TW: Hertzbeat對Deepseek Api進行量測監控。<br>您可以點擊“<i>Deepseek</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
helpLink:
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/deepseek
en-US: https://hertzbeat.apache.org/docs/help/deepseek
# Input params define for monitoring(render web ui by the definition)
params:
# field-param field key
- field: token
# name-param field display i18n name
name:
zh-CN: 会话密钥
en-US: Session Key
# type-param field type(most mapping the html input type)
type: text
# required-true or false
required: true
# collect metrics config list
metrics:
# metrics - auth
- name: billing
i18n:
zh-CN: 计费
en-US: Billing
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
priority: 0
# collect metrics content
fields:
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
- field: currency
type: 1
i18n:
zh-CN: 货币
en-US: Currency
- field: total_balance
type: 0
i18n:
zh-CN: 可用余额
en-US: Available Balance
- field: granted_balance
type: 0
i18n:
zh-CN: 未过期的赠金余额
en-US: Unexpired Gift Balance
- field: topped_up_balance
type: 0
i18n:
zh-CN: 充值的余额
en-US: Topped Up Balance
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
protocol: http
# the config content when protocol is http
http:
# http host: ipv4 ipv6 domain
host: api.deepseek.com
# http port
port: 443
# http url
url: /user/balance
# http method: GET POST PUT DELETE PATCH
method: GET
# if enabled https
ssl: true
# http auth
authorization:
# http auth type: Basic Auth, Digest Auth, Bearer Token
type: Bearer Token
bearerTokenToken: ^_^token^_^
# http response data parse type: default-hertzbeat rule, jsonpath-jsonpath script, website-for website monitoring, prometheus-prometheus exporter rule
parseType: jsonPath
parseScript: '$.balance_infos.*'
@@ -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.
*/
package org.apache.hertzbeat.warehouse.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
import org.apache.hertzbeat.warehouse.service.MetricsDataQueryService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Metrics Data Query API
*/
@RestController
@RequestMapping(produces = {APPLICATION_JSON_VALUE})
@Tag(name = "Metrics Data Query API")
public class MetricsDataQueryController {
@Autowired
private MetricsDataQueryService queryService;
@GetMapping("/api/warehouse/query")
@Operation(summary = "Query Real Time Metrics Data")
public ResponseEntity<Message<List<MetricQueryData>>> queryMetricsData(
@Parameter(description = "Query PromQL expr list", example = "cpu")
@RequestParam List<String> queries,
@Parameter(description = "Query timestamp", example = "1725854804451")
@RequestParam long time) {
return ResponseEntity.ok(Message.success(queryService.query(queries, time)));
}
@GetMapping("/api/warehouse/query/range")
@Operation(summary = "Query Range Metrics Data")
public ResponseEntity<Message<List<MetricQueryData>>> queryMetricsDataRange(
@Parameter(description = "Query PromQL expr list", example = "cpu")
@RequestParam List<String> queries,
@Parameter(description = "Query start timestamp", example = "1725854804451")
@RequestParam long start,
@Parameter(description = "Query end timestamp", example = "1733630804452")
@RequestParam long end,
@Parameter(description = "Query step", example = "4m")
@RequestParam String step
) {
return ResponseEntity.ok(Message.success(queryService.queryRange(queries, start, end, step)));
}
}
@@ -0,0 +1,45 @@
/*
* 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.hertzbeat.warehouse.service;
import java.util.List;
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
/**
* metrics data query service
*/
public interface MetricsDataQueryService {
/**
* Query metrics data
* @param queries query expr
* @param time time
* @return data
*/
List<MetricQueryData> query(List<String> queries, long time);
/**
* Query metrics data range
* @param queries query expr
* @param start start
* @param end end
* @param step step
* @return data
*/
List<MetricQueryData> queryRange(List<String> queries, long start, long end, String step);
}
@@ -0,0 +1,282 @@
/*
* 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.hertzbeat.warehouse.service.impl.greptime;
import io.greptime.GreptimeDB;
import io.greptime.models.AuthInfo;
import io.greptime.models.DataType;
import io.greptime.models.Err;
import io.greptime.models.Result;
import io.greptime.models.Table;
import io.greptime.models.TableSchema;
import io.greptime.models.WriteOk;
import io.greptime.options.GreptimeOptions;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.dto.Value;
import org.apache.hertzbeat.common.entity.dto.query.MetricQueryData;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.hertzbeat.common.util.TimePeriodUtil;
import org.apache.hertzbeat.warehouse.service.MetricsDataQueryService;
import org.apache.hertzbeat.warehouse.store.history.greptime.GreptimeProperties;
import org.apache.hertzbeat.warehouse.store.history.vm.PromQlQueryContent;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/**
* GreptimeDB data storage, only supports GreptimeDB version >= v0.5
*/
@Component
@ConditionalOnProperty(prefix = "warehouse.store.greptime", name = "enabled", havingValue = "true")
@Slf4j
public class GreptimeDbStorage implements MetricsDataQueryService, DisposableBean {
private static final String BASIC = "Basic";
private static final String QUERY_RANGE_PATH = "/v1/prometheus/api/v1/query_range";
private static final String LABEL_KEY_NAME = "__name__";
private static final String LABEL_KEY_FIELD = "__field__";
private static final String LABEL_KEY_INSTANCE = "instance";
private static final String SPILT = "_";
private GreptimeDB greptimeDb;
private final GreptimeProperties greptimeProperties;
private final RestTemplate restTemplate;
public GreptimeDbStorage(GreptimeProperties greptimeProperties, RestTemplate restTemplate) {
if (greptimeProperties == null) {
log.error("init error, please config Warehouse GreptimeDB props in application.yml");
throw new IllegalArgumentException("please config Warehouse GreptimeDB props");
}
this.restTemplate = restTemplate;
this.greptimeProperties = greptimeProperties;
initGreptimeDbClient(greptimeProperties);
}
private void initGreptimeDbClient(GreptimeProperties greptimeProperties) {
String endpoints = greptimeProperties.grpcEndpoints();
GreptimeOptions opts = GreptimeOptions.newBuilder(endpoints.split(","), greptimeProperties.database())
.writeMaxRetries(3)
.authInfo(new AuthInfo(greptimeProperties.username(), greptimeProperties.password()))
.routeTableRefreshPeriodSeconds(30)
.build();
this.greptimeDb = GreptimeDB.create(opts);
}
public void saveData(CollectRep.MetricsData metricsData) {
if (metricsData.getCode() != CollectRep.Code.SUCCESS) {
return;
}
if (metricsData.getValuesList().isEmpty()) {
log.info("[warehouse greptime] flush metrics data {} {} is null, ignore.", metricsData.getId(), metricsData.getMetrics());
return;
}
String monitorId = String.valueOf(metricsData.getId());
String tableName = getTableName(metricsData.getApp(), metricsData.getMetrics());
TableSchema.Builder tableSchemaBuilder = TableSchema.newBuilder(tableName);
tableSchemaBuilder.addTag("instance", DataType.String)
.addTimestamp("ts", DataType.TimestampMillisecond);
List<CollectRep.Field> fieldsList = metricsData.getFieldsList();
for (CollectRep.Field field : fieldsList) {
// handle field type
if (field.getLabel()) {
tableSchemaBuilder.addTag(field.getName(), DataType.String);
} else {
if (field.getType() == CommonConstants.TYPE_NUMBER) {
tableSchemaBuilder.addField(field.getName(), DataType.Float64);
} else if (field.getType() == CommonConstants.TYPE_STRING) {
tableSchemaBuilder.addField(field.getName(), DataType.String);
}
}
}
Table table = Table.from(tableSchemaBuilder.build());
try {
long now = System.currentTimeMillis();
Object[] values = new Object[2 + fieldsList.size()];
values[0] = monitorId;
values[1] = now;
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
for (int i = 0; i < fieldsList.size(); i++) {
if (!CommonConstants.NULL_VALUE.equals(valueRow.getColumns(i))) {
CollectRep.Field field = fieldsList.get(i);
if (field.getLabel()) {
values[2 + i] = valueRow.getColumns(i);
} else {
if (field.getType() == CommonConstants.TYPE_NUMBER) {
values[2 + i] = Double.parseDouble(valueRow.getColumns(i));
} else if (field.getType() == CommonConstants.TYPE_STRING) {
values[2 + i] = valueRow.getColumns(i);
}
}
} else {
values[2 + i] = null;
}
}
table.addRow(values);
}
CompletableFuture<Result<WriteOk, Err>> writeFuture = greptimeDb.write(table);
try {
Result<WriteOk, Err> result = writeFuture.get(10, TimeUnit.SECONDS);
if (result.isOk()) {
log.debug("[warehouse greptime]-Write successful");
} else {
log.warn("[warehouse greptime]--Write failed: {}", result.getErr());
}
} catch (Throwable throwable) {
log.error("[warehouse greptime]--Error occurred: {}", throwable.getMessage());
}
} catch (Exception e) {
log.error("[warehouse greptime]--Error: {}", e.getMessage(), e);
}
}
public Map<String, List<Value>> getHistoryMetricData(Long monitorId, String app, String metrics, String metric,
String label, String history) {
String name = getTableName(app, metrics);
String timeSeriesSelector = LABEL_KEY_NAME + "=\"" + name + "\""
+ "," + LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"";
if (!CommonConstants.PROMETHEUS.equals(app)) {
timeSeriesSelector = timeSeriesSelector + "," + LABEL_KEY_FIELD + "=\"" + metric + "\"";
}
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
if (StringUtils.hasText(greptimeProperties.username())
&& StringUtils.hasText(greptimeProperties.password())) {
String authStr = greptimeProperties.username() + ":" + greptimeProperties.password();
String encodedAuth = new String(Base64.encodeBase64(authStr.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
headers.add(HttpHeaders.AUTHORIZATION, BASIC + " " + encodedAuth);
}
Instant now = Instant.now();
long start;
try {
if (NumberUtils.isParsable(history)) {
start = NumberUtils.toLong(history);
start = (ZonedDateTime.now().toEpochSecond() - start);
} else {
TemporalAmount temporalAmount = TimePeriodUtil.parseTokenTime(history);
assert temporalAmount != null;
Instant dateTime = now.minus(temporalAmount);
start = dateTime.getEpochSecond();
}
} catch (Exception e) {
log.error("history time error: {}. use default: 6h", e.getMessage());
start = now.minus(6, ChronoUnit.HOURS).getEpochSecond();
}
long end = now.getEpochSecond();
String step = "60s";
if (end - start < Duration.ofDays(7).getSeconds() && end - start > Duration.ofDays(1).getSeconds()) {
step = "1h";
} else if (end - start >= Duration.ofDays(7).getSeconds()) {
step = "4h";
}
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
URI uri = UriComponentsBuilder.fromHttpUrl(greptimeProperties.httpEndpoint() + QUERY_RANGE_PATH)
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8), URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
.queryParam("start", start)
.queryParam("end", end)
.queryParam("step", step)
.build(true).toUri();
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri,
HttpMethod.GET, httpEntity, PromQlQueryContent.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
log.debug("query metrics data from victoria-metrics success. {}", uri);
if (responseEntity.getBody() != null && responseEntity.getBody().getData() != null
&& responseEntity.getBody().getData().getResult() != null) {
List<PromQlQueryContent.ContentData.Content> contents = responseEntity.getBody().getData().getResult();
for (PromQlQueryContent.ContentData.Content content : contents) {
Map<String, String> labels = content.getMetric();
labels.remove(LABEL_KEY_NAME);
labels.remove(LABEL_KEY_INSTANCE);
String labelStr = JsonUtil.toJson(labels);
if (content.getValues() != null && !content.getValues().isEmpty()) {
List<Value> valueList = instanceValuesMap.computeIfAbsent(labelStr, k -> new LinkedList<>());
for (Object[] valueArr : content.getValues()) {
long timestamp = ((Double) valueArr[0]).longValue();
String value = new BigDecimal(String.valueOf(valueArr[1])).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
// read timestamp here is s unit
valueList.add(new Value(value, timestamp * 1000));
}
}
}
}
} else {
log.error("query metrics data from greptime failed. {}", responseEntity);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return instanceValuesMap;
}
private String getTableName(String app, String metrics) {
return app + SPILT + metrics;
}
@Override
public void destroy() {
if (this.greptimeDb != null) {
this.greptimeDb.shutdownGracefully();
this.greptimeDb = null;
}
}
@Override
public List<MetricQueryData> query(List<String> queries, long time) {
return List.of();
}
@Override
public List<MetricQueryData> queryRange(List<String> queries, long start, long end, String step) {
return List.of();
}
}
+35
View File
@@ -0,0 +1,35 @@
---
id: deepseek
title: Monitoring Deepseek Account Status
sidebar_label: Deepseek Account Status
keywords: [Open Source Monitoring System, Open Source Network Monitoring, Deepseek Account Monitoring]
---
### Preparation
#### Obtain Session Key
Log in to the Deepseek backend and visit the `https://platform.deepseek.com/api_keys` page to obtain the session key.
### Configuration Parameters
| Parameter Name | Parameter Description |
| ------------- | --------------------- |
| Monitoring Host | Enter `api.deepseek.com` here. |
| Task Name | The name that identifies this monitoring task, which must be unique. |
| Session Key | The session key obtained in the preparation step. |
| Collector | Configure which collector is used to schedule data collection for this monitoring. |
| Monitoring Interval | The interval for periodically collecting data, in seconds. The minimum interval that can be set is 30 seconds. |
| Bound Tags | Tags for categorizing and managing monitoring resources. |
| Description/Remarks | Additional remarks to identify and describe this monitoring. Users can add notes here. |
### Collection Metrics
#### Metric Set: Billing
| Metric Name | Metric Unit | Metric Description |
| ---------- | ---------- | ----------------- |
| Currency | None | Currency, either RMB or USD. |
| Available Balance | RMB/USD | Total available balance, including bonus and recharge balance. |
| Unexpired Bonus Balance | RMB/USD | Unexpired bonus balance. |
| Recharge Balance | RMB/USD | Recharge balance. |
@@ -0,0 +1,35 @@
---
id: deepseek
title: 监控:Deepseek 账户情况
sidebar_label: Deepseek 账户情况
keywords: [开源监控系统, 开源网络监控, Deepseek账户监控]
---
### 准备工作
#### 获取会话密钥
登录 Deepseek 后台,访问 `https://platform.deepseek.com/api_keys` 页面,获取会话密钥。
### 配置参数
| 参数名称 | 参数帮助描述 |
|-------|---------------------------------|
| 监控Host | 此处填写 api.deepseek.com 。 |
| 任务名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 会话密钥 | 即准备工作中获取的会话密钥。 |
| 采集器 | 配置此监控使用哪台采集器调度采集。 |
| 监控周期 | 监控周期性采集数据间隔时间,单位秒,可设置的最小间隔为30秒。 |
| 绑定标签 | 对监控资源的分类管理标签。 |
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息。 |
### 采集指标
#### 指标集合:计费
| 指标名称 | 指标单位 | 指标帮助描述 |
|---------|--------|-----------|
| 货币 | 无 | 货币,人民币或美元 |
| 可用余额 | 人民币/美元 | 总的可用余额,包括赠金和充值余额 |
| 未过期的赠金余额 | 人民币/美元 | 未过期的赠金余额 |
| 充值的余额 | 人民币/美元 | 充值余额 |
@@ -23,15 +23,15 @@ keywords: [开源监控系统, 开源网络监控, OpenAI账户监控]
### 配置参数
| 参数名称 | 参数帮助描述 |
|:-------|---------------------------------|---|
| 监控Host | 此处填写 api.openai.com 。 |
| 任务名称 | 标识此监控的名称,名称需要保证唯一性。 | |
| 会话密钥 | 即准备工作中获取的会话密钥。 | |
| 采集器 | 配置此监控使用哪台采集器调度采集。 |
| 参数名称 | 参数帮助描述 |
|----------|--------------------------------|
| 监控Host | 此处填写 api.openai.com 。 |
| 任务名称 | 标识此监控的名称,名称需要保证唯一性。 |
| 会话密钥 | 即准备工作中获取的会话密钥。 |
| 采集器 | 配置此监控使用哪台采集器调度采集。 |
| 监控周期 | 监控周期性采集数据间隔时间,单位秒,可设置的最小间隔为30秒。 |
| 绑定标签 | 对监控资源的分类管理标签。 |
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息。 |
| 绑定标签 | 对监控资源的分类管理标签。 |
| 描述备注 | 更多标识和描述此监控的备注信息,用户可以在这里备注信息。 |
### 采集指标
@@ -81,4 +81,11 @@ describe('Service: I18n', () => {
expect(lang).toBe('en-US');
});
});
it('should be trigger notify when changed language', () => {
genModule();
srv.use('pt-BR', {});
srv.change.subscribe(lang => {
expect(lang).toBe('pt-BR');
});
});
});
+18 -2
View File
@@ -3,6 +3,7 @@ import { registerLocaleData } from '@angular/common';
import { HttpHeaders } from '@angular/common/http';
import ngEn from '@angular/common/locales/en';
import ngJa from '@angular/common/locales/ja';
import ngPt from '@angular/common/locales/pt';
import ngZh from '@angular/common/locales/zh';
import ngZhTw from '@angular/common/locales/zh-Hant';
import { Injectable } from '@angular/core';
@@ -17,9 +18,16 @@ import {
ja_JP as delonJaJP
} from '@delon/theme';
import { AlainConfigService } from '@delon/util/config';
import { enUS as dfEn, zhCN as dfZhCn, zhTW as dfZhTw, ja as dfJa } from 'date-fns/locale';
import { enUS as dfEn, zhCN as dfZhCn, zhTW as dfZhTw, ja as dfJa, ptBR as dfPtBR } from 'date-fns/locale';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { en_US as zorroEnUS, NzI18nService, zh_CN as zorroZhCN, zh_TW as zorroZhTW, ja_JP as zorroJaJP } from 'ng-zorro-antd/i18n';
import {
en_US as zorroEnUS,
NzI18nService,
zh_CN as zorroZhCN,
zh_TW as zorroZhTW,
ja_JP as zorroJaJP,
pt_BR as zorroPtBR
} from 'ng-zorro-antd/i18n';
import { Observable, zip } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -67,6 +75,14 @@ const LANGS: { [key: string]: LangConfigData } = {
date: dfJa,
delon: delonJaJP,
abbr: '🇯🇵'
},
'pt-BR': {
text: 'Português (Brasil)',
ng: ngPt,
zorro: zorroPtBR,
date: dfPtBR,
delon: delonEnUS, // Usando en-US como fallback (ou crie um locale personalizado)
abbr: '🇧🇷'
}
};
@@ -43,7 +43,7 @@ import { GeneralConfigService } from '../../../service/general-config.service';
ngClass="alain-default__nav-item-icon"
(click)="toggleMute($event)"
nz-tooltip
[nzTooltipTitle]="'common.mute' | i18n"
[nzTooltipTitle]="(mute.mute ? 'common.unmute' : 'common.mute') | i18n"
></i>
</nz-badge>
</div>
@@ -163,6 +163,9 @@ export class HeaderNotifyComponent implements OnInit, OnDestroy {
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
}
if (this.eventSource) {
this.eventSource.close();
}
}
onPopoverVisibleChange(visible: boolean): void {
@@ -228,24 +231,6 @@ export class HeaderNotifyComponent implements OnInit, OnDestroy {
);
}
updateAlertsStatus(alertIds: Set<number>, status: string) {
const markAlertsStatus$ = this.alertSvc.applyGroupAlertsStatus(alertIds, status).subscribe(
message => {
markAlertsStatus$.unsubscribe();
if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.mark-success'), '');
this.loadData();
} else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), message.msg);
}
},
error => {
markAlertsStatus$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), error.msg);
}
);
}
gotoAlertCenter(): void {
this.popoverVisible = false;
this.router.navigateByUrl(`/alert/center`);
@@ -314,7 +299,7 @@ export class HeaderNotifyComponent implements OnInit, OnDestroy {
});
this.eventSource.onerror = error => {
console.error('SSE connection error:', error);
setTimeout(() => this.initSSEConnection(), 3000);
this.eventSource.close();
};
}
}
@@ -169,7 +169,7 @@
<tbody>
<tr *ngFor="let data of fixedTable.data">
<td nzAlign="center" nzLeft [nzChecked]="checkedMonitorIds.has(data.id)" (nzCheckedChange)="onItemChecked(data.id, $event)"></td>
<td nzAlign="center">
<td nzAlign="center" nzEllipsis>
<button nz-button nzSize="default" nzType="link" [routerLink]="['/monitors/' + data.id]">
{{ data.name }}
<span nz-icon nzType="area-chart"></span>
@@ -189,7 +189,7 @@
<span>{{ 'monitor.status.down' | i18n }}</span>
</nz-tag>
</td>
<td nzAlign="center">
<td nzAlign="center" nzEllipsis>
<button
nz-button
nzSize="default"
@@ -32,6 +32,7 @@
<nz-option [nzValue]="'zh_CN'" [nzLabel]="'settings.system-config.locale.zh_CN' | i18n"></nz-option>
<nz-option [nzValue]="'zh_TW'" [nzLabel]="'settings.system-config.locale.zh_TW' | i18n"></nz-option>
<nz-option [nzValue]="'ja_JP'" [nzLabel]="'settings.system-config.locale.ja-JP' | i18n"></nz-option>
<nz-option [nzValue]="'pt_BR'" [nzLabel]="'settings.system-config.locale.pt_BR' | i18n"></nz-option>
</nz-select>
</se>
<se [label]="'settings.system-config.timezone' | i18n" [error]="'validation.required' | i18n">
+8 -6
View File
@@ -31,7 +31,7 @@
"alert.center.filter-priority": "Alert Priority",
"alert.center.filter-status": "Alert Status",
"alert.center.first-time": "Start Time",
"alert.center.labels": "Tags",
"alert.center.labels": "Labels",
"alert.center.last-time": "Active Time",
"alert.center.monitor": "Belong Monitor",
"alert.center.no-deal": "Mark Pending",
@@ -124,8 +124,8 @@
"alert.notice.rule.period.no-limit": "Unlimited",
"alert.notice.rule.priority": "Priority Match",
"alert.notice.rule.priority.placeholder": "Select Priorities",
"alert.notice.rule.tag": "Tag Match",
"alert.notice.rule.tag.placeholder": "Select Tags",
"alert.notice.rule.tag": "Label Match",
"alert.notice.rule.tag.placeholder": "Select Labels",
"alert.notice.rule.time": "Notification Time",
"alert.notice.rule.time-end": "End time",
"alert.notice.rule.time-start": "Start time",
@@ -310,7 +310,7 @@
"alert.severity.all": "All Severity",
"alert.silence.delete": "Delete Silence Strategy",
"alert.silence.edit": "Edit Silence Strategy",
"alert.silence.labels": "Tag Match",
"alert.silence.labels": "Label Match",
"alert.silence.match-all": "Match All",
"alert.silence.name": "Silence Strategy Name",
"alert.silence.new": "New Silence Strategy",
@@ -437,6 +437,7 @@
"common.file.select": "Select File",
"common.ignore": "Ignore",
"common.mute": "Mute",
"common.unmute": "Unmute",
"common.name": "Metric Name",
"common.new-time": "Create Time",
"common.no": "No",
@@ -772,6 +773,7 @@
"settings.system-config.locale.zh_CN": "Simplified Chinese(zh_CN)",
"settings.system-config.locale.zh_TW": "Traditional Chinese(zh_TW)",
"settings.system-config.locale.ja-JP": "Japanese(ja_JP)",
"settings.system-config.locale.pt_BR": "Portuguese(pt_BR)",
"settings.system-config.ok": "Confirm Update",
"settings.system-config.theme": "System Theme",
"settings.system-config.theme.compact": "Compact Theme",
@@ -797,7 +799,7 @@
"status.component.state.0": "Normal",
"status.component.state.1": "Abnormal",
"status.component.state.2": "Unknown",
"status.component.tag": "Match Tag",
"status.component.tag": "Match Label",
"status.component.tag.tip": "Status calculation associates the label, and uses all monitoring availability status associated with the label as data to calculate the service status of this component.",
"status.help": "Quickly build a powerful status page based on HertzBeat to easily communicate the real-time status of your services to users. For example, the status page provided by Github <a href='https://www.githubstatus.com'> https://www.githubstatus.com</a>. <br>Supports linkage and synchronization of status page component status and monitoring status, fault event maintenance and management mechanism, etc. Improve your transparency, professionalism and user trust, and reduce communication costs.",
"status.help.link": "https://hertzbeat.apache.org/docs/help/status",
@@ -846,7 +848,7 @@
"status.public.to-component": "Status Page",
"status.public.to-incident": "Incident History",
"status.public.today": "Today",
"tag": "Tag",
"tag": "Label",
"validation.confirm-password.required": "Please confirm your password!",
"validation.date.required": "Please select the start and end date",
"validation.email.invalid": "Invalid email",
+2
View File
@@ -437,6 +437,7 @@
"common.file.select": "ファイルを選択",
"common.ignore": "無視",
"common.mute": "ミュート",
"common.unmute": "ミュート解除",
"common.name": "メトリック名",
"common.new-time": "作成時間",
"common.no": "いいえ",
@@ -772,6 +773,7 @@
"settings.system-config.locale.zh_CN": "簡体字中国語(zh_CN)",
"settings.system-config.locale.zh_TW": "繁体字中国語(zh_TW)",
"settings.system-config.locale.ja-JP": "日本語(ja_JP)",
"settings.system-config.locale.pt_BR": "Português(pt_BR)",
"settings.system-config.ok": "更新を確認",
"settings.system-config.theme": "システムテーマ",
"settings.system-config.theme.compact": "コンパクトテーマ",
+770
View File
@@ -0,0 +1,770 @@
{
"menu": {
"main": "Principal",
"lang": "Idioma",
"dashboard": "Painel",
"search.placeholder": "Pesquisar: Tarefa de Monitoramento: Nome, Host, etc",
"fullscreen": "Tela Cheia",
"fullscreen.exit": "Sair",
"clear.local.storage": "Limpar Armazenamento Local",
"monitor": {
"": "Monitoramento",
"center": "Centro de Monitoramento",
"bulletin": "Boletim",
"service": "Monitor de Serviço",
"db": "Monitor de Banco de Dados",
"os": "Monitor de Sistema Operacional",
"mid": "Monitor de Middleware",
"cn": "Nativo da Nuvem",
"network": "Monitor de Rede",
"custom": "Monitor Personalizado",
"prometheus": "Tarefa Prometheus",
"program": "Monitor de Programa",
"webserver": "Monitor de Servidor Web",
"cache": "Monitor de Cache",
"bigdata": "Monitor de Big Data",
"promql": "Consulta de Dados",
"llm": "AI LLM",
"server": "Monitor de Servidor"
},
"account": {
"": "Pessoal",
"center": "Centro Pessoal",
"settings": "Configurações da Conta",
"security": "Configurações de Segurança",
"binding": "Vinculação de Conta",
"trigger": "Disparar Erro",
"logout": "Sair"
},
"alert": {
"": "Alertas",
"center": "Centro de Alarmes",
"converge": "Convergência de Alarmes",
"setting": "Regra de Limite",
"silence": "Silenciar Alarme",
"dispatch": "Notificação"
},
"advanced": {
"": "Avançado",
"collector": "Cluster de Coletores",
"tags": "Gerenciar Tags",
"define": "Modelo de Monitoramento",
"status": "Página de Status",
"plugins": "Gerenciar Plugins"
},
"extras": {
"": "Mais",
"help": "Centro de Ajuda",
"setting": "Configuração",
"settings": "Configurações",
"about": "Sobre"
},
"more": "Mais"
},
"monitor": {
"": "Monitor",
"availability": "Disponibilidade do Monitor",
"name": "Nome da Tarefa",
"name.tip": "Nome da tarefa de monitoramento",
"host": "Host de Destino",
"host.tip": "O IP ou domínio do peer monitorado",
"description": "Descrição",
"description.tip": "Descrição e observações",
"intervals": "Intervalos",
"intervals.tip": "Intervalo de tempo para coleta periódica de dados, em segundos",
"collector": "Coletor",
"collector.tip": "Escolha qual coletor despachar para este monitoramento",
"collector.system.default": "Despacho Padrão do Sistema",
"collector.status.online": "Online",
"collector.status.offline": "Offline",
"category": {
"": "Categoria",
"server": "Monitor de Servidor",
"service": "Serviço",
"db": "Banco de Dados",
"os": "Sistema Operacional",
"mid": "Middleware",
"cn": "Nativo da Nuvem",
"network": "Rede",
"custom": "Personalizado",
"program": "Aplicação",
"webserver": "Servidor Web",
"cache": "Cache",
"bigdata": "Big Data",
"auto": "Tarefa Automática"
},
"app": {
"": "Tipo de Monitor",
"website": "Monitor de Site",
"api": "API HTTP",
"http": "API HTTP",
"ping": "Conexão PING",
"port": "Porta Disponível",
"mysql": "MySQL",
"oracle": "Oracle",
"redis": "Redis",
"fullsite": "Monitor de Mapa do Site"
},
"status": {
"": "Status da Tarefa",
"all": "Todos os Status",
"up": "Ativo",
"down": "Inativo",
"unreachable": "Inacessível",
"paused": "Pausado"
},
"grafana": {
"enabled.tip": "está habilitado, os dados de monitoramento serão exibidos no Grafana",
"enabled.label": "Habilitar Grafana",
"upload.tip": "Carregar arquivo de modelo do Grafana, suporta arquivo .json",
"upload.label": "Carregar Modelo do Grafana"
}
},
"alert": {
"": "Alerta",
"status": {
"": "Status do Alerta",
"all": "Todos os Status",
"0": "Pendente",
"2": "Restaurado",
"3": "Processado"
},
"priority": {
"": "Prioridade do Alarme",
"all": "Todas as Prioridades",
"0": "Emergência",
"1": "Crítico",
"2": "Aviso"
}
},
"bulletin": {
"new": "Novo Boletim",
"edit": "Editar Boletim",
"delete": "Excluir Boletim",
"batch.delete": "Excluir Boletins em Lote",
"name": "Nome do Boletim",
"name.placeholder": "Digite um nome personalizado para o boletim",
"monitor.type": "Tipo de Monitor",
"monitor.name": "Nome da Tarefa de Monitoramento",
"monitor.metrics": "Métricas de Monitoramento",
"help.content": "Boletim de monitoramento personalizado (beta), exibindo métricas selecionadas de um monitor específico em forma de tabela",
"help.link": ""
},
"question.link": "https://hertzbeat.apache.org/docs/help/issue/",
"alert.setting.new": "Nova Regra de Limite",
"alert.setting.edit": "Editar Regra de Limite",
"alert.setting.delete": "Excluir Regra de Limite",
"alert.setting.export": "Exportar Regra",
"alert.setting.import": "Importar Regra",
"alert.setting.target": "Métrica Alvo",
"alert.setting.target.place-holder": "Pesquise ou selecione a métrica alvo",
"alert.setting.expr": "Expressão de Disparo do Limite",
"alert.setting.trigger": "Disparar alarmes e atualizar o status do monitor",
"alert.setting.rule": "Regra de Limite",
"alert.setting.number": "Numérico",
"alert.setting.string": "Texto",
"alert.setting.time": "Tempo",
"alert.setting.rule.label": "Configuração gráfica de regras de limite de alarme, suporta múltiplas regras &&",
"alert.setting.rule.metric.place-holder": "Selecione a métrica",
"alert.setting.rule.switch-expr.0": "Limite de Modelo",
"alert.setting.rule.switch-expr.1": "Limite de Codificação",
"alert.setting.rule.operator": "Operador",
"alert.setting.rule.operator.str-equals": "igual",
"alert.setting.rule.operator.str-no-equals": "não igual",
"alert.setting.rule.operator.str-contains": "contém",
"alert.setting.rule.operator.str-no-contains": "não contém",
"alert.setting.rule.operator.str-matches": "corresponde",
"alert.setting.rule.operator.str-no-matches": "não corresponde",
"alert.setting.rule.operator.exists": "valor existe",
"alert.setting.rule.operator.no-exists": "valor não existe",
"alert.setting.rule.string-value.place-holder": "Digite o texto",
"alert.setting.rule.numeric-value.place-holder": "Digite o número",
"alert.setting.times": "Número de Disparos",
"alert.setting.times.tip": "Defina quantas vezes o limite deve ser disparado antes de enviar um alerta",
"alert.setting.template": "Modelo de Notificação",
"alert.setting.template.tip": "Variáveis de ambiente de modelo de notificação suportadas",
"alert.setting.template.label": "O modelo de informação de notificação enviado após o disparo do alarme, veja as variáveis de ambiente do modelo acima",
"alert.setting.template.example": "Digite o modelo de notificação. Ex: ${app}.${metrics}.${metric} valor está muito alto",
"alert.setting.template.monitor-type": "Nome do Tipo de Monitor",
"alert.setting.template.metrics-name": "Nome da Métrica",
"alert.setting.template.metric-name": "Nome da Métrica",
"alert.setting.template.metric-value": "Valor da Métrica",
"alert.setting.template.other-value": "Outro Valor da Métrica",
"alert.setting.default": "Padrão Global",
"alert.setting.default.tip": "Se esta configuração de limite de alarme se aplica a todos os monitoramentos deste tipo globalmente",
"alert.setting.enable": "Habilitar Limite",
"alert.setting.enable.tip": "Esta configuração de limite de alarme está habilitada ou desabilitada",
"alert.setting.recover-notice": "Notificação de Recuperação",
"alert.setting.recover-notice.tip": "Se deve enviar a notificação correspondente quando o alarme for resolvido sob esta regra de limite",
"alert.setting.connect": "Associar Monitores ao Limite de Alarme",
"alert.setting.connect.left": "Não Associado",
"alert.setting.connect.right": "Associado",
"alert.setting.expr.tip": "Variáveis de ambiente e operadores suportados na expressão de disparo do limite",
"alert.setting.expr.label": "Calcule e julgue se o limite foi disparado de acordo com esta expressão. As variáveis de ambiente e operadores da expressão são mostrados acima.",
"alert.setting.expr.example": "Calcule se o limite foi disparado de acordo com esta expressão. Ex",
"alert.setting.priority.tip": "O nível de alarme que dispara o limite, do baixo para o alto: Aviso, Crítico, Emergência",
"alert.setting.target.tip": "O objeto métrico selecionado",
"alert.setting.target.other": "Outros objetos métricos da linha",
"alert.setting.target.system_value_row_count": "Contagem de linhas de valor do Sistema-Métricas",
"alert.setting.operator": "Funções de operador suportadas",
"alert.setting.search": "Pesquisar Limite",
"alert.silence.new": "Nova Estratégia de Silêncio",
"alert.silence.edit": "Editar Estratégia de Silêncio",
"alert.silence.delete": "Excluir Estratégia de Silêncio",
"alert.silence.name": "Nome da Estratégia de Silêncio",
"alert.silence.match-all": "Corresponder a Todos",
"alert.silence.priority": "Corresponder Prioridade",
"alert.silence.type.once": "Silêncio Único",
"alert.silence.type.cyc": "Silêncio Periódico",
"alert.silence.type": "Tipo de Silêncio",
"alert.silence.tags": "Corresponder Tags",
"alert.silence.time": "Período de Silêncio",
"alert.silence.times": "Número de Alertas Silenciados",
"alert.silence.enable": "Habilitar Silêncio",
"alert.converge.new": "Nova Estratégia de Convergência",
"alert.converge.edit": "Editar Estratégia de Convergência",
"alert.converge.delete": "Excluir Estratégia de Convergência",
"alert.converge.name": "Nome da Estratégia",
"alert.converge.match-all": "Corresponder a Todos",
"alert.converge.priority": "Corresponder Prioridade",
"alert.converge.tags": "Corresponder Tags",
"alert.converge.repeat": "Critério de Repetição de Alerta",
"alert.converge.repeat-rule": "As tags e a prioridade do alerta são as mesmas",
"alert.converge.eval-interval": "Intervalo de Convergência de Repetição de Alerta (s)",
"alert.converge.enable": "Habilitar Convergência",
"alert.center.delete": "Excluir Alertas",
"alert.center.clear": "Limpar Tudo",
"alert.center.deal": "Marcar como Processado",
"alert.center.no-deal": "Marcar como Pendente",
"alert.center.search": "Pesquisar Conteúdo do Alerta",
"alert.center.filter-status": "Status do Alerta",
"alert.center.filter-priority": "Prioridade do Alerta",
"alert.center.target": "Métrica Alvo",
"alert.center.monitor": "Monitor Pertence",
"alert.center.priority": "Prioridade",
"alert.center.content": "Conteúdo do Alerta",
"alert.center.tags": "Tags",
"alert.center.status": "Status",
"alert.center.time": "Hora do Alerta",
"alert.center.time.tip": "Alertas foram disparados {{times}} vezes durante este período de alerta",
"alert.center.first-time": "Hora de Início",
"alert.center.last-time": "Última Hora",
"alert.center.confirm.delete": "Confirme se deseja excluir!",
"alert.center.confirm.clear-all": "Confirme se deseja limpar todos os alertas!",
"alert.center.notify.no-mark": "Nenhum item selecionado para marcação!",
"alert.center.confirm.mark-done-batch": "Confirme se deseja marcar como processado em lote!",
"alert.center.confirm.mark-done": "Confirme se deseja marcar como processado!",
"alert.center.confirm.mark-no-batch": "Confirme se deseja marcar como pendente em lote!",
"alert.center.confirm.mark-no": "Confirme se deseja marcar como pendente!",
"alert.help.notice": "A notificação é usada para configurar o destinatário da mensagem de alarme e o método de recebimento. A mensagem de alarme será enviada ao destinatário de forma especificada (suporta email, discord, webhook, etc). <a href='https://hertzbeat.apache.org/zh-cn/docs/help/alert_webhook'>Clique aqui para ver os passos de configuração.</a>.<br>“<i>Modelo de Notificação</i>” é o modelo de estrutura de conteúdo da mensagem. O modelo embutido é usado por padrão ou você pode personalizar o modelo para personalizar a estrutura de notificação da mensagem.<br><span class='help_module_span'>Nota⚠\uFE0F: Após configurar o “<i>Destinatário</i>”, você também precisa configurar a “<i>Política de Notificação</i>” para especificar quais mensagens são enviadas para quais destinatários.</span><a href='https://hertzbeat.apache.org/docs/help/alert_email'> Clique aqui para ver possíveis problemas</a>.",
"alert.help.notice.link": "https://hertzbeat.apache.org/docs/help/alert_email",
"alert.help.converge": "A Convergência de Alarmes suporta a deduplicação e convergência de mensagens de alarme repetidas dentro de um período de tempo especificado. <br> Clique em \"<i>Nova Estratégia de Convergência</i>\" e configure o período de tempo para evitar um grande número de alarmes repetitivos que podem anestesiar o destinatário do alarme.",
"alert.help.converge.link": "https://hertzbeat.apache.org",
"alert.help.center": "O Centro de Alarmes é o centro de processamento de notificações para todas as mensagens de alarme disparadas, incluindo alarmes disparados por limites internos do sistema e informações de alarme acessadas através de canais de alarme externos de terceiros. <br> O Hertzbeat suporta operações em lote, como consulta de alarmes, marcação de processamento, não processados, exclusão de alarmes e limpeza.",
"alert.help.center.link": "https://hertzbeat.apache.org/docs/help/guide",
"alert.help.setting": "As Regras de Limite são usadas para o gerenciamento de regras de limite de alarme para métricas. Clique em \"<i>Novo Limite</i>\" para configurar o limite de alarme para métricas de monitoramento. O Hertzbeat disparará alarmes com base no limite e nos dados das métricas.<br>Nota⚠\uFE0F: A mensagem de alarme que foi disparada pode ser verificada no [Centro de Alarmes], e você também pode configurar o método de notificação e os destinatários em [Notificação].",
"alert.help.setting.link": "https://hertzbeat.apache.org/docs/help/alert_threshold",
"alert.help.silence": "O gerenciamento de Silêncio de Alarmes é usado quando você não quer ser perturbado durante a manutenção do sistema ou nos fins de semana. <br> Clique em \"<i>Nova Estratégia de Silêncio</i>\" e configure o período de tempo para bloquear mensagens para que você não seja perturbado durante os intervalos.",
"alert.help.silence.link": "https://hertzbeat.apache.org/docs",
"alert.notice.template": "Modelo de Notificação",
"alert.notice.template.new": "Novo Modelo",
"alert.notice.template.edit": "Editar Modelo",
"alert.notice.template.show": "Ver Conteúdo do Modelo",
"alert.notice.template.delete": "Excluir Modelo",
"alert.notice.template.name": "Nome do Modelo",
"alert.notice.template.type": "Tipo de Notificação",
"alert.notice.template.preset": "Tipo de Modelo",
"alert.notice.template.preset.true": "Pré-definido pelo Sistema",
"alert.notice.template.preset.false": "Personalizado pelo Usuário",
"alert.notice.template.content": "Conteúdo do Modelo",
"alert.notice.template.placeholder": "Selecione um modelo",
"alert.notice.receiver": "Destinatário da Notificação",
"alert.notice.receiver.new": "Novo Destinatário",
"alert.notice.receiver.edit": "Editar Destinatário",
"alert.notice.receiver.delete": "Excluir Destinatário",
"alert.notice.receiver.people": "Destinatário",
"alert.notice.receiver.people.placeholder": "Selecione um destinatário",
"alert.notice.receiver.people.name": "Nome do Destinatário",
"alert.notice.receiver.type": "Tipo de Notificação",
"alert.notice.receiver.type.placeholder": "Selecione um tipo de notificação",
"alert.notice.receiver.setting": "Configuração",
"alert.notice.receiver.next": "Por favor, configure sua [Política de Notificação de Alerta] no próximo passo",
"alert.notice.type.sms": "SMS",
"alert.notice.type.phone": "Telefone",
"alert.notice.type.email": "Email",
"alert.notice.type.userId": "ID do Usuário",
"alert.notice.type.url": "URL",
"alert.notice.type.wechat": "Abrir WeChat",
"alert.notice.type.wechat-id": "WeChat OPENID",
"alert.notice.type.WeCom-robot": "Robô WeCom",
"alert.notice.type.WeCom-robot-key": "Chave do Robô WeCom",
"alert.notice.type.access-token": "Token de Acesso do Robô",
"alert.notice.type.ding": "Robô DingDing",
"alert.notice.type.fei-shu": "Robô FeiShu",
"alert.notice.type.fei-shu-key": "Chave do Robô FeiShu",
"alert.notice.type.telegram-bot": "Bot do Telegram",
"alert.notice.type.telegram-bot-token": "Token do Bot do Telegram",
"alert.notice.type.telegram-bot-user-id": "ID do Usuário do Telegram",
"alert.notice.type.slack": "WebHook do Slack",
"alert.notice.type.slack-webHook-url": "URL do WebHook do Slack",
"alert.notice.type.discord": "Bot do Discord",
"alert.notice.type.discord-bot-token": "Token do Bot do Discord",
"alert.notice.type.discord-channel-id": "ID do Canal do Discord",
"alert.notice.type.WeComApp": "App WeCom",
"alert.notice.type.WeComApp-corpId": "ID da Corporação do App WeCom",
"alert.notice.type.WeComApp-agentId": "ID do App WeCom",
"alert.notice.type.WeComApp-appSecret": "Segredo do App WeCom",
"alert.notice.type.WeComApp-userId": "ID do Usuário (separado por |)",
"alert.notice.type.WeComApp-partyId": "ID do Partido (separado por |)",
"alert.notice.type.WeComApp-tagId": "ID da Tag (separado por |)",
"alert.notice.type.smn": "SMN da Nuvem Huawei",
"alert.notice.type.smn-ak": "AK",
"alert.notice.type.smn-sk": "SK",
"alert.notice.type.smn-projectId": "ID do Projeto",
"alert.notice.type.smn-region": "Região",
"alert.notice.type.smn-topicUrn": "TopicUrn",
"alert.notice.type.serverchan": "ServerChan",
"alert.notice.type.serverchan-token": "Token do ServerChan",
"alert.notice.type.gotify": "Gotify",
"alert.notice.type.gotify-token": "Token do Gotify",
"alert.notice.rule": "Política de Notificação",
"alert.notice.rule.new": "Nova Política de Notificação",
"alert.notice.rule.edit": "Editar Política de Notificação",
"alert.notice.rule.delete": "Excluir Política de Notificação",
"alert.notice.rule.name": "Nome da Política",
"alert.notice.rule.all": "Despachar Todos",
"alert.notice.rule.enable": "Habilitar",
"alert.notice.rule.tag": "Corresponder Tags",
"alert.notice.rule.tag.placeholder": "Selecione Tags",
"alert.notice.rule.priority": "Corresponder Prioridades",
"alert.notice.rule.priority.placeholder": "Selecione Prioridades",
"alert.notice.rule.period": "Período de Tempo",
"alert.notice.rule.period-chose": "Escolher Data",
"alert.notice.rule.period.no-limit": "Ilimitado",
"alert.notice.rule.period.custom": "Personalizado",
"alert.notice.rule.time": "Hora da Notificação",
"alert.notice.rule.time-start": "Hora de Início",
"alert.notice.rule.time-end": "Hora de Término",
"alert.notice.send-test": "Enviar Mensagem de Teste de Alerta",
"alert.notice.send-test.notify.success": "Envio de Teste de Alerta Bem-sucedido!",
"alert.notice.send-test.notify.failed": "Envio de Teste de Alerta Falhou!",
"alert.notice.sender.enable": "está Habilitado",
"alert.notice.sender.mail.host": "Endereço do Servidor de Email",
"alert.notice.sender.mail.username": "Conta de Email",
"alert.notice.sender.mail.password": "Senha do Email",
"alert.notice.sender.mail.port": "Porta do Email",
"alert.notice.sender.mail.ssl": "Habilitar SSL",
"alert.notice.sender.mail.starttls": "Habilitar STARTTLS",
"alert.notice.sender.mail.enable": "Habilitar Configuração de Email",
"alert.notice.sender.sms.type": "Tipo de SMS",
"alert.notice.sender.sms.type.tencent": "SMS Tencent",
"alert.notice.sender.sms.type.alibaba": "SMS Alibaba",
"alert.notice.sender.sms.tencent.secretId": "SecretId do SMS Tencent",
"alert.notice.sender.sms.tencent.secretKey": "SecretKey do SMS Tencent",
"alert.notice.sender.sms.tencent.signName": "Nome de Assinatura do SMS Tencent",
"alert.notice.sender.sms.tencent.appId": "AppId do SMS Tencent",
"alert.notice.sender.sms.tencent.templateId": "ID do Modelo do SMS Tencent",
"alert.export.switch-type": "Selecione o formato do arquivo de exportação!",
"alert.export.use-type": "Exportar regras no formato de arquivo {{type}}",
"dashboard.alerts.title": "Lista de Alarmes Recentes",
"dashboard.alerts.title-no": "Alarmes Pendentes Recentes",
"dashboard.alerts.no": "Nenhum Alarme Pendente",
"dashboard.alerts.enter": "Ir para o Centro de Alarmes",
"dashboard.alerts.distribute": "A Distribuição dos Alarmes",
"dashboard.alerts.num": "Número de Alarmes",
"dashboard.alerts.deal": "Tratamento de Alarmes",
"dashboard.alerts.deal-percent": "Taxa de Tratamento",
"dashboard.monitors.total": "Total de Monitores",
"dashboard.monitors.title": "Visão Geral do Monitoramento",
"dashboard.monitors.sub-title": "A Distribuição dos Monitores",
"dashboard.monitors.formatter": " Monitores ",
"dashboard.monitors.distribute": "Distribuição do Monitor",
"menu.link.question": "FAQ",
"menu.link.guild": "Guia do Usuário",
"monitor_icon.center": "laptop",
"monitor_icon.service": "appstore",
"monitor_icon.db": "console-sql",
"monitor_icon.os": "windows",
"monitor_icon.mid": "cluster",
"monitor_icon.cn": "cloud-server",
"monitor_icon.network": "global",
"monitor_icon.custom": "project",
"monitor_icon.program": "code",
"monitor_icon.cache": "group",
"monitor_icon.bigdata": "dot-chart",
"monitor_icon.webserver": "database",
"monitors.center.help": "O Centro de Monitoramento é o portal de gerenciamento de recursos de monitoramento do HertzBeat. Exibe os monitores atualmente adicionados em forma de lista e suporta agrupamento por tags, filtragem de consulta e acesso para visualizar detalhes de monitoramento. <br> Você pode adicionar, modificar, excluir, pausar monitoramento, importar/exportar, gerenciar em lote e outras operações nos monitores.",
"monitors.center.help.link": "https://hertzbeat.apache.org/docs/",
"monitors.center.search.placeholder": "Pesquisar tipo de monitor para adicionar: Linux, Redis",
"monitors.list": "Lista de Monitores",
"monitors.spinning-tip.detecting": "Detecção Disponível",
"monitors.new": "Novo",
"monitors.new-monitor": "Novo Monitor",
"monitors.new.success": "Novo Monitor Bem-sucedido",
"monitors.new.failed": "Novo Monitor Falhou",
"monitors.edit": "Editar",
"monitors.edit.success": "Atualização do Monitor Bem-sucedida",
"monitors.edit.failed": "Atualização do Monitor Falhou",
"monitors.not-found": "Este Monitor Não Encontrado",
"monitors.delete": "Excluir",
"monitors.edit-monitor": "Editar Monitor",
"monitors.delete-monitor": "Excluir Monitor",
"monitors.enable": "Retomar Monitor",
"monitors.cancel": "Pausar Monitor",
"monitors.export": "Exportar Monitor",
"monitors.export.switch-type": "Selecione o formato do arquivo de exportação!",
"monitors.export.use-type": "Exportar monitores no formato de arquivo {{type}}",
"monitors.import": "Importar Monitor",
"monitors.search.placeholder": "Pesquisar Monitor",
"monitors.search.tag": "Filtrar por Tag",
"monitors.search.app": "Filtrar por Tipo",
"monitors.total": "Total",
"monitors.advanced": "Avançado",
"monitors.advanced.tip": "Parâmetros de Configuração Avançada",
"monitors.detect": "Detectar",
"monitors.detect.success": "Detecção Bem-sucedida",
"monitors.detect.failed": "Detecção Falhou",
"monitors.detect.tip": "Verificar e detectar o status de disponibilidade do monitor",
"monitors.detail.time-series.unavailable": "Incapaz de fornecer gráfico histórico, configure o banco de dados de séries temporais",
"monitors.detail": "Detalhes do Monitor",
"monitors.detail.auto-refresh": "Atualização Automática Após {{time}} s",
"monitors.detail.config-refresh": "Definir Atualização Automática para {{time}} s",
"monitors.detail.close-refresh": "Fechar Atualização Automática",
"monitors.detail.show-basic": "Mostrar Básico do Monitor",
"monitors.detail.name": "Nome",
"monitors.detail.port": "Porta",
"monitors.detail.description": "Descrição",
"monitors.detail.status": "Status",
"monitors.detail.basic": "Básico do Monitoramento",
"monitors.detail.realtime": "Detalhes em Tempo Real do Monitor",
"monitors.detail.history": "Detalhes do Gráfico Histórico do Monitor",
"monitors.collect.time": "Tempo de Coleta",
"monitors.collect.time.tip": "Último Tempo de Coleta",
"monitors.detail.chart.zoom": "Ampliar",
"monitors.detail.chart.back": "Restaurar Zoom",
"monitors.detail.chart.save": "Salvar como Imagem",
"monitors.detail.chart.query-1h": "Consultar 1 Hora",
"monitors.detail.chart.query-6h": "Consultar 6 Horas",
"monitors.detail.chart.query-1d": "Consultar 1 Dia",
"monitors.detail.chart.query-1w": "Consultar 1 Semana",
"monitors.detail.chart.query-1m": "Consultar 1 Mês",
"monitors.detail.chart.query-3m": "Consultar 3 Meses",
"monitors.detail.chart.no-data": "Nenhum Dado de Métrica",
"monitors.detail.chart.unit": "Unidade",
"monitors.detail.value.null": "Nenhum Valor",
"common.name": "Nome da Métrica",
"common.value": "Valor da Métrica",
"common.search": "Pesquisar",
"common.refresh": "Atualizar",
"common.notice": "Notificação",
"common.ignore": "Ignorar",
"common.edit-time": "Tempo de Atualização",
"common.new-time": "Tempo de Criação",
"common.edit": "Operar",
"common.total": "Total",
"common.yes": "Sim",
"common.no": "Não",
"common.enable": "Habilitar",
"common.disable": "Desabilitar",
"common.copy": "Copiar para a Área de Transferência",
"common.copy.button": "Copiar",
"common.notify.no-select-edit": "Nenhum item selecionado para edição!",
"common.notify.one-select-edit": "Apenas uma seleção pode ser editada!",
"common.confirm.delete": "Confirme se deseja excluir!",
"common.notify.no-select-delete": "Nenhum item selecionado para exclusão!",
"common.notify.no-select-export": "Nenhum item selecionado para exportação!",
"common.confirm.delete-batch": "Confirme se deseja excluir em lote!",
"common.notify.delete-success": "Exclusão Bem-sucedida!",
"common.notify.delete-fail": "Exclusão Falhou!",
"common.notify.new-success": "Adição Bem-sucedida!",
"common.notify.new-fail": "Adição Falhou!",
"common.notify.apply-success": "Aplicação Bem-sucedida!",
"common.notify.apply-fail": "Aplicação Falhou!",
"common.notify.operate-success": "Operação Bem-sucedida!",
"common.notify.operate-fail": "Operação Falhou!",
"common.notify.monitor-fail": "Consulta do Monitor Falhou!",
"common.notify.edit-success": "Edição Bem-sucedida!",
"common.notify.edit-fail": "Edição Falhou!",
"common.notify.no-select-cancel": "Nenhum item selecionado para cancelamento!",
"common.confirm.cancel-batch": "Confirme se deseja cancelar o monitor em lote!",
"common.confirm.cancel": "Confirme se deseja cancelar o monitor!",
"common.notify.cancel-success": "Cancelamento Bem-sucedido!",
"common.notify.cancel-fail": "Cancelamento Falhou!",
"common.notify.mark-success": "Marca Bem-sucedida!",
"common.notify.mark-fail": "Marca Falhou!",
"common.notify.no-select-enable": "Nenhum item selecionado para habilitar!",
"common.confirm.enable-batch": "Confirme se deseja habilitar o monitor em lote!",
"common.confirm.enable": "Confirme se deseja habilitar o monitor!",
"common.notify.enable-success": "Habilitação Bem-sucedida!",
"common.notify.enable-fail": "Habilitação Falhou!",
"common.confirm.clear-cache": "Confirme se deseja limpar o cache!",
"common.notify.clear-success": "Limpeza Bem-sucedida!",
"common.notify.clear-fail": "Limpeza Falhou!",
"common.notify.export-success": "Exportação Bem-sucedida!",
"common.notify.export-fail": "Exportação Falhou!",
"common.notify.import-success": "Importação Bem-sucedida!",
"common.notify.import-fail": "Importação Falhou!",
"common.notify.copy-success": "Cópia Bem-sucedida!",
"common.button.ok": "OK",
"common.button.cancel": "Cancelar",
"common.button.return": "Retornar",
"common.button.help": "Ajuda",
"common.button.edit": "Editar",
"common.button.setting": "Configuração",
"common.button.delete": "Excluir",
"common.button.detect": "Detectar",
"common.week.7": "Domingo",
"common.week.1": "Segunda-feira",
"common.week.2": "Terça-feira",
"common.week.3": "Quarta-feira",
"common.week.4": "Quinta-feira",
"common.week.5": "Sexta-feira",
"common.week.6": "Sábado",
"common.time.unit.second": "Segundos",
"common.file.select": "Selecionar Arquivo",
"validation.email.invalid": "Email inválido",
"validation.phone.invalid": "Número de telefone inválido",
"validation.verification-code.invalid": "Código de verificação inválido, deve ter 6 dígitos",
"validation.required": "Por favor, preencha os campos obrigatórios! ",
"app.theme.default": "Tema Claro",
"app.theme.dark": "Tema Escuro",
"app.theme.compact": "Tema Compacto",
"app.role.admin": "administrador",
"app.lock": "Desbloquear",
"app.lock.placeholder": "Digite qualquer coisa para desbloquear",
"app.passport.desc": "Um Sistema de Monitoramento em Tempo Real de Código Aberto",
"app.passport.intro-1": "Código Aberto, Distribuído",
"app.passport.intro-2": "Monitoramento em Tempo Real",
"app.login.message-need-identifier": "Por favor, insira seu nome de usuário",
"app.login.message-need-credential": "Por favor, insira a senha",
"app.login.message-invalid-credentials": "Nome de usuário ou senha inválidos",
"app.login.need-change-password": "Por favor, atualize a senha inicial padrão em tempo hábil!",
"app.login.tab-login-credentials": "Entrar no HertzBeat",
"app.login.remember-me": "Lembrar de mim",
"app.login.login": "Entrar",
"app.login.notify": "Por favor, faça login!",
"app.login.explore.cloud": "Explorar Nuvem",
"app.login.explore.cloud.detail": "Clique para Explorar a Nuvem HertzBeat",
"tag.new": "Nova Tag",
"tag.edit": "Editar Tag",
"tag.search": "Pesquisar Tag",
"tag.delete": "Excluir Tag",
"tag": "Tag",
"tag.setting": "Tags",
"tag.id": "ID",
"tag.name": "Nome da Tag",
"tag.value": "Valor da Tag",
"tag.color": "Cor",
"tag.description": "Descrição",
"tag.update-time": "Tempo de Atualização",
"tag.display": "Exibir",
"tag.bind": "Vincular Tags",
"tag.bind.tip": "Você pode usar tags para gerenciamento de classificação. Ex: atribuir tags a recursos em ambiente de produção e teste.",
"tag.help": "As tags estão em todos os lugares no HertzBeat. Podemos aplicar tags no agrupamento de recursos, correspondência de tags sob regras e outros. [Gerenciamento de Tags] é usado para gerenciamento unificado de tags, incluindo adição, exclusão, edição, etc. <br>Você pode usar tags para classificar e gerenciar recursos de monitoramento, como vincular etiquetas para ambientes de produção e teste separadamente.",
"tag.help.link": "https://hertzbeat.apache.org/zh-cn/docs/",
"plugin.help": "No HertzBeat, podemos usar o mecanismo de plugin para realizar algumas outras operações após o alarme, exceto notificação. O gerenciamento de plugins é usado para gerenciamento unificado de plugins, incluindo upload e operações de habilitar/desabilitar.<br>Por exemplo, você pode usar o mecanismo de plugin para executar scripts específicos ou SQL após a ocorrência do alarme.",
"plugin.help.link": "https://hertzbeat.apache.org/docs/help/plugin",
"plugin.upload": "Carregar Plugin",
"plugin.name": "Nome do Plugin",
"plugin.type": "Tipo do Plugin",
"plugin.status": "Status Habilitado",
"plugin.jar.file": "Arquivo Jar",
"plugin.delete": "Excluir Plugin",
"plugin.type.POST_ALERT": "PÓS ALERTA",
"plugin.type.POST_COLLECT": "PÓS COLETA",
"plugin.search": "Pesquisar plugins",
"plugin.edit": "Editar plugin",
"plugin.param.edit": "Editar Parâmetros",
"define.help": "Os modelos de monitoramento definem cada tipo de monitoramento, variável de parâmetro, informações de métricas, protocolo de coleta, etc. Você pode selecionar um modelo de monitoramento existente no menu suspenso e fazer modificações de acordo com suas próprias necessidades. A área inferior esquerda é a área de comparação e a área inferior direita é o local de edição. <br> Você também pode clicar em \"Novo Tipo de Monitor\" para definir um novo tipo personalizado. Atualmente, os protocolos suportados incluem<a href='https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-http'> HTTP</a>, <a href='https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-jdbc'>JDBC</a>, <a href='https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-ssh'>SSH</a>, <a href='https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-jmx'>JMX</a>, <a href='https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-snmp'> SNMP</a>. <a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/template'>Modelos de Monitoramento</a>.",
"define.help.link": "https://hertzbeat.apache.org/zh-cn/docs/advanced/extend-point/",
"define.save-apply": "Salvar e Aplicar",
"define.delete": "Excluir {{app}}",
"define.delete.confirm": "Confirme se deseja excluir o tipo de monitoramento {{app}}? Este tipo de monitoramento não poderá ser adicionado após a exclusão.",
"define.new": "Novo Tipo de Monitor",
"define.new.code": "# Por favor, defina um novo tipo de monitoramento escrevendo o conteúdo YML aqui, consulte o documento: https://hertzbeat.apache.org/docs/advanced/extend-point ",
"define.save-apply.no-code": "O conteúdo da definição do tipo de monitoramento não pode estar vazio.",
"define.save-apply.confirm": "Confirme se deseja atualizar e aplicar a definição do monitor? Isso afetará o que você monitora.",
"define.hide-true.tip": "Não exibido no menu principal, se deseja exibi-lo",
"define.hide-true.confirm": "Confirme se deseja exibir este menu?",
"define.hide-false.tip": "Já exibido no menu principal, se deseja ocultá-lo",
"define.hide-false.confirm": "Confirme se deseja ocultar este menu?",
"settings.server": "Configuração do Servidor de Mensagens",
"settings.server.email": "Servidor de Email",
"settings.server.email.setting": "Configurar Servidor de Email",
"settings.server.sms": "Servidor de SMS",
"settings.server.sms.setting": "Configurar Servidor de SMS",
"settings.system-config": "Configuração do Sistema",
"settings.system-config.locale": "Idioma do Sistema",
"settings.system-config.locale.zh_CN": "Chinês Simplificado(zh_CN)",
"settings.system-config.locale.zh_TW": "Chinês Tradicional(zh_TW)",
"settings.system-config.locale.en_US": "Inglês(en_US)",
"settings.system-config.locale.pt_BR": "Português(pt_BR)",
"settings.system-config.timezone": "Fuso Horário do Sistema",
"settings.system-config.theme": "Tema do Sistema",
"settings.system-config.theme.default": "Tema Padrão",
"settings.system-config.theme.dark": "Tema Escuro",
"settings.system-config.theme.compact": "Tema Compacto",
"settings.system-config.ok": "Confirmar Atualização",
"settings.object-store": "Configuração do Servidor de Arquivos",
"settings.object-store.type": "Provedor do Servidor de Arquivos",
"settings.object-store.type.file": "Arquivo local (padrão)",
"settings.object-store.type.database": "Banco de dados local",
"settings.object-store.type.obs": "HUAWEI CLOUD OBS",
"settings.object-store.obs.accessKey": "AccessKey",
"settings.object-store.obs.accessKey.placeholder": "Access Key ID da HUAWEI CLOUD",
"settings.object-store.obs.secretKey": "SecretKey",
"settings.object-store.obs.secretKey.placeholder": "Access Key Secret da HUAWEI CLOUD",
"settings.object-store.obs.bucketName": "Bucket",
"settings.object-store.obs.bucketName.placeholder": "O nome do bucket que você criou na HUAWEI CLOUD OBS",
"settings.object-store.obs.endpoint": "EndPoint",
"settings.object-store.obs.endpoint.placeholder": "Domínio da HUAWEI CLOUD OBS, excluindo o nome do bucket",
"settings.object-store.obs.savePath": "Caminho de Salvamento",
"settings.object-store.obs.savePath.placeholder": "Caminho para salvar o arquivo de backup, O valor padrão é hertzbeat.",
"collector": "Coletor",
"collector.name": "Nome do Coletor",
"collector.name.placeholder": "Por favor, configure o nome único do coletor",
"collector.status": "Status Online",
"collector.mode": "Modo de Execução",
"collector.mode.public": "Cluster Público",
"collector.mode.private": "Nuvem-Private Edge",
"collector.task": "Total de Tarefas",
"collector.start-time": "Hora de Início",
"collector.ip": "Endereço IP",
"collector.version": "Versão",
"collector.node": "Nome do Nó",
"collector.pinned": "Tarefas Fixadas",
"collector.dispatched": "Tarefas Despachadas",
"collector.delete": "Excluir Coletor",
"collector.deploy": "Implantar Coletor",
"collector.deploy.identity": "Token do Coletor (IDENTIDADE)",
"collector.deploy.identity.tip": "Por favor, note que este token é único, mantenha-o seguro.",
"collector.deploy.ok": "Gerar Token e Comandos de Implantação",
"collector.deploy.close": "Fechar - Eu Salvei o Token",
"collector.deploy.docker": "Implantar via Docker",
"collector.deploy.docker.help": "# Execute o seguinte comando no ambiente Docker",
"collector.deploy.docker.help.1": "# docker run -d : Inicie um contêiner em execução em segundo plano através do Docker",
"collector.deploy.docker.help.2": "# -e IDENTITY=xxx : Defina o token de identidade do coletor",
"collector.deploy.docker.help.3": "# -e MANAGER_HOST=127.0.0.1 : Defina o endereço do serviço principal do HertzBeat para conexão",
"collector.deploy.docker.help.4": "# -e MODE=public : Defina o modo de execução (público ou privado), cluster público ou nuvem-private edge.",
"collector.deploy.docker.help.5": "# --name hertzbeat-collector: Nomeie o contêiner como hertzbeat-collector",
"collector.deploy.docker.help.6": "# apache/hertzbeat-collector: Fonte oficial da imagem do aplicativo, ou use quay.io/tancloud/hertzbeat-collector quando houver timeout",
"collector.deploy.package": "Implantar via Pacote",
"collector.deploy.package.github": "Baixar do Github",
"collector.deploy.package.gitee": "Baixar do Gitee",
"collector.deploy.package.help": "# Baixe o pacote de lançamento correspondente ao sistema hertzbeat-collector-xx.tar.gz",
"collector.deploy.package.help.1": "# Descompacte e configure o arquivo hertzbeat-collector/config/application.yml",
"collector.deploy.package.help.2": "# Substitua os parâmetros IDENTITY MANAGER_HOST MODE no arquivo como segue.",
"collector.deploy.package.help.3": "# Execute bin/startup.sh ou startup.bat(windows) para iniciar o coletor.",
"collector.online": "Coletor Online",
"collector.offline": "Coletor Offline",
"collector.confirm.online": "Confirme se deseja colocar este coletor online!",
"collector.confirm.offline": "Confirme se deseja colocar este coletor offline!",
"collector.confirm.online-batch": "Confirme se deseja colocar o coletor online em lote!",
"collector.confirm.offline-batch": "Confirme se deseja colocar o coletor offline em lote!",
"collector.notify.no-select-online": "Nenhum item selecionado para coletor online!",
"collector.notify.no-select-offline": "Nenhum item selecionado para coletor offline!",
"collector.help": "O Cluster de Coletores é usado para gerenciar nós de cluster de coletores registrados, exibir o status atual do coletor e a distribuição de tarefas de agendamento, e suporta operações como implantação, exclusão, offline de coletores.<br>Além de usar o coletor embutido, você pode registrar vários coletores para uso em cenários de <strong>Cluster de Alto Desempenho</strong> ou <strong>Colaboração Nuvem-Edge</strong>.",
"collector.help.link": "https://hertzbeat.apache.org/docs/help/guide",
"about.title": "Um sistema de monitoramento em tempo real de código aberto, sem agente, cluster, compatível com prometheus, personalizado e página de status.",
"about.point.1": "Monitoramento-alerta-notificação tudo em um, suporta web, banco de dados, sistema operacional, middleware, rede, etc.",
"about.point.2": "Fácil de usar, operações totalmente baseadas na web com apenas um clique do mouse.",
"about.point.3": "Capacidades poderosas de modelo de monitoramento, monitoramento personalizado de qualquer métrica que você desejar.",
"about.point.4": "Alto desempenho, suporta cluster de coletores, rede multi-isolada e nuvem-edge.",
"about.point.5": "Regras de limite de alarme flexíveis, notificação oportuna via discord, slack, telegram, etc.",
"about.point.6": "Construa facilmente uma página de status poderosa para comunicar o status em tempo real aos usuários.",
"about.help": "A poderosa personalização do HertzBeat, suporte a vários tipos, alto desempenho e fácil expansão, visa ajudar os usuários a construir rapidamente seu próprio sistema de monitoramento.",
"about.github": "Github",
"about.gitee": "Gitee",
"about.issue": "Feedback",
"about.pr": "Contribuir",
"about.discuss": "Discutir",
"about.doc": "Documento",
"about.upgrade": "Atualizar",
"about.star": "Estrela",
"status.page": "Página de Status",
"status.org.name": "Nome da Organização",
"status.org.name.tip": "O nome da equipe da organização exibido na página de status, como TanCloud",
"status.org.desc": "Introdução",
"status.org.desc.tip": "Introdução às informações da organização exibidas na página de status",
"status.org.logo": "Imagem do Logo",
"status.org.logo.tip": "Por favor, configure o endereço URL da imagem do logo da organização, sugere svg",
"status.org.home": "Link do Site",
"status.org.home.tip": "Por favor, configure o endereço da página inicial do site da organização",
"status.org.feedback": "Link de Feedback",
"status.org.feedback.tip": "Por favor, configure o endereço de contato de feedback dos usuários",
"status.org.color": "Cor do Tema",
"status.org.color.tip": "Por favor, configure a cor do tema da página de status",
"status.org.state": "Estado da Organização",
"status.public.feedback": "FEEDBACK DE PROBLEMAS",
"status.public.org.state.0": "Todos os Sistemas Operacionais",
"status.public.org.state.1": "Alguns Sistemas Anormais",
"status.public.org.state.2": "Todos os Sistemas Anormais",
"status.public.today": "Hoje",
"status.public.30-day": "30 dias atrás",
"status.public.power-by": "Desenvolvido por Apache HertzBeat. Dê-nos uma estrela!",
"status.public.to-incident": "Histórico de Incidentes",
"status.public.to-component": "Página de Status",
"status.incident": "Incidente",
"status.incident.name": "Nome do Incidente",
"status.incident.name.tip": "Por favor, descreva brevemente o título do incidente atual",
"status.incident.history": "Histórico de Incidentes",
"status.incident.state": "Status do Incidente",
"status.incident.state.0": "Investigando",
"status.incident.state.1": "Identificado",
"status.incident.state.2": "Monitorando",
"status.incident.state.3": "Resolvido",
"status.incident.message": "Publicar Mensagem",
"status.incident.message.tip.0": "Estamos investigando este incidente, por favor, verifique novamente mais tarde para atualizações.",
"status.incident.message.tip.1": "Confirmamos a causa da falha e estamos processando.",
"status.incident.message.tip.2": "Estamos monitorando este evento e observando o efeito do processamento",
"status.incident.message.tip.3": "Este incidente foi resolvido, obrigado pela compreensão e apoio.",
"status.incident.message-latest": "Última Mensagem",
"status.incident.component": "Componente Afetado",
"status.incident.new": "Publicar Incidente",
"status.incident.update": "Atualizar Incidente",
"status.incident.delete": "Excluir Incidente",
"status.incident.public.start-at": "Iniciar em",
"status.incident.public.update-at": "Atualizar em",
"status.incident.public.process-time": "Tempo de Processamento",
"status.component": "Componente",
"status.component.name": "Componente de Serviço",
"status.component.name.tip": "Configurar o nome do componente de serviço exibido, como Gateway",
"status.component.desc": "Descrição do Componente",
"status.component.desc.tip": "Configurar informações de descrição do componente de serviço",
"status.component.state": "Estado do Componente",
"status.component.new": "Novo Componente",
"status.component.edit": "Editar Componente",
"status.component.delete": "Excluir Componente",
"status.component.tag": "Corresponder Tag",
"status.component.tag.tip": "O cálculo do status associa a etiqueta e usa todos os status de disponibilidade de monitoramento associados à etiqueta como dados para calcular o status do serviço deste componente.",
"status.component.method": "Modo de Cálculo do Status",
"status.component.method.tip": "A forma de calcular o status do serviço do componente é calcular automaticamente a disponibilidade com base no monitoramento de associação de tags ou configurar manualmente o status.",
"status.component.method.0": "Cálculo Automático",
"status.component.method.1": "Configuração Manual",
"status.component.config-state": "Estado de Configuração",
"status.component.config-state.tip": "Quando o modo de cálculo do status é manual, o estado do serviço do componente configurado.",
"status.component.state.0": "Normal",
"status.component.state.1": "Anormal",
"status.component.state.2": "Desconhecido",
"status.component.notify.need-org": "Por favor, configure as informações da sua organização primeiro!",
"status.help": "Construa rapidamente uma página de status poderosa com base no HertzBeat para comunicar facilmente o status em tempo real dos seus serviços aos usuários. Por exemplo, a página de status fornecida pelo Github <a href='https://www.githubstatus.com'> https://www.githubstatus.com</a>. <br>Suporta vinculação e sincronização do status do componente da página de status e status de monitoramento, manutenção e gerenciamento de eventos de falha, etc. Melhore sua transparência, profissionalismo e confiança do usuário, e reduza os custos de comunicação.",
"status.help.link": "https://hertzbeat.apache.org/docs/help/status",
"validation.email.required": "Por favor, insira seu email!",
"validation.email.wrong-format": "O endereço de email está no formato errado!",
"validation.password.required": "Por favor, insira sua senha!",
"validation.password.twice": "As senhas inseridas duas vezes não coincidem!",
"validation.password.strength.msg": "Por favor, insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.",
"validation.password.strength.strong": "Força: forte",
"validation.password.strength.medium": "Força: média",
"validation.password.strength.short": "Força: muito curta",
"validation.confirm-password.required": "Por favor, confirme sua senha!",
"validation.phone-number.required": "Por favor, insira seu número de telefone!",
"validation.phone-number.wrong-format": "Número de telefone mal formatado!",
"validation.verification-code.required": "Por favor, insira o código de verificação!",
"validation.title.required": "Por favor, insira um título",
"validation.date.required": "Por favor, selecione a data de início e término",
"validation.goal.required": "Por favor, insira uma descrição do objetivo",
"validation.standard.required": "Por favor, insira uma métrica",
"expand": "Expandir",
"collapse": "Recolher"
}
+2
View File
@@ -437,6 +437,7 @@
"common.file.select": "选择文件",
"common.ignore": "忽略",
"common.mute": "静音",
"common.unmute": "取消静音",
"common.name": "指标名",
"common.new-time": "创建时间",
"common.no": "否",
@@ -772,6 +773,7 @@
"settings.system-config.locale.zh_CN": "简体中文(zh_CN)",
"settings.system-config.locale.zh_TW": "繁体中文(zh_TW)",
"settings.system-config.locale.ja-JP": "日语(ja_JP)",
"settings.system-config.locale.pt_BR": "Português(pt_BR)",
"settings.system-config.ok": "确认更新",
"settings.system-config.theme": "系统主题",
"settings.system-config.theme.compact": "紧凑主题",
+2
View File
@@ -437,6 +437,7 @@
"common.file.select": "選擇文件",
"common.ignore": "忽略",
"common.mute": "靜音",
"common.unmute": "取消靜音",
"common.name": "指標名",
"common.new-time": "創建時間",
"common.no": "否",
@@ -772,6 +773,7 @@
"settings.system-config.locale.zh_CN": "簡體中文(zh_CN)",
"settings.system-config.locale.zh_TW": "繁體中文(zh_TW)",
"settings.system-config.locale.ja-JP": "日語(ja_JP)",
"settings.system-config.locale.pt_BR": "Português(pt_BR)",
"settings.system-config.ok": "確認更新",
"settings.system-config.theme": "系統主題",
"settings.system-config.theme.compact": "緊湊主題",