Skip to content

Commit 36aa3fa

Browse files
authored
Merge cf4c6ed into 5afd941
2 parents 5afd941 + cf4c6ed commit 36aa3fa

File tree

12 files changed

+478
-3
lines changed

12 files changed

+478
-3
lines changed

dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-all/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
<artifactId>dolphinscheduler-alert-all</artifactId>
2828

2929
<dependencies>
30+
<dependency>
31+
<groupId>org.apache.dolphinscheduler</groupId>
32+
<artifactId>dolphinscheduler-alert-prometheus</artifactId>
33+
<version>${project.version}</version>
34+
</dependency>
3035
<dependency>
3136
<groupId>org.apache.dolphinscheduler</groupId>
3237
<artifactId>dolphinscheduler-alert-dingtalk</artifactId>

dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-api/src/main/java/org/apache/dolphinscheduler/alert/api/AlertInputTips.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public enum AlertInputTips {
5050
SECRET("please input secret", "请输入secret"),
5151
WECHAT_MENTION_USERS("use `|` to separate userIds and `@all` to everyone", "使用`|`来分割userId或使用`@all`来提到所有人"),
5252
WECHAT_AGENT_ID("please input agent id or chat id", "请输入agent id或chat id"),
53-
;
53+
ANNOTATION("please input annotation in json form", "请输入json格式的annotation"),
54+
GENERATOR_URL("please input Generator URL", "请输入生成地址");
5455

5556
private final String enMsg;
5657
private final String zhMsg;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>org.apache.dolphinscheduler</groupId>
23+
<artifactId>dolphinscheduler-alert-plugins</artifactId>
24+
<version>dev-SNAPSHOT</version>
25+
</parent>
26+
<artifactId>dolphinscheduler-alert-prometheus</artifactId>
27+
<packaging>jar</packaging>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>org.apache.dolphinscheduler</groupId>
32+
<artifactId>dolphinscheduler-alert-api</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.apache.httpcomponents</groupId>
36+
<artifactId>httpclient</artifactId>
37+
</dependency>
38+
</dependencies>
39+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.plugin.alert.prometheus;
19+
20+
import org.apache.dolphinscheduler.alert.api.AlertChannel;
21+
import org.apache.dolphinscheduler.alert.api.AlertData;
22+
import org.apache.dolphinscheduler.alert.api.AlertInfo;
23+
import org.apache.dolphinscheduler.alert.api.AlertResult;
24+
25+
import java.util.Map;
26+
27+
public final class PrometheusAlertChannel implements AlertChannel {
28+
29+
@Override
30+
public AlertResult process(AlertInfo info) {
31+
AlertData alertData = info.getAlertData();
32+
Map<String, String> paramsMap = info.getAlertParams();
33+
if (null == paramsMap) {
34+
return new AlertResult("false", "prometheus alert manager params is null");
35+
}
36+
return new PrometheusAlertSender(paramsMap).sendMessage(alertData);
37+
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.plugin.alert.prometheus;
19+
20+
import org.apache.dolphinscheduler.alert.api.AlertChannel;
21+
import org.apache.dolphinscheduler.alert.api.AlertChannelFactory;
22+
import org.apache.dolphinscheduler.alert.api.AlertInputTips;
23+
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
24+
import org.apache.dolphinscheduler.spi.params.base.Validate;
25+
import org.apache.dolphinscheduler.spi.params.input.InputParam;
26+
27+
import java.util.Arrays;
28+
import java.util.List;
29+
30+
import com.google.auto.service.AutoService;
31+
32+
@AutoService(AlertChannelFactory.class)
33+
public final class PrometheusAlertChannelFactory implements AlertChannelFactory {
34+
35+
@Override
36+
public String name() {
37+
return "Prometheus AlertManager";
38+
}
39+
40+
@Override
41+
public List<PluginParams> params() {
42+
InputParam urlParam =
43+
InputParam
44+
.newBuilder(PrometheusAlertConstants.NAME_ALERT_MANAGER_URL,
45+
PrometheusAlertConstants.ALERT_MANAGER_URL)
46+
.setPlaceholder(AlertInputTips.URL.getMsg())
47+
.addValidate(Validate.newBuilder()
48+
.setRequired(true)
49+
.build())
50+
.build();
51+
InputParam annotationParam =
52+
InputParam
53+
.newBuilder(PrometheusAlertConstants.NAME_ALERT_MANAGER_ANNOTATIONS,
54+
PrometheusAlertConstants.ALERT_MANAGER_ANNOTATIONS)
55+
.setPlaceholder(AlertInputTips.ANNOTATION.getMsg())
56+
.addValidate(Validate.newBuilder()
57+
.setRequired(false).build())
58+
.build();
59+
InputParam generatorUrlParam =
60+
InputParam
61+
.newBuilder(PrometheusAlertConstants.NAME_GENERATOR_URL, PrometheusAlertConstants.GENERATOR_URL)
62+
.setPlaceholder(AlertInputTips.GENERATOR_URL.getMsg())
63+
.addValidate(Validate.newBuilder()
64+
.setRequired(false).build())
65+
.build();
66+
67+
return Arrays.asList(urlParam, annotationParam, generatorUrlParam);
68+
}
69+
70+
@Override
71+
public AlertChannel create() {
72+
return new PrometheusAlertChannel();
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.plugin.alert.prometheus;
19+
20+
public class PrometheusAlertConstants {
21+
22+
static final String ALERT_MANAGER_URL = "$t('url')";
23+
static final String NAME_ALERT_MANAGER_URL = "url";
24+
static final String ALERT_MANAGER_ANNOTATIONS = "$t('annotations')";
25+
static final String NAME_ALERT_MANAGER_ANNOTATIONS = "annotations";
26+
static final String ALERT_V2_API_PATH = "/api/v2/alerts";
27+
static final String GENERATOR_URL = "$t('generatorURL')";
28+
static final String NAME_GENERATOR_URL = "generatorURL";
29+
static final String ALERT_SUCCESS = "alert success";
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.plugin.alert.prometheus;
19+
20+
import org.apache.dolphinscheduler.alert.api.AlertData;
21+
import org.apache.dolphinscheduler.alert.api.AlertResult;
22+
import org.apache.dolphinscheduler.alert.api.HttpServiceRetryStrategy;
23+
import org.apache.dolphinscheduler.common.utils.JSONUtils;
24+
25+
import org.apache.commons.collections4.CollectionUtils;
26+
import org.apache.http.HttpEntity;
27+
import org.apache.http.HttpStatus;
28+
import org.apache.http.client.methods.CloseableHttpResponse;
29+
import org.apache.http.client.methods.HttpPost;
30+
import org.apache.http.entity.ContentType;
31+
import org.apache.http.entity.StringEntity;
32+
import org.apache.http.impl.client.CloseableHttpClient;
33+
import org.apache.http.impl.client.HttpClients;
34+
import org.apache.http.util.EntityUtils;
35+
36+
import java.io.IOException;
37+
import java.text.SimpleDateFormat;
38+
import java.util.ArrayList;
39+
import java.util.Date;
40+
import java.util.HashMap;
41+
import java.util.List;
42+
import java.util.Map;
43+
import java.util.Objects;
44+
45+
import lombok.extern.slf4j.Slf4j;
46+
47+
@Slf4j
48+
public class PrometheusAlertSender {
49+
50+
private String url;
51+
private String generatorURL;
52+
private String annotations;
53+
54+
public PrometheusAlertSender(Map<String, String> config) {
55+
url = config.get(PrometheusAlertConstants.NAME_ALERT_MANAGER_URL);
56+
generatorURL = config.get(PrometheusAlertConstants.NAME_GENERATOR_URL);
57+
annotations = config.get(PrometheusAlertConstants.NAME_ALERT_MANAGER_ANNOTATIONS);
58+
}
59+
60+
public AlertResult sendMessage(AlertData alertData) {
61+
AlertResult alertResult;
62+
try {
63+
String resp = sendMsg(alertData);
64+
return checkSendAlertManageMsgResult(resp);
65+
} catch (Exception e) {
66+
String errorMsg = String.format("send prometheus alert manager alert error, exception: %s", e.getMessage());
67+
log.error(errorMsg);
68+
alertResult = new AlertResult();
69+
alertResult.setStatus("false");
70+
alertResult.setMessage(errorMsg);
71+
}
72+
return alertResult;
73+
}
74+
75+
private String sendMsg(AlertData alertData) throws IOException {
76+
String v2Path = String.format("%s%s", this.url, PrometheusAlertConstants.ALERT_V2_API_PATH);
77+
String msg = generateContentJson(alertData);
78+
HttpPost httpPost = constructHttpPost(v2Path, msg);
79+
80+
try (CloseableHttpClient httpClient = getDefaultClient()) {
81+
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
82+
String resp;
83+
int statusCode = response.getStatusLine().getStatusCode();
84+
if (statusCode == HttpStatus.SC_OK) {
85+
resp = PrometheusAlertConstants.ALERT_SUCCESS;
86+
log.info("Prometheus alert manager send alert succeed, title: {} ,content: {}",
87+
alertData.getTitle(),
88+
alertData.getContent());
89+
return resp;
90+
}
91+
92+
HttpEntity entity = response.getEntity();
93+
resp = EntityUtils.toString(entity, "utf-8");
94+
EntityUtils.consume(entity);
95+
log.error(
96+
"Prometheus alert manager send alert failed, http status code: {}, title: {} ,content: {}, resp: {}",
97+
statusCode,
98+
alertData.getTitle(),
99+
alertData.getContent(), resp);
100+
101+
return resp;
102+
}
103+
}
104+
}
105+
106+
public AlertResult checkSendAlertManageMsgResult(String resp) {
107+
AlertResult alertResult = new AlertResult();
108+
alertResult.setStatus("false");
109+
110+
if (Objects.equals(resp, PrometheusAlertConstants.ALERT_SUCCESS)) {
111+
alertResult.setStatus("true");
112+
alertResult.setMessage("prometheus alert manager send success");
113+
return alertResult;
114+
}
115+
116+
alertResult.setMessage(String.format("prometheus alert manager send fail, resp is %s", resp));
117+
log.info("send prometheus alert manager msg error, resp error");
118+
return alertResult;
119+
}
120+
121+
public String generateContentJson(AlertData alertData) {
122+
List<HashMap> list = JSONUtils.toList(alertData.getContent(), HashMap.class);
123+
HashMap<String, String> labels = new HashMap<>();
124+
if (CollectionUtils.isEmpty(list)) {
125+
labels.put("content", alertData.getContent());
126+
}
127+
for (Map map : list) {
128+
for (Map.Entry<String, Object> entry : (Iterable<Map.Entry<String, Object>>) map.entrySet()) {
129+
String key = entry.getKey();
130+
String value = entry.getValue().toString();
131+
labels.put(key, value);
132+
}
133+
}
134+
labels.put("title", alertData.getTitle());
135+
136+
Map<String, Object> alert = new HashMap<>();
137+
alert.put("labels", labels);
138+
139+
Map<String, String> annotations = JSONUtils.toMap(this.annotations);
140+
if (annotations != null) {
141+
alert.put("annotations", annotations);
142+
}
143+
144+
String formattedTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(new Date());
145+
alert.put("startsAt", formattedTime);
146+
alert.put("endsAt", formattedTime);
147+
148+
if (generatorURL != null && generatorURL.length() != 0) {
149+
alert.put("generatorURL", generatorURL);
150+
}
151+
List<Map<String, Object>> body = new ArrayList<>();
152+
body.add(alert);
153+
return JSONUtils.toJsonString(body);
154+
}
155+
156+
private static CloseableHttpClient getDefaultClient() {
157+
return HttpClients.custom().setRetryHandler(HttpServiceRetryStrategy.retryStrategy).build();
158+
}
159+
160+
private static HttpPost constructHttpPost(String url, String msg) {
161+
HttpPost post = new HttpPost(url);
162+
StringEntity entity = new StringEntity(msg, ContentType.APPLICATION_JSON);
163+
post.setEntity(entity);
164+
return post;
165+
}
166+
}

0 commit comments

Comments
 (0)