18
18
package org .apache .hertzbeat .alert .service .impl ;
19
19
20
20
import lombok .extern .slf4j .Slf4j ;
21
+ import org .apache .commons .lang3 .StringUtils ;
21
22
import org .apache .hertzbeat .alert .dto .TencentCloudExternAlert ;
22
23
import org .apache .hertzbeat .alert .reduce .AlarmCommonReduce ;
23
24
import org .apache .hertzbeat .alert .service .ExternAlertService ;
25
+ import org .apache .hertzbeat .common .constants .CommonConstants ;
24
26
import org .apache .hertzbeat .common .entity .alerter .SingleAlert ;
25
27
import org .apache .hertzbeat .common .util .JsonUtil ;
26
28
import org .springframework .beans .factory .annotation .Autowired ;
27
29
import org .springframework .stereotype .Service ;
28
30
31
+ import java .text .ParseException ;
32
+ import java .text .SimpleDateFormat ;
33
+ import java .util .HashMap ;
34
+ import java .util .Map ;
35
+ import java .util .Objects ;
36
+
29
37
/**
30
38
* Default external alarm service impl
31
39
*/
@@ -43,13 +51,177 @@ public void addExternAlert(String content) {
43
51
log .warn ("parse extern alert content failed! content: {}" , content );
44
52
return ;
45
53
}
46
- // todo convert TenCloudAlertReport to SingleAlert
47
- SingleAlert alert = new SingleAlert ();
54
+ SingleAlert alert = new TencentCloudAlertConverter ().convert (report );
48
55
alarmCommonReduce .reduceAndSendAlarm (alert );
49
56
}
50
57
51
58
@ Override
52
59
public String supportSource () {
53
60
return "tencent" ;
54
61
}
62
+
63
+ /**
64
+ * Converter: TencentCloud alert to SingleAlert
65
+ */
66
+ public static class TencentCloudAlertConverter {
67
+
68
+ /**
69
+ * Metric alert content template
70
+ */
71
+ private final String metricTemplate = "Tencent Cloud Metric Alert: {metricShowName} {calcType} {calcValue}{calcUnit}, Current: {currentValue}{unit}" ;
72
+
73
+ /**
74
+ * Event alert content template
75
+ */
76
+ private final String eventTemplate = "Tencent Cloud Event Alert: {productShowName} - {eventShowName}" ;
77
+
78
+
79
+ /**
80
+ * Convert TencentCloud alert to SingleAlert
81
+ */
82
+ public SingleAlert convert (TencentCloudExternAlert tencentAlert ) {
83
+ // Building basic information
84
+ SingleAlert .SingleAlertBuilder builder = SingleAlert .builder ()
85
+ .status (convertStatus (tencentAlert .getAlarmStatus ()))
86
+ .startAt (parseTime (tencentAlert .getFirstOccurTime ()))
87
+ .activeAt (parseTime (tencentAlert .getFirstOccurTime ()))
88
+ .triggerTimes (1 );
89
+ // If it is a recovery state, set the end time.
90
+ if ("0" .equals (tencentAlert .getAlarmStatus ())) {
91
+ builder .endAt (parseTime (tencentAlert .getRecoverTime ()));
92
+ }
93
+
94
+ // Build labels
95
+ Map <String , String > labels = new HashMap <>();
96
+ buildLabels (labels , tencentAlert );
97
+
98
+ // Build annotations
99
+ Map <String , String > annotations = new HashMap <>();
100
+ buildAnnotations (annotations , tencentAlert );
101
+
102
+ // Build content
103
+ String content = generateContent (tencentAlert );
104
+
105
+ return builder
106
+ .labels (labels )
107
+ .annotations (annotations )
108
+ .content (content )
109
+ .build ();
110
+ }
111
+
112
+ private void buildLabels (Map <String , String > labels , TencentCloudExternAlert alert ) {
113
+ labels .put ("__source__" , "tencent_cloud" );
114
+ labels .put ("alert_type" , alert .getAlarmType ());
115
+ if (TencentCloudExternAlert .METRIC .equals (alert .getAlarmType ())) {
116
+ labels .put ("metric_name" , alert .getAlarmPolicyInfo ().getConditions ().getMetricName ());
117
+ labels .put ("namespace" , alert .getAlarmObjInfo ().getNamespace ());
118
+ } else {
119
+ labels .put ("event_name" , alert .getAlarmPolicyInfo ().getConditions ().getEventName ());
120
+ labels .put ("product_name" , alert .getAlarmPolicyInfo ().getConditions ().getProductName ());
121
+ }
122
+ }
123
+
124
+ private void buildAnnotations (Map <String , String > annotations , TencentCloudExternAlert alert ) {
125
+ TencentCloudExternAlert .AlarmPolicyInfo alarmPolicyInfo = alert .getAlarmPolicyInfo ();
126
+ TencentCloudExternAlert .AlarmObjInfo alarmObjInfo = alert .getAlarmObjInfo ();
127
+ TencentCloudExternAlert .Dimensions dimensions = alert .getAlarmObjInfo ().getDimensions ();
128
+
129
+ putIfNotNull (annotations , "policy_id" , alarmPolicyInfo .getPolicyId ());
130
+ putIfNotNull (annotations , "policy_type" , alarmPolicyInfo .getPolicyType ());
131
+ putIfNotNull (annotations , "policy_name" , alarmPolicyInfo .getPolicyName ());
132
+ putIfNotNull (annotations , "policy_type_cname" , alarmPolicyInfo .getPolicyTypeCname ());
133
+
134
+ putIfNotNull (annotations , "namespace" , alarmObjInfo .getNamespace ());
135
+ putIfNotNull (annotations , "region" , alarmObjInfo .getRegion ());
136
+ putIfNotNull (annotations , "app_id" , alarmObjInfo .getAppId ());
137
+ putIfNotNull (annotations , "uin" , alarmObjInfo .getUin ());
138
+
139
+ putIfNotNull (annotations , "instance_id" , dimensions .getUnInstanceId ());
140
+ putIfNotNull (annotations , "obj_id" , dimensions .getObjId ());
141
+
142
+ }
143
+
144
+ /**
145
+ * Generate alert content with template
146
+ */
147
+ private String generateContent (TencentCloudExternAlert alert ) {
148
+ if (TencentCloudExternAlert .METRIC .equals (alert .getAlarmType ())) {
149
+ return generateMetricContent (alert );
150
+ } else {
151
+ return generateEventContent (alert );
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Generate metric alert content
157
+ */
158
+ private String generateMetricContent (TencentCloudExternAlert alert ) {
159
+ TencentCloudExternAlert .Conditions conditions = alert .getAlarmPolicyInfo ().getConditions ();
160
+ Map <String , String > params = new HashMap <>();
161
+
162
+ params .put ("metricShowName" , conditions .getMetricShowName ());
163
+
164
+ if (StringUtils .isNotEmpty (conditions .getCalcType ())
165
+ && StringUtils .isNotEmpty (conditions .getCalcValue ())) {
166
+ params .put ("calcType" , conditions .getCalcType ());
167
+ params .put ("calcValue" , conditions .getCalcValue ());
168
+ params .put ("calcUnit" , Objects .toString (conditions .getCalcUnit (), "" ));
169
+ } else {
170
+ params .put ("calcType" , "" );
171
+ params .put ("calcValue" , "N/A" );
172
+ params .put ("calcUnit" , "" );
173
+ }
174
+
175
+ if (StringUtils .isNotEmpty (conditions .getCurrentValue ())) {
176
+ params .put ("currentValue" , conditions .getCurrentValue ());
177
+ params .put ("unit" , Objects .toString (conditions .getUnit (), "" ));
178
+ } else {
179
+ params .put ("currentValue" , "N/A" );
180
+ params .put ("unit" , "" );
181
+ }
182
+ return replacePlaceholders (metricTemplate , params );
183
+ }
184
+
185
+ /**
186
+ * Generate event alert content
187
+ */
188
+ private String generateEventContent (TencentCloudExternAlert alert ) {
189
+ TencentCloudExternAlert .Conditions conditions = alert .getAlarmPolicyInfo ().getConditions ();
190
+ Map <String , String > params = new HashMap <>();
191
+ params .put ("productShowName" , conditions .getProductShowName ());
192
+ params .put ("eventShowName" , conditions .getEventShowName ());
193
+ return replacePlaceholders (eventTemplate , params );
194
+ }
195
+
196
+ /**
197
+ * Replace placeholders in template with actual values
198
+ */
199
+ private String replacePlaceholders (String template , Map <String , String > params ) {
200
+ String result = template ;
201
+ for (Map .Entry <String , String > entry : params .entrySet ()) {
202
+ result = result .replace ("{" + entry .getKey () + "}" , Objects .toString (entry .getValue (), "NULL" ));
203
+ }
204
+ return result ;
205
+ }
206
+
207
+ private String convertStatus (String alarmStatus ) {
208
+ return "1" .equals (alarmStatus ) ? CommonConstants .ALERT_STATUS_FIRING : CommonConstants .ALERT_STATUS_RESOLVED ;
209
+ }
210
+
211
+ private Long parseTime (String timeStr ) {
212
+ try {
213
+ SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" );
214
+ return sdf .parse (timeStr ).getTime ();
215
+ } catch (ParseException e ) {
216
+ log .error ("Failed to parse time: {}" , timeStr );
217
+ throw new IllegalArgumentException ("Failed to parse time: " + timeStr , e );
218
+ }
219
+ }
220
+
221
+ private void putIfNotNull (Map <String , String > map , String key , String value ){
222
+ if (StringUtils .isNotEmpty (value )){
223
+ map .put (key , value );
224
+ }
225
+ }
226
+ }
55
227
}
0 commit comments