├── errorrecord.log ├── .idea ├── vcs.xml ├── encodings.xml ├── modules.xml ├── misc.xml ├── libraries │ ├── Maven__org_mongodb_bson_3_4_2.xml │ ├── Maven__com_tdunning_t_digest_3_0.xml │ ├── Maven__org_yaml_snakeyaml_1_17.xml │ ├── Maven__com_carrotsearch_hppc_0_7_1.xml │ ├── Maven__com_google_guava_guava_18_0.xml │ ├── Maven__com_twitter_jsr166e_1_1_0.xml │ ├── Maven__joda_time_joda_time_2_9_7.xml │ ├── Maven__com_spatial4j_spatial4j_0_5.xml │ ├── Maven__org_slf4j_slf4j_api_1_7_24.xml │ ├── Maven__com_google_code_gson_gson_2_8_2.xml │ ├── Maven__org_elasticsearch_securesm_1_0.xml │ ├── Maven__com_fasterxml_classmate_1_3_3.xml │ ├── Maven__com_ning_compress_lzf_1_0_2.xml │ ├── Maven__io_netty_netty_3_10_6_Final.xml │ ├── Maven__commons_cli_commons_cli_1_3_1.xml │ ├── Maven__org_slf4j_jul_to_slf4j_1_7_24.xml │ ├── Maven__commons_codec_commons_codec_1_10.xml │ ├── Maven__org_mongodb_mongodb_driver_3_4_2.xml │ ├── Maven__org_slf4j_jcl_over_slf4j_1_7_24.xml │ ├── Maven__org_apache_lucene_lucene_core_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_join_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_misc_5_5_2.xml │ ├── Maven__ch_qos_logback_logback_core_1_1_11.xml │ ├── Maven__org_hdrhistogram_HdrHistogram_2_1_6.xml │ ├── Maven__org_slf4j_log4j_over_slf4j_1_7_24.xml │ ├── Maven__org_apache_httpcomponents_httpcore_4_4_6.xml │ ├── Maven__org_apache_lucene_lucene_memory_5_5_2.xml │ ├── Maven__org_elasticsearch_elasticsearch_2_4_4.xml │ ├── Maven__ch_qos_logback_logback_classic_1_1_11.xml │ ├── Maven__commons_logging_commons_logging_1_1_3.xml │ ├── Maven__org_apache_lucene_lucene_queries_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_sandbox_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_spatial_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_suggest_5_5_2.xml │ ├── Maven__org_apache_httpcomponents_httpclient_4_5_3.xml │ ├── Maven__org_apache_lucene_lucene_grouping_5_5_2.xml │ ├── Maven__org_mongodb_mongodb_driver_core_3_4_2.xml │ ├── Maven__org_apache_lucene_lucene_spatial3d_5_5_2.xml │ ├── Maven__org_apache_httpcomponents_httpcore_nio_4_4_5.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_core_2_8_7.xml │ ├── Maven__org_apache_lucene_lucene_highlighter_5_5_2.xml │ ├── Maven__org_apache_lucene_lucene_queryparser_5_5_2.xml │ ├── Maven__org_springframework_spring_tx_4_3_7_RELEASE.xml │ ├── Maven__org_jboss_logging_jboss_logging_3_3_0_Final.xml │ ├── Maven__javax_validation_validation_api_1_1_0_Final.xml │ ├── Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_11.xml │ ├── Maven__org_springframework_spring_aop_4_3_7_RELEASE.xml │ ├── Maven__org_springframework_spring_web_4_3_7_RELEASE.xml │ ├── Maven__org_apache_httpcomponents_httpasyncclient_4_1_3.xml │ ├── Maven__org_springframework_spring_core_4_3_7_RELEASE.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_databind_2_8_7.xml │ ├── Maven__org_springframework_spring_beans_4_3_7_RELEASE.xml │ ├── Maven__org_apache_lucene_lucene_backward_codecs_5_5_2.xml │ ├── Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_11.xml │ ├── Maven__org_springframework_spring_webmvc_4_3_7_RELEASE.xml │ ├── Maven__org_elasticsearch_plugin_parent_join_client_5_6_4.xml │ ├── Maven__org_hibernate_hibernate_validator_5_3_4_Final.xml │ ├── Maven__org_apache_lucene_lucene_analyzers_common_5_5_2.xml │ ├── Maven__org_springframework_boot_spring_boot_1_5_2_RELEASE.xml │ ├── Maven__org_springframework_spring_context_4_3_7_RELEASE.xml │ ├── Maven__com_fasterxml_jackson_core_jackson_annotations_2_8_0.xml │ ├── Maven__org_springframework_spring_expression_4_3_7_RELEASE.xml │ ├── Maven__org_apache_tomcat_embed_tomcat_embed_websocket_8_5_11.xml │ ├── Maven__org_elasticsearch_plugin_aggs_matrix_stats_client_5_6_4.xml │ ├── Maven__org_elasticsearch_client_elasticsearch_rest_client_5_6_4.xml │ ├── Maven__org_springframework_boot_spring_boot_starter_1_5_2_RELEASE.xml │ ├── Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_cbor_2_8_7.xml │ ├── Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_8_7.xml │ ├── Maven__org_springframework_data_spring_data_commons_1_13_1_RELEASE.xml │ ├── Maven__org_springframework_data_spring_data_mongodb_1_10_1_RELEASE.xml │ ├── Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_smile_2_8_7.xml │ ├── Maven__org_springframework_boot_spring_boot_starter_web_1_5_2_RELEASE.xml │ ├── Maven__org_springframework_boot_spring_boot_autoconfigure_1_5_2_RELEASE.xml │ ├── Maven__org_springframework_boot_spring_boot_starter_tomcat_1_5_2_RELEASE.xml │ ├── Maven__org_springframework_boot_spring_boot_starter_logging_1_5_2_RELEASE.xml │ ├── Maven__org_elasticsearch_client_elasticsearch_rest_high_level_client_5_6_4.xml │ └── Maven__org_springframework_boot_spring_boot_starter_data_mongodb_1_5_2_RELEASE.xml ├── compiler.xml └── uiDesigner.xml ├── Dockerfile ├── src └── main │ ├── java │ └── com │ │ └── haier │ │ └── alertmanager │ │ ├── test │ │ └── controller │ │ │ ├── RegexTest.java │ │ │ ├── Test.java │ │ │ ├── MongoDBTest.java │ │ │ ├── ESSaveTest.java │ │ │ ├── TemplateTest.java │ │ │ ├── ESQueryTest.java │ │ │ └── ApiTest.java │ │ ├── notifyhandlers │ │ ├── INotifyStorageHandler.java │ │ ├── INotifySendHanlder.java │ │ ├── ESNotifyStorageHandler.java │ │ └── NotifySendCommonHandler.java │ │ ├── AlertManagerWebApplication.java │ │ ├── configuration │ │ ├── AlertConstVariable.java │ │ ├── AlertManagerCode.java │ │ ├── MongoConfiguration.java │ │ ├── ElasticsearchConfiguration.java │ │ └── AlertConfigurationProp.java │ │ ├── service │ │ ├── HistoryStoreService.java │ │ ├── NotifySendService.java │ │ ├── LogService.java │ │ └── ReceiverService.java │ │ ├── model │ │ ├── ApiResult.java │ │ ├── AlertDictionary.java │ │ ├── MessageReceiverInfo.java │ │ ├── AlertExcluse.java │ │ └── AlertRecord.java │ │ ├── template │ │ └── SimpleTemplate.java │ │ └── container │ │ ├── AlertExcluseContainer.java │ │ ├── AlertRecordContainer.java │ │ ├── MessageReceiverContainer.java │ │ └── AlertDictionaryContainer.java │ └── resources │ ├── notifysend │ ├── esmapping6.x.json │ ├── esmapping5.x.json │ └── personlist.list │ ├── application-test.yml │ ├── application-prod.yml │ └── application.yml ├── pom.xml ├── 201711.log ├── alertmanager.iml └── README.md /errorrecord.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java 2 | # !!重要!! 请替换下面的 {targetJarName} 为真实打包出的目标 jar 包 3 | ADD alertmanager-1.0-SNAPSHOT.jar /application.jar 4 | WORKDIR / 5 | #设置时区 6 | RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 7 | && echo 'Asia/Shanghai' >/etc/timezone \ 8 | EXPOSE 8080 9 | CMD ["java", "-jar", "application.jar","--spring.profiles.active=prod"] -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/RegexTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class RegexTest { 7 | 8 | public static void main(String[] args){ 9 | String pp = "*"; 10 | pp = pp.replace("*","[\\w\\-]*"); 11 | Pattern p = Pattern.compile( pp); 12 | String str = "ab-cd"; 13 | Matcher m = p.matcher(str); 14 | System.out.println(m.matches()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_mongodb_bson_3_4_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_tdunning_t_digest_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_yaml_snakeyaml_1_17.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_carrotsearch_hppc_0_7_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_guava_guava_18_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_twitter_jsr166e_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__joda_time_joda_time_2_9_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_spatial4j_spatial4j_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_24.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_code_gson_gson_2_8_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_securesm_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_classmate_1_3_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_ning_compress_lzf_1_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__io_netty_netty_3_10_6_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_cli_commons_cli_1_3_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_24.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_codec_commons_codec_1_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_mongodb_mongodb_driver_3_4_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_jcl_over_slf4j_1_7_24.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_core_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_join_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_misc_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_24.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_memory_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_elasticsearch_2_4_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_logging_commons_logging_1_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_queries_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_sandbox_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_spatial_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_suggest_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_grouping_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_mongodb_mongodb_driver_core_3_4_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_spatial3d_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_httpcomponents_httpcore_nio_4_4_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_8_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_highlighter_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_queryparser_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_tx_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/notifyhandlers/INotifyStorageHandler.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.notifyhandlers; 2 | 3 | import com.haier.alertmanager.model.AlertRecord; 4 | 5 | /** 6 | * @description 历史告警信息转储接口 7 | * @date 2017/11/17 8 | * @author Niemingming 9 | */ 10 | public interface INotifyStorageHandler { 11 | /** 12 | * @description 判断是否需要由该处理器处理转储事情 13 | * @date 2017/11/17 14 | * @author Niemingming 15 | */ 16 | public boolean shouldResolve(AlertRecord record); 17 | /** 18 | * @description 转储处理器 19 | * @date 2017/11/17 20 | * @author Niemingming 21 | */ 22 | public void saveRecord(AlertRecord record); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_0_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__javax_validation_validation_api_1_1_0_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_8_5_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_aop_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_web_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/notifyhandlers/INotifySendHanlder.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.notifyhandlers; 2 | 3 | import com.haier.alertmanager.model.AlertRecord; 4 | 5 | /** 6 | * @description 通知发送处理接口,用于后续扩展 7 | * @date 2017/11/17 8 | * @author Niemingming 9 | */ 10 | public interface INotifySendHanlder { 11 | /** 12 | * @description 判断是否由该处理器,处理该告警。每条告警只能有一个处理器处理。 13 | * @date 2017/11/17 14 | * @author Niemingming 15 | */ 16 | public boolean supportRule(AlertRecord record); 17 | /** 18 | * @description 发送消息方法。 19 | * @date 2017/11/17 20 | * @author Niemingming 21 | */ 22 | public void sendNotify(AlertRecord record); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_httpcomponents_httpasyncclient_4_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_core_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_8_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_beans_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_backward_codecs_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_8_5_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_webmvc_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_plugin_parent_join_client_5_6_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_hibernate_hibernate_validator_5_3_4_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_lucene_lucene_analyzers_common_5_5_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_context_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_8_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_expression_4_3_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_8_5_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_plugin_aggs_matrix_stats_client_5_6_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_client_elasticsearch_rest_client_5_6_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/AlertManagerWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | 8 | /** 9 | * @description alertmanager的启动类 10 | * @date 2017/11/16 11 | * @author Niemingming 12 | */ 13 | @SpringBootApplication 14 | @EnableScheduling 15 | @ComponentScan("com.haier.alertmanager") 16 | public class AlertManagerWebApplication { 17 | 18 | public static void main(String[] args){ 19 | //应用程序启动类。 20 | SpringApplication.run(AlertManagerWebApplication.class,args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/notifysend/esmapping6.x.json: -------------------------------------------------------------------------------- 1 | //index template 2 | { 3 | "index_patterns":["alert-*"], 4 | "settings":{ 5 | "number_of_shards":"3", 6 | "number_of_replicas":"1", 7 | "refresh_interval":"2s" 8 | }, 9 | "mappings":{ 10 | "HISTORY":{ 11 | "properties":{ 12 | "startsAt":{"type":"date","format":"epoch_second"}, 13 | "endsAt":{"type":"date","format":"epoch_second"}, 14 | "lastNotifyTime":{"type":"date","format":"epoch_second"}, 15 | "lastReceiveTime":{"type":"date","format":"epoch_second"}, 16 | "times":{"type":"integer"}, 17 | "status":{"type":"keyword"}, 18 | "message":{"type":"text"}, 19 | "labels.*":{ 20 | "type":"keyword" 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/configuration/AlertConstVariable.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.configuration; 2 | /** 3 | * @description 整个应用的常量池 4 | * @date 2017/11/16 5 | * @author Niemingming 6 | */ 7 | public interface AlertConstVariable { 8 | /**告警信息的id计算算法*/ 9 | public static final String ALERT_ID_ALG ="MD5"; 10 | /**告警信息传过来的*/ 11 | public static final String ALERT_TIME_PATTERN="yyyy-MM-dd HH:mm:ss"; 12 | /**告警状态*/ 13 | public static final String ALERT_STATUS_FIRING = "firing";//触发状态 14 | public static final String ALERT_STATUS_SURE = "sure";//确认状态 15 | public static final String ALERT_STATUS_RESLOVE = "resolve";//解决状态 16 | /*人员配置路径*/ 17 | public static final String MESSAGE_RECEIVER_LIST = "classpath:notifysend/personlist.list"; 18 | } 19 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_cbor_2_8_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_8_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_data_spring_data_commons_1_13_1_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_data_spring_data_mongodb_1_10_1_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_smile_2_8_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | #测试文件 2 | spring: 3 | application: 4 | name: alertmanager 5 | data: 6 | mongodb: 7 | uri: mongodb://10.138.40.221:27018/alert 8 | server: 9 | port: 8080 10 | #告警相关表明配置 11 | alertmanager: 12 | #告警记录表明 13 | alertrecord: 14 | tablename: alertRecord 15 | #告警字典表名 16 | alertdictionary: 17 | tablename: alertDictionary 18 | #通知白名单表名 19 | alertexcluse: 20 | tablename: alertExcluse 21 | #消息重发间隔时长单位为s:秒,m:分,h:时,d:天 22 | resendinterval: 3d 23 | #ES主机和端口配置 24 | elasticsearch: 25 | #ES的主机端口配置,支持多台主机, 26 | hostnames: ['10.138.16.188:9200','10.138.16.189:9200','10.138.16.190:9200'] 27 | #索引的时间格式 28 | datepattern: yyyyMM 29 | #es的类型 30 | type: HISTORY 31 | #index的前缀 32 | indexpre: alert- 33 | #notifyService endpoint 34 | notifyUrl: http://localhost:9000 -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_elasticsearch_client_elasticsearch_rest_high_level_client_5_6_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_mongodb_1_5_2_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/notifysend/esmapping5.x.json: -------------------------------------------------------------------------------- 1 | //index template 2 | { 3 | "template":"alert-*", 4 | "settings":{ 5 | "number_of_shards":"3", 6 | "number_of_replicas":"1", 7 | "refresh_interval":"2s" 8 | }, 9 | "mappings":{ 10 | "HISTORY":{ 11 | "properties":{ 12 | "startsAt":{"type":"date","format":"epoch_second"}, 13 | "endsAt":{"type":"date","format":"epoch_second"}, 14 | "lastNotifyTime":{"type":"date","format":"epoch_second"}, 15 | "lastReceiveTime":{"type":"date","format":"epoch_second"}, 16 | "times":{"type":"integer"}, 17 | "status":{"type":"keyword"}, 18 | "alertname":{"type":"keyword"}, 19 | "project":{"type":"keyword"}, 20 | "unit":{"type":"keyword"}, 21 | "suggest":{"type":"keyword"}, 22 | "alertCategory":{"type":"keyword"}, 23 | "description":{"type":"string","index":"analyzed"}, 24 | "message":{"type":"text"}, 25 | "labels.*":{ 26 | "type":"keyword" 27 | } 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/Test.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import javax.annotation.PostConstruct; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Component 10 | public class Test { 11 | 12 | private List list = new ArrayList(); 13 | private boolean flag = true; 14 | 15 | public Test(){ 16 | } 17 | // @PostConstruct 18 | public void xh(){ 19 | while(true){ 20 | // list.remove(0); 21 | System.out.println(11); 22 | Thread tread = new Thread(new Runnable() { 23 | @Override 24 | public void run() { 25 | 26 | } 27 | }); 28 | } 29 | } 30 | 31 | public void receive(){ 32 | synchronized (Test.class){ 33 | if (flag){ 34 | xh(); 35 | flag = false; 36 | } 37 | } 38 | list.add("11"); 39 | return; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/service/HistoryStoreService.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.service; 2 | 3 | import com.haier.alertmanager.model.AlertRecord; 4 | import com.haier.alertmanager.notifyhandlers.INotifyStorageHandler; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.mongodb.core.MongoTemplate; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @description 转储历史消息 13 | * @date 2017/11/16 14 | * @author Niemingming 15 | */ 16 | @Service 17 | public class HistoryStoreService { 18 | @Autowired 19 | private MongoTemplate mongoTemplate; 20 | //历史记录处理类 21 | @Autowired 22 | private List notifyStorageHandlers; 23 | 24 | public boolean storeHistoryRecord(AlertRecord record){ 25 | //转存之后删除历史记录 26 | for (INotifyStorageHandler notifyStorageHandler:notifyStorageHandlers){ 27 | if (notifyStorageHandler.shouldResolve(record)){ 28 | notifyStorageHandler.saveRecord(record); 29 | return true; 30 | } 31 | } 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/configuration/AlertManagerCode.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.configuration; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * @description 编码注入 10 | * @date 2017/11/27 11 | * @author Niemingming 12 | */ 13 | @Component 14 | @ConfigurationProperties(prefix = "alertmanager.code") 15 | public class AlertManagerCode { 16 | /*告警级别*/ 17 | private Map alertlevel; 18 | /*告警分类*/ 19 | private Map alertCategory; 20 | /*告警类型*/ 21 | private Map alertType; 22 | 23 | public Map getAlertlevel() { 24 | return alertlevel; 25 | } 26 | public void setAlertlevel(Map alertlevel) { 27 | this.alertlevel = alertlevel; 28 | } 29 | 30 | public Map getAlertCategory() { 31 | return alertCategory; 32 | } 33 | 34 | public void setAlertCategory(Map alertCategory) { 35 | this.alertCategory = alertCategory; 36 | } 37 | 38 | public Map getAlertType() { 39 | return alertType; 40 | } 41 | 42 | public void setAlertType(Map alertType) { 43 | this.alertType = alertType; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/configuration/MongoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.configuration; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.mongodb.MongoDbFactory; 7 | import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; 8 | import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper; 9 | import org.springframework.data.mongodb.core.convert.MappingMongoConverter; 10 | import org.springframework.data.mongodb.core.mapping.MongoMappingContext; 11 | 12 | /** 13 | * @description mongo配置类,用于去掉java自动生成的_class字段 14 | * @date 2017/11/16 15 | * @author Niemingming 16 | */ 17 | @Configuration 18 | public class MongoConfiguration { 19 | @Autowired 20 | private MongoDbFactory mongoDbFactory; 21 | @Autowired 22 | private MongoMappingContext mongoMappingContext; 23 | 24 | @Bean 25 | public MappingMongoConverter mappingMongoConverter(){ 26 | DefaultDbRefResolver refResolver = new DefaultDbRefResolver(mongoDbFactory); 27 | MappingMongoConverter converter = new MappingMongoConverter(refResolver,mongoMappingContext); 28 | //将默认的mapper类型设置为null,这样就不会再库中生成额外字段。 29 | converter.setTypeMapper(new DefaultMongoTypeMapper(null)); 30 | return converter; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/service/NotifySendService.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.service; 2 | 3 | import com.haier.alertmanager.container.AlertExcluseContainer; 4 | import com.haier.alertmanager.model.AlertRecord; 5 | import com.haier.alertmanager.notifyhandlers.INotifySendHanlder; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @description 通知发送调用服务 13 | * @date 2017/11/16 14 | * @author Niemingming 15 | */ 16 | @Service 17 | public class NotifySendService { 18 | 19 | /*白名单列表*/ 20 | @Autowired 21 | private AlertExcluseContainer alertExcluseContainer; 22 | /*消息发送处理器*/ 23 | @Autowired 24 | private List notifySendHanlders; 25 | /** 26 | * @description 发送通知消息 27 | * @date 2017/11/16 28 | * @author Niemingming 29 | */ 30 | public void sendNotify(AlertRecord record){ 31 | 32 | //如果不在白名单列表中,发送通知。 33 | if (!alertExcluseContainer.inExcluseList(record)){ 34 | 35 | for (INotifySendHanlder notifySendHanlder:notifySendHanlders){ 36 | //如果处理器可以处理消息发送,就有该处理器处理,并且排序靠前的处理器享有较高的处理优先级 37 | if (notifySendHanlder.supportRule(record)){ 38 | notifySendHanlder.sendNotify(record); 39 | break; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/MongoDBTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import com.mongodb.BasicDBObject; 4 | import com.mongodb.DBObject; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.mongodb.core.MongoTemplate; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @RestController 13 | @RequestMapping("/testmongo") 14 | public class MongoDBTest { 15 | @Autowired 16 | private MongoTemplate mongoTemplate; 17 | /** 18 | * @description 测试javamongo新增操作,尝试自己赋值id 19 | * @date 2017/11/16 20 | * @author Niemingming 21 | */ 22 | @ResponseBody 23 | @RequestMapping("/insert/{colname}/{name}/{age}") 24 | public String insert (@PathVariable String colname,@PathVariable String name,@PathVariable int age){ 25 | DBObject object = new BasicDBObject(); 26 | object.put("_id",10); 27 | object.put("name",name); 28 | object.put("age",age); 29 | // mongoTemplate.insert(object,"test"); 30 | DBObject query = new BasicDBObject(); 31 | query.put("_id",10); 32 | mongoTemplate.getCollection(colname).update(query,object,true,false); 33 | mongoTemplate.getCollection(colname).count(); 34 | return "success"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/model/ApiResult.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @description api调用结果实体抽象 8 | * @date 2017/11/21 9 | * @author Niemingming 10 | */ 11 | public class ApiResult { 12 | /*是否成功*/ 13 | private boolean success = false; 14 | /*返回编码,成功为0,失败为非0*/ 15 | private int code = 1; 16 | /*返回数据*/ 17 | private Object data; 18 | /*提示信息*/ 19 | private String msg; 20 | 21 | public ApiResult(){ 22 | data = new HashMap(); 23 | Map page = new HashMap(); 24 | ((Map)data).put("page",page); 25 | } 26 | 27 | public boolean isSuccess() { 28 | return success; 29 | } 30 | 31 | public void setSuccess(boolean success) { 32 | this.success = success; 33 | } 34 | 35 | public int getCode() { 36 | return code; 37 | } 38 | 39 | public void setCode(int code) { 40 | this.code = code; 41 | } 42 | 43 | public String getMsg() { 44 | return msg; 45 | } 46 | 47 | public void setMsg(String msg) { 48 | this.msg = msg; 49 | } 50 | 51 | public Object getData() { 52 | return data; 53 | 54 | } 55 | public void setData(Object data) { 56 | this.data = data; 57 | } 58 | 59 | public void setTotal(long total) { 60 | Map page = (Map) ((Map)data).get("page"); 61 | page.put("total",total); 62 | } 63 | public void setCurrentPage(long currentPage) { 64 | Map page = (Map) ((Map)data).get("page"); 65 | page.put("currentPage",currentPage); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: alertmanager 4 | data: 5 | mongodb: 6 | uri: mongodb://10.138.40.221:27018/alert 7 | server: 8 | port: 8080 9 | #告警相关表明配置 10 | alertmanager: 11 | #告警记录表明 12 | alertrecord: 13 | tablename: alertRecord 14 | #告警字典表名 15 | alertdictionary: 16 | tablename: alertDictionary 17 | #通知白名单表名 18 | alertexcluse: 19 | tablename: alertExcluse 20 | #消息重发间隔时长单位为s:秒,m:分,h:时,d:天 21 | resendinterval: 3d 22 | #ES主机和端口配置 23 | elasticsearch: 24 | #ES的主机端口配置,支持多台主机, 25 | hostnames: ['10.138.16.188:9200','10.138.16.189:9200','10.138.16.190:9200'] 26 | #索引的时间格式 27 | datepattern: yyyyMM 28 | #es的类型 29 | type: HISTORY 30 | #index的前缀 31 | indexpre: alert- 32 | #模板文件地址,根据ES版本设置 33 | template: "classpath:notifysend/esmapping5.x.json" 34 | #notifyService endpoin 35 | notifyurl: http://10.138.16.192:8888/api/notify/message?async=1 36 | code: 37 | alertlevel: 38 | critical: 紧急 39 | serious: 严重 40 | warning: 一般 41 | info: 提示 42 | #告警分类 43 | alertCategory: 44 | machine: 机器 45 | app: 应用 46 | #告警类型 47 | alertType: 48 | node_service_down: 机器监控数据无法获取 49 | node_reboot: 机器重启 50 | node_cpu_pct_high: CPU利用率过高 51 | node_mem_pct_high: 内存利用率过高 52 | node_mem_available_low: 机器内存剩余量不足 53 | node_fs_pct_high: 文件系统利用率过高 54 | node_tcp_conn_toomuch: TCP连接数过多 55 | node_disk_ioutil_pct_high: 磁盘io利用率过高 56 | app_crash: 应用不可访问 57 | http_requests_delay_high: 应用服务端访问响应慢 58 | http_errors_rate_high: 应用服务端错误率高 59 | dubbo_requests_delay_high: dubbo服务响应慢 60 | dubbo_errors_rate_high: dubbo服务错误率高 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/configuration/ElasticsearchConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.configuration; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description ES配置信息 10 | * @date 2017/11/20 11 | * @author Niemingming 12 | */ 13 | @Component 14 | @ConfigurationProperties(prefix = "alertmanager.elasticsearch") 15 | public class ElasticsearchConfiguration { 16 | /*es主机地址*/ 17 | private List hostnames; 18 | /*转储ES的索引日期格式*/ 19 | private String datepattern; 20 | /*转储ES的类型名称*/ 21 | private String type; 22 | /*index的前缀*/ 23 | private String indexpre; 24 | /*模板配置文件地址*/ 25 | private String template; 26 | 27 | public List getHostnames() { 28 | return hostnames; 29 | } 30 | public void setHostnames(List hostnames) { 31 | this.hostnames = hostnames; 32 | } 33 | 34 | public String getDatepattern() { 35 | return datepattern; 36 | } 37 | 38 | public void setDatepattern(String datepattern) { 39 | this.datepattern = datepattern; 40 | } 41 | 42 | public String getType() { 43 | return type; 44 | } 45 | 46 | public void setType(String type) { 47 | this.type = type; 48 | } 49 | 50 | public String getIndexpre() { 51 | return indexpre; 52 | } 53 | 54 | public void setIndexpre(String indexpre) { 55 | this.indexpre = indexpre; 56 | } 57 | 58 | public String getTemplate() { 59 | return template; 60 | } 61 | 62 | public void setTemplate(String template) { 63 | this.template = template; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: alertmanager 4 | data: 5 | mongodb: 6 | uri: mongodb://localhost:27017/alertmanager 7 | #mongodb://localhost:27017/alertmanager 8 | #mongodb://10.138.40.221:27018/alert 9 | server: 10 | port: 8081 11 | #告警相关表明配置 12 | alertmanager: 13 | #告警记录表明 14 | alertrecord: 15 | tablename: alertRecord 16 | #告警字典表名 17 | alertdictionary: 18 | tablename: alertDictionary 19 | #通知白名单表名 20 | alertexcluse: 21 | tablename: alertExcluse 22 | #消息重发间隔时长单位为s:秒,m:分,h:时,d:天 23 | resendinterval: 30m 24 | #ES主机和端口配置 25 | elasticsearch: 26 | #ES的主机端口配置,支持多台主机, 27 | hostnames: ['10.138.16.188:9200','10.138.16.189:9200','10.138.16.190:9200'] 28 | #['10.138.16.188:9200','10.138.16.189:9200','10.138.16.190:9200'] 29 | #['localhost:9200'] 30 | #索引的时间格式 31 | datepattern: yyyyMM 32 | #es的类型 33 | type: HISTORY 34 | #index的前缀 35 | indexpre: alert- 36 | #模板文件地址,根据ES版本设置 37 | template: "classpath:notifysend/esmapping5.x.json" 38 | #notifyService endpoint 39 | notifyurl: http://10.138.16.192:8888/api/notify/message?async=1 40 | code: 41 | alertlevel: 42 | critical: 紧急 43 | serious: 严重 44 | warning: 一般 45 | info: 提示 46 | #告警分类 47 | alertCategory: 48 | machine: 机器 49 | app: 应用 50 | #告警类型,改为从库中获取 51 | alertType: 52 | node_service_down: 机器监控数据无法获取 53 | node_reboot: 机器重启 54 | node_cpu_pct_high: CPU利用率过高 55 | node_mem_pct_high: 内存利用率过高 56 | node_mem_available_low: 机器内存剩余量不足 57 | node_fs_pct_high: 文件系统利用率过高 58 | node_tcp_conn_toomuch: TCP连接数过多 59 | node_disk_ioutil_pct_high: 磁盘io利用率过高 60 | app_crash: 应用不可访问 61 | http_requests_delay_high: 应用服务端访问响应慢 62 | http_errors_rate_high: 应用服务端错误率高 63 | dubbo_requests_delay_high: dubbo服务响应慢 64 | dubbo_errors_rate_high: dubbo服务错误率高 65 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/ESSaveTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import com.haier.alertmanager.model.AlertRecord; 4 | import com.haier.alertmanager.notifyhandlers.INotifyStorageHandler; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import java.util.Date; 12 | import java.util.UUID; 13 | 14 | /** 15 | * @description es转储压力测试 16 | * @date 2017/12/12 17 | * @author Niemingming 18 | */ 19 | @Controller 20 | @RequestMapping("/test") 21 | public class ESSaveTest { 22 | @Autowired 23 | private INotifyStorageHandler notifyStorageHandler; 24 | /** 25 | * @description 转储压力测试默认是1000次 26 | * @date 2017/12/12 27 | * @author Niemingming 28 | */ 29 | @ResponseBody 30 | @RequestMapping("/testSave") 31 | public String testExSave(@RequestParam(name="cs",defaultValue = "1000")int cs){ 32 | 33 | for (int i = 0; i < cs; i++){ 34 | AlertRecord record = new AlertRecord(); 35 | record.setId(UUID.randomUUID().toString()); 36 | record.setAlertname("ylcs"); 37 | record.setTimes(11); 38 | record.setReason("??"); 39 | record.setAlertCategory("app"); 40 | record.setUnit("%"); 41 | record.setSuggest("无"); 42 | record.setDescription("wu"); 43 | record.setProject("hlht"); 44 | record.setLevel("info"); 45 | record.setLastNotifyTime(new Date().getTime()); 46 | record.setLastReceiveTime(new Date().getTime()); 47 | record.setStatus("firing"); 48 | record.setStartsAt(new Date().getTime()); 49 | record.setEndsAt(new Date().getTime()); 50 | notifyStorageHandler.saveRecord(record); 51 | } 52 | return "success"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/service/LogService.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.service; 2 | 3 | import com.google.gson.Gson; 4 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 5 | import com.haier.alertmanager.model.AlertRecord; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * @description 日志处理服务 16 | * @date 2017/11/17 17 | * @author Niemingming 18 | */ 19 | @Component 20 | public class LogService { 21 | @Autowired 22 | private AlertConfigurationProp alertConfigurationProp; 23 | /** 24 | * @description 保存失败向日志文件中写入记录。 25 | * 日志格式为 26 | * {"index":{"_index":"name","_type":"type","_id":"id"}} 27 | * {field1:value1} 28 | * @date 2017/11/17 29 | * @author Niemingming 30 | */ 31 | public synchronized void writeLog(AlertRecord record, String index, String id, String filename){ 32 | FileWriter fileWriter = null; 33 | try { 34 | fileWriter = new FileWriter(filename,true); 35 | //按照ES要求格式构造数据 36 | Map indexMap = new HashMap(); 37 | indexMap.put("_index",index); 38 | indexMap.put("_type",alertConfigurationProp.esType); 39 | indexMap.put("_id",id); 40 | Map first = new HashMap(); 41 | first.put("index",indexMap); 42 | Gson gson = new Gson(); 43 | String firstStr = gson.toJson(first) + "\r\n"; 44 | Map bodymap = record.toSql().toMap(); 45 | bodymap.remove("_id"); 46 | String secondStr = gson.toJson(bodymap) + "\r\n"; 47 | fileWriter.write(firstStr); 48 | fileWriter.write(secondStr); 49 | } catch (IOException e) { 50 | System.out.println("写入日志文件失败!"); 51 | e.printStackTrace(); 52 | }finally { 53 | if (fileWriter != null){ 54 | try { 55 | fileWriter.close(); 56 | } catch (IOException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/configuration/AlertConfigurationProp.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.configuration; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.annotation.PostConstruct; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * @description 告警通知应用所有的配置信息 13 | * @date 2017/11/17 14 | * @author Niemingming 15 | */ 16 | @Component 17 | public class AlertConfigurationProp { 18 | /*监控记录表表名*/ 19 | @Value("${alertmanager.alertrecord.tablename}") 20 | public String alertRecordTalbeName; 21 | /*监控白名单表表名*/ 22 | @Value("${alertmanager.alertexcluse.tablename}") 23 | public String alertExcluseTableName; 24 | /*告警规则表表名*/ 25 | @Value("${alertmanager.alertdictionary.tablename}") 26 | public String alertDictionaryTableName; 27 | /*转储ES配置信息*/ 28 | public List esHostNames; 29 | /*转储ES的索引日期格式*/ 30 | public String esDataPattern; 31 | /*转储ES的类型名称*/ 32 | public String esType; 33 | /*告警信息重发间隔设置*/ 34 | @Value("${alertmanager.resendinterval}") 35 | public String resendinterval; 36 | /*index的前缀*/ 37 | public String indexpre; 38 | /*ES配置文件地址*/ 39 | public String esTemplateAddress; 40 | /*消息通信地址*/ 41 | @Value("${alertmanager.notifyurl}") 42 | public String messageUri; 43 | /*公共编码*/ 44 | @Autowired 45 | public AlertManagerCode alertManagerCode; 46 | /*告警级别*/ 47 | public Map alertlevel; 48 | /*告警分类*/ 49 | public Map alertCategory; 50 | /*告警类型*/ 51 | public Map alertType; 52 | @Autowired 53 | private ElasticsearchConfiguration elasticsearchConfiguration; 54 | @PostConstruct 55 | public void init(){ 56 | this.esHostNames = elasticsearchConfiguration.getHostnames(); 57 | this.esDataPattern = elasticsearchConfiguration.getDatepattern(); 58 | this.esType = elasticsearchConfiguration.getType(); 59 | this.indexpre = elasticsearchConfiguration.getIndexpre(); 60 | this.esTemplateAddress = elasticsearchConfiguration.getTemplate(); 61 | this.alertlevel = alertManagerCode.getAlertlevel(); 62 | this.alertCategory = alertManagerCode.getAlertCategory(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/template/SimpleTemplate.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.template; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.util.HashSet; 6 | import java.util.Map; 7 | import java.util.Set; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | /** 12 | * @description 提示信息的简单模板处理类,用于转换模板信息,模板格式${object.name}形式,模板会自动替换里面值 13 | * @date 2017/11/16 14 | * @author Niemingming 15 | */ 16 | @Component 17 | public class SimpleTemplate { 18 | //匹配规则,用于匹配${object.name}格式的字符串 19 | private Pattern pattern = Pattern.compile("\\$\\{\\w+(\\.\\w+)*\\}"); 20 | 21 | /** 22 | * @description 分析模板格式,将占位符找出,并返回。 23 | * @date 2017/11/16 24 | * @author Niemingming 25 | */ 26 | public Set compileTemplate(String templateStr){ 27 | Set vars = new HashSet(); 28 | Matcher matcher = pattern.matcher(templateStr); 29 | while(matcher.find()){ 30 | matcher.start(); 31 | vars.add(matcher.group()); 32 | matcher.end(); 33 | } 34 | return vars; 35 | } 36 | /** 37 | * @description 分析模板数据,并用实际业务数据替换占位符 38 | * @date 2017/11/16 39 | * @author Niemingming 40 | */ 41 | public String decodeTemplate(String source,Map values){ 42 | //处理空字符串 43 | if (source == null ||"".equals(source) || "null".equals(source)){ 44 | return ""; 45 | } 46 | Set keys = compileTemplate(source); 47 | for (String key : keys){ 48 | String[] fields = key.substring(2,key.length()-1).split("\\."); 49 | Object value = values; 50 | for (String field:fields){ 51 | if (value instanceof Map){ 52 | value = ((Map)value).get(field); 53 | //如果没有值,用空字符串替换 54 | if (value == null ){ 55 | System.out.println("传入值,未能找到属性:" + field + ""); 56 | value = ""; 57 | break; 58 | } 59 | }else { 60 | System.out.println("传入值,未能找到属性:" + field + ""); 61 | value = ""; 62 | break; 63 | } 64 | } 65 | source = source.replace(key,value.toString()); 66 | } 67 | return source; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/TemplateTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import com.haier.alertmanager.template.SimpleTemplate; 4 | import org.springframework.core.io.DefaultResourceLoader; 5 | import org.springframework.core.io.Resource; 6 | 7 | import java.io.FileWriter; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.net.URL; 11 | import java.text.ParseException; 12 | import java.text.SimpleDateFormat; 13 | import java.util.Arrays; 14 | import java.util.Date; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | import java.util.regex.MatchResult; 18 | import java.util.regex.Matcher; 19 | import java.util.regex.Pattern; 20 | 21 | public class TemplateTest { 22 | 23 | public static void main(String[]args) throws ParseException, IOException { 24 | // String str = "我们走在${labels}asdfa上,${labels.name}天涯${fff}"; 25 | // Pattern pattern = Pattern.compile("\\$\\{\\w+(\\.\\w+)*\\}"); 26 | // System.out.println(pattern.pattern()); 27 | // String [] strs = pattern.split(str); 28 | // Matcher matcher = pattern.matcher(str); 29 | // while (matcher.find()){ 30 | // matcher.start(); 31 | // String str1 = matcher.group(); 32 | // str1 = str1.substring(2,str1.length()-1); 33 | // matcher.end(); 34 | // 35 | // System.out.println(str1); 36 | // System.out.println(str1.indexOf(".")); 37 | // } 38 | // Map map = new HashMap(); 39 | // Map labels = new HashMap(); 40 | // map.put("labels",labels); 41 | // labels.put("name","王五"); 42 | // SimpleTemplate template = new SimpleTemplate(); 43 | // String res = template.decodeTemplate(str,map); 44 | // System.out.println(str); 45 | // System.out.println(res); 46 | // 47 | // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 48 | // str = "2017-11-09 23:24:42.806"; 49 | // sdf.parse(str); 50 | 51 | // FileWriter fw = new FileWriter("/errorrecord.log",true); 52 | // fw.write("第二行"); 53 | // fw.write("\r\n"); 54 | // fw.close(); 55 | DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader(); 56 | Resource resource = defaultResourceLoader.getResource("classpath:notifysend/personlist.txt"); 57 | 58 | System.out.println(resource.getFile()); 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/service/ReceiverService.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.service; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonArray; 5 | import com.google.gson.JsonObject; 6 | import com.haier.alertmanager.container.AlertRecordContainer; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.BufferedReader; 15 | import java.io.IOException; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * @description 告警信息接收器,监听prometheus发送的告警信息,并记录和转发通知信息。 22 | * @date 2017/11/16 23 | * @author Niemingming 24 | */ 25 | @RestController 26 | @RequestMapping("/receive") 27 | public class ReceiverService { 28 | @Autowired 29 | private AlertRecordContainer alertRecordContainer; 30 | 31 | /** 32 | * @description 接收alertmanager的告警信息 33 | * @date 2017/11/16 34 | * @author Niemingming 35 | */ 36 | @ResponseBody 37 | @RequestMapping("/api/v1/alerts") 38 | public void receiveAlert(HttpServletResponse response, HttpServletRequest request) throws IOException { 39 | System.out.println("接收告警信息开始。"); 40 | Gson gson = new Gson(); 41 | StringBuilder alerts = new StringBuilder(); 42 | //获取请求输入流 43 | BufferedReader bufferedReader = request.getReader(); 44 | String string = null; 45 | //读取请求体内容,获取告警信息 46 | while((string = bufferedReader.readLine()) != null){ 47 | alerts.append(string); 48 | } 49 | //打印请求体2017-12-13 50 | // System.out.println(alerts); 51 | //如果没有传入数据,我们返回状态信息 52 | if(!"".equals(alerts.toString())){ 53 | //将告警信息转成json数据,并处理告警记录 54 | JsonArray labels = gson.fromJson(alerts.toString(),JsonArray.class); 55 | for (int i = 0; i < labels.size(); i++){ 56 | JsonObject alertRecord = labels.get(i).getAsJsonObject(); 57 | alertRecordContainer.addRecord(alertRecord); 58 | } 59 | } 60 | //返回成功状态 61 | response.setHeader("Content-Type","application/json"); 62 | Map result = new HashMap(); 63 | result.put("status","success"); 64 | response.getWriter().write(gson.toJson(result)); 65 | response.getWriter().flush(); 66 | System.out.println("接收告警信息完成。"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.haier.alertmanager 8 | alertmanager 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.5.2.RELEASE 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-mongodb 26 | 27 | 28 | 29 | com.google.code.gson 30 | gson 31 | 2.8.2 32 | 33 | 34 | 35 | org.elasticsearch.client 36 | elasticsearch-rest-high-level-client 37 | 5.6.4 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /201711.log: -------------------------------------------------------------------------------- 1 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"95584fa50534b83937ebb01c914582561511154872"}} 2 | {"startsAt":1511154872,"endsAt":1511169716,"lastNotifyTime":1511154877,"lastReceiveTime":1511169726,"times":2750,"status":"resolve","alertname":"mymetric11","app":"project2","group":"my1","instance":"localhost:8080","job":"tomcat","monitor":"codelab-monitor"} 3 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"e5352b65ba9ffb8d9d5f731107038afa1511236422"}} 4 | {"startsAt":1511236422,"endsAt":1511236667,"lastNotifyTime":1511236689,"lastReceiveTime":1511236690,"times":54,"status":"resolve","alertname":"mymetric11","app":"project1","group":"my1","instance":"localhost:8080","job":"tomcat","monitor":"codelab-monitor"} 5 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"e5352b65ba9ffb8d9d5f731107038afa1511242907"}} 6 | {"startsAt":1511242907,"endsAt":1511243507,"lastNotifyTime":1511243507,"lastReceiveTime":1511243507,"times":120,"status":"resolve","alertname":"mymetric11","app":"project1","group":"my1","instance":"localhost:8080","job":"tomcat","monitor":"codelab-monitor"} 7 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"247D78214DCCD7FE830EC039F2B310C4-1511839567"}} 8 | {"startsAt":1511839567,"endsAt":1511840187,"lastNotifyTime":1511840118,"lastReceiveTime":1511840187,"times":120,"status":"resolve","level":"warning","alertId":"247D78214DCCD7FE830EC039F2B310C4-1511839567","project":"project1","alertname":"mymetric11","value":375.0,"labels":{"instance":"localhost:8080","monitor":"codelab-monitor","job":"tomcat","group":"my1"}} 9 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"FC6EF20EED02AA884745283049CDE2B2-1511839567"}} 10 | {"startsAt":1511839567,"endsAt":1511840187,"lastNotifyTime":1511840119,"lastReceiveTime":1511840189,"times":118,"status":"resolve","level":"warning","alertId":"FC6EF20EED02AA884745283049CDE2B2-1511839567","project":"project2","alertname":"mymetric11","value":375.0,"labels":{"instance":"localhost:8080","monitor":"codelab-monitor","job":"tomcat","group":"my1"}} 11 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"247D78214DCCD7FE830EC039F2B310C4-1511840297"}} 12 | {"startsAt":1511840297,"endsAt":1511840542,"lastNotifyTime":0,"lastReceiveTime":1511840542,"times":48,"status":"resolve","level":"warning","alertId":"247D78214DCCD7FE830EC039F2B310C4-1511840297","project":"project1","alertname":"mymetric11","value":71.0,"labels":{"instance":"localhost:8080","monitor":"codelab-monitor","job":"tomcat","group":"my1"}} 13 | {"index":{"_index":"alert-201711","_type":"HISTORY","_id":"FC6EF20EED02AA884745283049CDE2B2-1511840297"}} 14 | {"startsAt":1511840297,"endsAt":1511840542,"lastNotifyTime":0,"lastReceiveTime":1511840543,"times":48,"status":"resolve","level":"warning","alertId":"FC6EF20EED02AA884745283049CDE2B2-1511840297","project":"project2","alertname":"mymetric11","value":71.0,"labels":{"instance":"localhost:8080","monitor":"codelab-monitor","job":"tomcat","group":"my1"}} 15 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/container/AlertExcluseContainer.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.container; 2 | 3 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 4 | import com.haier.alertmanager.model.AlertExcluse; 5 | import com.haier.alertmanager.model.AlertRecord; 6 | import com.mongodb.BasicDBObject; 7 | import com.mongodb.DBCursor; 8 | import com.mongodb.DBObject; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.mongodb.core.MongoTemplate; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.util.ArrayList; 15 | import java.util.Date; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | /** 20 | * @description 白名单容器,初始化系统配置的所有白名单 21 | * @date 2017/11/16 22 | * @author Niemingming 23 | */ 24 | @Component 25 | public class AlertExcluseContainer { 26 | @Autowired 27 | private AlertConfigurationProp alertConfigurationProp; 28 | @Autowired 29 | private MongoTemplate mongoTemplate; 30 | private List alertExcluses; 31 | 32 | /** 33 | * @description 初始化方法,加载所有白名单数据 34 | * @date 2017/11/16 35 | * @author Niemingming 36 | */ 37 | @PostConstruct 38 | public void init(){ 39 | List alertExcluses = new ArrayList(); 40 | //首先删除过时的记录 41 | long curr = new Date().getTime()/1000; 42 | DBObject query = new BasicDBObject(); 43 | query.put("endsAt","{$lt:" + curr + "}"); 44 | mongoTemplate.getCollection(alertConfigurationProp.alertExcluseTableName).remove(query); 45 | //加载所有为过时且已经生效的记录 46 | DBCursor cursor = mongoTemplate.getCollection(alertConfigurationProp.alertExcluseTableName).find(); 47 | while (cursor.hasNext()){ 48 | DBObject excluse = cursor.next(); 49 | AlertExcluse alertExcluse = new AlertExcluse(excluse); 50 | alertExcluses.add(alertExcluse); 51 | } 52 | this.alertExcluses = alertExcluses; 53 | } 54 | /** 55 | * @description 刷新白名单列表 56 | * @date 2017/11/16 57 | * @author Niemingming 58 | */ 59 | public void refresh(){ 60 | init(); 61 | } 62 | /** 63 | * @description 判断是否在白名单列表中 64 | * @date 2017/11/16 65 | * @author Niemingming 66 | */ 67 | public boolean inExcluseList(AlertRecord record){ 68 | boolean flag = false;//不在白名单中 69 | Map map = record.getLabels();//通过labels中属性做出判断 70 | long now = new Date().getTime()/1000; 71 | for (AlertExcluse excluse:alertExcluses){ 72 | //当前时间在白名单范围内且过滤条件吻合 73 | if (excluse.algExculseId(map).equals(excluse.getId()) 74 | && excluse.getStartsAt() <= now 75 | && excluse.getEndsAt() >= now){ 76 | flag = true; 77 | break; 78 | } 79 | } 80 | return flag; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/ESQueryTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import com.mongodb.BasicDBObject; 6 | import com.mongodb.util.JSON; 7 | import org.apache.http.Header; 8 | import org.apache.http.HttpHost; 9 | import org.apache.http.entity.StringEntity; 10 | import org.apache.http.message.BasicHeader; 11 | import org.apache.http.util.EntityUtils; 12 | import org.elasticsearch.client.Response; 13 | import org.elasticsearch.client.RestClient; 14 | 15 | import java.io.IOException; 16 | import java.io.UnsupportedEncodingException; 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * @description elasticsearch客户端查询测试 24 | * @date 2017/11/20 25 | * @author Niemingming 26 | */ 27 | public class ESQueryTest { 28 | 29 | public static void main(String[] args) throws IOException { 30 | RestClient client = RestClient.builder(new HttpHost("localhost",9200)).build(); 31 | //查询方法。 32 | /** 33 | * GET /_search 34 | * { 35 | * query:{ 36 | * bool:{ 37 | * must:[ 38 | * {"match":{"job":"tom"}} 39 | * ], 40 | * filter:[ 41 | * range:{times:{gte:10}}, 42 | * term:{monitor:"codelab"} 43 | * ] 44 | * } 45 | * } 46 | * } 47 | */ 48 | Map query = new HashMap(); 49 | //构造查询条件 50 | Map multi = new HashMap(); 51 | multi.put("query_string",new BasicDBObject("query","httpminotor").toMap()); 52 | // multi.put("fields","_all"); 53 | Map bool = new HashMap(); 54 | 55 | // query.put("multi_match",multi); 56 | query.put("bool",bool); 57 | List must = new ArrayList(); 58 | bool.put("must",must); 59 | Map match = new HashMap(); 60 | must.add(match); 61 | Map job = new HashMap(); 62 | match.put("match",job); 63 | job.put("job","tomcat"); 64 | List filter = new ArrayList(); 65 | bool.put("filter",filter); 66 | Map range = new HashMap(); 67 | filter.add(range); 68 | filter.add(multi); 69 | Map times = new HashMap(); 70 | range.put("range",times); 71 | Map time = new HashMap(); 72 | times.put("times",time); 73 | time.put("gte",25); 74 | Map term = new HashMap(); 75 | filter.add(term); 76 | Map monitor = new HashMap(); 77 | term.put("term",monitor); 78 | monitor.put("monitor","codelab"); 79 | Map con = new HashMap(); 80 | con.put("query",query); 81 | con.put("from",0); 82 | con.put("size",10); 83 | 84 | // query.put("term",monitor); 85 | Gson gson = new Gson(); 86 | System.out.println(gson.toJson(con)); 87 | StringEntity se = new StringEntity(gson.toJson(con)); 88 | Header header = new BasicHeader("content-type","application/json"); 89 | 90 | Response response = client.performRequest("GET","/_search",new HashMap(),se,header); 91 | System.out.println(EntityUtils.toString(response.getEntity())); 92 | client.close(); 93 | 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/model/AlertDictionary.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.model; 2 | 3 | import com.mongodb.DBObject; 4 | 5 | /** 6 | * @description 告警转发的数据字典。 7 | * @date 2017/11/16 8 | * @author Niemingming 9 | */ 10 | public class AlertDictionary { 11 | /*告警名称*/ 12 | private String alertname; 13 | /*告警级别*/ 14 | private String alertlevel; 15 | /*告警描述,可以使用变量占位符${labels.name},${startsAt}*/ 16 | private String description; 17 | /*告警建议 */ 18 | private String suggest; 19 | /*告警类型:机器、应用、中间件等*/ 20 | private String alertCategory; 21 | /*告警原因*/ 22 | private String reason; 23 | /*告警类型*/ 24 | private String alertType; 25 | 26 | public AlertDictionary() { 27 | } 28 | public AlertDictionary(DBObject dict) { 29 | alertname = dict.get("alertname") + ""; 30 | alertlevel = dict.get("level") +""; 31 | description = dict.get("description") +""; 32 | suggest = dict.get("suggest") == null? "" :dict.get("suggest") +""; 33 | alertCategory = dict.get("alertCategory")+""; 34 | reason = dict.get("reason") == null ? "" : dict.get("reason")+""; 35 | alertType = dict.get("alertType") == null ? "" : dict.get("alertType")+""; 36 | } 37 | 38 | public String getAlertname() { 39 | return alertname; 40 | } 41 | 42 | public void setAlertname(String alertname) { 43 | this.alertname = alertname; 44 | } 45 | 46 | public String getAlertlevel() { 47 | return alertlevel; 48 | } 49 | 50 | public void setAlertlevel(String alertlevel) { 51 | this.alertlevel = alertlevel; 52 | } 53 | 54 | public String getDescription() { 55 | return description; 56 | } 57 | 58 | public void setDescription(String description) { 59 | this.description = description; 60 | } 61 | 62 | public String getSuggest() { 63 | return suggest; 64 | } 65 | 66 | public void setSuggest(String suggest) { 67 | this.suggest = suggest; 68 | } 69 | 70 | public String getAlertCategory() { 71 | return alertCategory; 72 | } 73 | 74 | public void setAlertCategory(String alertCategory) { 75 | this.alertCategory = alertCategory; 76 | } 77 | 78 | public String getReason() { 79 | return reason; 80 | } 81 | 82 | public void setReason(String reason) { 83 | this.reason = reason; 84 | } 85 | 86 | public String getAlertType() { 87 | return alertType; 88 | } 89 | 90 | public void setAlertType(String alertType) { 91 | this.alertType = alertType; 92 | } 93 | 94 | @Override 95 | public boolean equals(Object o) { 96 | if (this == o) return true; 97 | if (o == null || getClass() != o.getClass()) return false; 98 | 99 | AlertDictionary that = (AlertDictionary) o; 100 | 101 | return alertname != null ? alertname.equals(that.alertname) : that.alertname == null; 102 | } 103 | 104 | @Override 105 | public int hashCode() { 106 | return alertname != null ? alertname.hashCode() : 0; 107 | } 108 | 109 | @Override 110 | public String toString() { 111 | return "AlertDictionary{" + 112 | "alertname='" + alertname + '\'' + 113 | ", alertlevel='" + alertlevel + '\'' + 114 | ", description='" + description + '\'' + 115 | ", suggest='" + suggest + '\'' + 116 | ", alertCategory='" + alertCategory + '\'' + 117 | '}'; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/model/MessageReceiverInfo.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.model; 2 | 3 | import com.haier.alertmanager.configuration.AlertConstVariable; 4 | import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; 5 | 6 | import java.io.UnsupportedEncodingException; 7 | import java.security.MessageDigest; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.regex.Pattern; 13 | 14 | /** 15 | * @description 信息接收人实体 16 | * @date 2017/11/21 17 | * @author Niemingming 18 | */ 19 | public class MessageReceiverInfo { 20 | /*匹配结果id*/ 21 | private String id; 22 | /*人员id*/ 23 | private String personId; 24 | /*人员名称*/ 25 | private String personName; 26 | /*过滤规则*/ 27 | private Map filters; 28 | 29 | public String getId() { 30 | return id; 31 | } 32 | public void setId(String id) { 33 | this.id = id; 34 | } 35 | public String getPersonId() { 36 | return personId; 37 | } 38 | public void setPersonId(String personId) { 39 | this.personId = personId; 40 | } 41 | public String getPersonName() { 42 | return personName; 43 | } 44 | public void setPersonName(String personName) { 45 | this.personName = personName; 46 | } 47 | public Map getFilters() { 48 | return filters; 49 | } 50 | public void setFilters(Map filters) { 51 | this.filters = filters; 52 | setId(algExculseId(filters)); 53 | } 54 | 55 | public String algExculseId(Map data) { 56 | //计算id 57 | List algfields = new ArrayList(); 58 | for (String field : filters.keySet()){ 59 | //修改匹配规则,适用于正则表达式,支持name*号匹配 60 | String value = filters.get(field).toString(); 61 | if (value.charAt(value.length() - 1) == '*'){ 62 | Pattern pattern = Pattern.compile(value.replace("*","[\\w\\-]*")); 63 | String dv = data.get(field) + ""; 64 | if (pattern.matcher(dv).matches()){//全字符匹配,直接使用判断值。 65 | algfields.add(field+"="+filters.get(field)); 66 | }else { 67 | algfields.add(field+"="+data.get(field)); 68 | } 69 | }else { 70 | algfields.add(field+"="+data.get(field)); 71 | } 72 | } 73 | try { 74 | MessageDigest digest = MessageDigest.getInstance(AlertConstVariable.ALERT_ID_ALG); 75 | return HexBin.encode(digest.digest(algfields.toString().getBytes("UTF-8"))); 76 | } catch (NoSuchAlgorithmException e) { 77 | e.printStackTrace(); 78 | System.out.println("系统不支持配置的计算算法"); 79 | } catch (UnsupportedEncodingException e) { 80 | e.printStackTrace(); 81 | System.out.println("不支持的字符串编码格式"); 82 | } 83 | return "null"; 84 | } 85 | 86 | @Override 87 | public boolean equals(Object o) { 88 | if (this == o) return true; 89 | if (o == null || getClass() != o.getClass()) return false; 90 | 91 | MessageReceiverInfo that = (MessageReceiverInfo) o; 92 | 93 | return id != null ? id.equals(that.id) : that.id == null; 94 | } 95 | 96 | @Override 97 | public int hashCode() { 98 | return id != null ? id.hashCode() : 0; 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return "MessageReceiverInfo{" + 104 | "id='" + id + '\'' + 105 | ", personId='" + personId + '\'' + 106 | ", personName='" + personName + '\'' + 107 | ", filters=" + filters + 108 | '}'; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/resources/notifysend/personlist.list: -------------------------------------------------------------------------------- 1 | #通知发送列表,分为3列,人员id,人员名称,匹配规则json字符串。一行对应一条通知规则,可以重复 2 | #01462834 薛冰 {alertname:"mymetric11",job:"tomcat"} 3 | #redis,mysql,MONITOR-DEV,MONITOR-PROD 4 | #01479820 聂明明 {alertname:"mymetric11"} 5 | #01479820 聂明明 {project:"*"} 6 | #01462834 薛冰 {project:"*"} 7 | #01430959 徐金良 {project:"*"} 8 | 01462834 薛冰 {job:"redis"} 9 | 01462834 薛冰 {job:"mysql"} 10 | 01462834 薛冰 {project:"HLHT"} 11 | 01462834 薛冰 {project:"MONITOR-DEV"} 12 | 01462834 薛冰 {project:"MONITOR-PROD"} 13 | #01445511 于鸿磊 MONITOR-DEV,MONITOR-PROD 14 | 01445511 于鸿磊 {project:"MONITOR-DEV"} 15 | 01445511 于鸿磊 {project:"MONITOR-PROD"} 16 | #01452142 于志强 POINT,HDYBC,redis 17 | 01452142 于志强 {project:"POINT"} 18 | 01452142 于志强 {project:"HDYBC"} 19 | 01452142 于志强 {project:"redis"} 20 | #01430959 徐金良 HDYBCFP,HAIDAYUAN,COSMOIM,PAAS-PROD,PAAS-DEV 21 | 01430959 徐金良 {project:"HDYBCFP"} 22 | 01430959 徐金良 {project:"HAIDAYUAN"} 23 | 01430959 徐金良 {project:"COSMOIM"} 24 | 01430959 徐金良 {project:"PAAS-PROD"} 25 | 01430959 徐金良 {project:"PAAS-DEV"} 26 | #01431003 孙晓坤 TDP,BTBRRS 27 | 01431003 孙晓坤 {project:"TDP"} 28 | 01431003 孙晓坤 {project:"BTBRRS"} 29 | #01429102 班点点 HECO,PAAS-PROD,PAAS-DEV 30 | 01429102 班点点 {project:"HECO"} 31 | 01429102 班点点 {project:"PAAS-PROD"} 32 | 01429102 班点点 {project:"PAAS-DEV"} 33 | #01426061 王雷鸣 CENTER 34 | 01426061 王雷鸣 {project:"CENTER"} 35 | #01457141 王建坤 JHZX,WANGJIANKUN 36 | 01457141 王建坤 {project:"JHZX"} 37 | 01457141 王建坤 {project:"WANGJIANKUN"} 38 | #01460476 季相相 UOC 39 | 01460476 季相相 {project:"UOC"} 40 | #01458316 毛芳 ADP 41 | 01458316 毛芳 {project:"ADP"} 42 | # 43 | #01461125 高殿翔-技术 ADP 44 | 01461125 高殿翔-技术 {project:"ADP"} 45 | #01462541 UOC技术-姬哲 UOC 46 | 01462541 UOC技术-姬哲 {project:"UOC"} 47 | #01303014 UOC技术-陈子琦 UOC 48 | 01303014 UOC技术-陈子琦 {project:"UOC"} 49 | #01467848 李岚-技术 POINT 50 | 01467848 李岚-技术 {project:"POINT"} 51 | #01188413 HDYBC技术-李丹 HDYBC 52 | 01188413 HDYBC技术-李丹 {project:"HDYBC"} 53 | # 54 | #01076632 HDYBCFP技术-常靓靓 HDYBCFP 55 | 01076632 HDYBCFP技术-常靓靓 {project:"HDYBCFP"} 56 | ##01430860 COSMOIM技术-姚彬 COSMOIM 57 | 01430860 COSMOIM技术-姚彬 {project:"COSMOIM"} 58 | #01197593 TDP技术/项目-王明超 {project:"TDP"} 59 | 01075303 HECO技术-王海欧 {project:"HECO"} 60 | # 61 | 01357690 HBDM技术-王贤秀 {project:"HBDM"} 62 | # 63 | 01436556 CENTER技术-黄超 {project:"CENTER"} 64 | 65 | 00575591 HAIDAYUAN技术-许峰 {project:"HAIDAYUAN"} 66 | 01413497 HAIDAYUAN技术-李成 {project:"HAIDAYUAN"} 67 | 01455606 JHZX技术-赵华伟 {project:"JHZX"} 68 | 69 | 00025644 BTBRRS技术-路文超 {project:"BTBRRS"} 70 | 00602213 DZSP-技术-侯宝原 {project:"DZSP"} 71 | 01457199 HAIERBTOB-技术-郭钥 {project:"HAIERBTOB"} 72 | 01402638 HMMS-技术-张爱萍 {project:"HMMS"} 73 | 01402638 HMMS-技术-张爱萍 {project:"HMMSYJ"} 74 | 01025569 HMQM-技术-盖晓雅 {project:"HMQM"} 75 | 01303040 HOVAS-技术-马宏伟 {project:"HOVAS"} 76 | 01341720 WGXSPT-技术-卢瑾 {project:"WGXSPT"} 77 | 01419699 OEM技术-周陈 {project:"OEM"} 78 | 00594667 SOPPLAT技术-严惠 {project:"SOPPLAT"} 79 | 01419699 DFGL技术-周陈 {project:"DFGL"} 80 | 01188578 IOS技术-邳继武 {project:"IOS"} 81 | 01025569 MEC技术-盖晓雅 {project:"MEC"} 82 | 01025569 MKHL技术-盖晓雅 {project:"MKHL"} 83 | 00592038 CGSIS技术-李娣 {project:"CGSIS"} 84 | 01437224 HROIS技术-王学骞 {project:"HROIS"} 85 | 0003524 HROIS技术-朱晓亮 {project:"HROIS"} 86 | 00552601 HPBCS技术-庄小兰 {project:"HPBCS"} 87 | 01407391 HPBCS技术-韩仁龙 {project:"HPBCS"} 88 | 01197593 BVS技术-王明超 {project:"BVS"} 89 | 01025913 HNM技术-程宏平 {project:"HNM"} 90 | 01431021 CEI技术-柳京活 {project:"CEI"} 91 | a0015527 RDCXT技术-张继功 {project:"RDCXT"} 92 | 01431622 RDCXT技术-乔云龙 {project:"RDCXT"} 93 | 01204349 KQXT技术-魏杰 {project:"KQXT"} 94 | a0003302 YXHDAPP技术-于召和 {project:"YXHDAPP"} 95 | 00592140 YXHDAPP技术-杨璐嘉 {project:"YXHDAPP"} 96 | 01070548 YJQLCGL技术-张富伟 {project:"YJQLCGL"} 97 | 01405482 HBASE技术-魏鹏源 {project:"HBASE"} 98 | 01439687 COSMOWMS技术-王延磊 {project:"COSMOWMS"} 99 | 01440568 SVP技术-孙新伟 {project:"SVP"} 100 | 01070403 ZPTZJYKB技术-张玉丽 {project:"ZPTZJYKB"} 101 | 00594018 CQEMR技术-张小平 {project:"CQEMR"} 102 | 01467824 DIYUAS技术-刘雨濛 {project:"DIYUAS"} 103 | A0010384 DIYUAS技术-荆汉娜 {project:"DIYUAS"} 104 | 01405482 OMS技术-魏鹏源 {project:"OMS"} 105 | A0001627 OMS技术-陈浩 {project:"OMS"} 106 | 01462541 HMCENTER技术-姬哲 {project:"HMCENTER"} 107 | A0020408 HMCENTER技术-安茂鑫 {project:"HMCENTER"} -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/container/AlertRecordContainer.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.container; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 5 | import com.haier.alertmanager.configuration.AlertConstVariable; 6 | import com.haier.alertmanager.model.AlertRecord; 7 | import com.haier.alertmanager.service.HistoryStoreService; 8 | import com.haier.alertmanager.service.NotifySendService; 9 | import com.mongodb.DBCursor; 10 | import com.mongodb.DBObject; 11 | import com.mongodb.WriteResult; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.data.mongodb.core.MongoTemplate; 14 | import org.springframework.stereotype.Component; 15 | 16 | import java.util.HashMap; 17 | import java.util.Map; 18 | 19 | /** 20 | * @description 告警记录的内存容器,用于缓存告警记录,同时保持与数据库的一致状态 21 | * @date 2017/11/16 22 | * @author Niemingming 23 | */ 24 | @Component 25 | public class AlertRecordContainer { 26 | @Autowired 27 | private MongoTemplate mongoTemplate; 28 | //所有当前发生的告警 29 | private Map records; 30 | //监控记录表明 31 | @Autowired 32 | private AlertConfigurationProp alertConfigurationProp; 33 | /**发送通知消息服务*/ 34 | @Autowired 35 | private NotifySendService notifySendService; 36 | /**历史信息转储服务*/ 37 | @Autowired 38 | private HistoryStoreService historyStoreService; 39 | /**数据字典*/ 40 | @Autowired 41 | private AlertDictionaryContainer alertDictionaryContainer; 42 | /** 43 | * @description 初始化方法,完成告警记录的加载 44 | * @date 2017/11/16 45 | * @author Niemingming 46 | */ 47 | // @PostConstruct 不在读取缓存 48 | public void initMethod(){ 49 | records = new HashMap(); 50 | DBCursor cursor = mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).find(); 51 | while (cursor.hasNext()){ 52 | AlertRecord record = new AlertRecord(cursor.next()); 53 | records.put(record.getId(),record); 54 | } 55 | } 56 | /** 57 | * @description 添加一条告警记录,并发送告警通知 58 | * @date 2017/11/16 59 | * @author Niemingming 60 | */ 61 | public AlertRecord addRecord(JsonObject record){ 62 | AlertRecord record1 = new AlertRecord(record); 63 | DBObject object = mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).findOne(record1.toQuerySqlById()); 64 | boolean shouldexec = true; 65 | //结束时间和1970年比较,如果比1970年晚,认为是已经结束了,否则未结束。 66 | if (record1.getEndsAt() > 0){ 67 | //如果有结束时间,则设置状态为已解决 68 | record1.setStatus(AlertConstVariable.ALERT_STATUS_RESLOVE); 69 | //如果数据库中有记录,表示第一次接收到消除请求,需要更新,且删除记录;否则表示已经处理过,后续不在处理。 70 | shouldexec = object != null; 71 | } 72 | if (object != null){ 73 | //如果数据库不为空,将通用属性赋值到新记录中。 74 | AlertRecord tmp = new AlertRecord(object); 75 | record1.setLastNotifyTime(tmp.getLastNotifyTime()); 76 | record1.setTimes(tmp.getTimes()+1); 77 | record1.setLevel(tmp.getLevel()); 78 | record1.setMessage(tmp.getMessage()); 79 | record1.setSuggest(tmp.getSuggest()); 80 | record1.setDescription(tmp.getDescription()); 81 | record1.setAlertCategory(tmp.getAlertCategory()); 82 | record1.setReason(tmp.getReason()); 83 | record1.setUnit(tmp.getUnit()); 84 | }else {//数据库中没有的时候,先初始化提示信息 85 | String message = alertDictionaryContainer.getNotifyMessage(record1); 86 | record1.setMessage(message); 87 | } 88 | //如果没有结束时间,或者有但是需要更新时,执行更新操作。 89 | if (shouldexec){ 90 | DBObject obj = record1.toSql(); 91 | //更新或者插入告警记录 92 | WriteResult writeResult = mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).update(record1.toQuerySqlById(),obj,true,false); 93 | //发送消息通知 94 | notifySendService.sendNotify(record1); 95 | } 96 | //如果需要更新操作,且状态是解决,name就是第一次获取到解决数据,需要转储 97 | if (shouldexec&&AlertConstVariable.ALERT_STATUS_RESLOVE.equals(record1.getStatus())){ 98 | historyStoreService.storeHistoryRecord(record1);//删除缓存中记录 99 | } 100 | return record1; 101 | } 102 | /** 103 | * @description 更新告警信息 104 | * @date 2017/11/17 105 | * @author Niemingming 106 | */ 107 | public void updateRecord(AlertRecord record){ 108 | mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).update(record.toQuerySqlById(),record.toSql(),true,false); 109 | } 110 | /** 111 | * @description 获取所有当前告警记录 112 | * @date 2017/11/20 113 | * @author Niemingming 114 | */ 115 | public Map getRecords(){ 116 | return this.records; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/container/MessageReceiverContainer.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.container; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import com.haier.alertmanager.configuration.AlertConstVariable; 7 | import com.haier.alertmanager.model.AlertRecord; 8 | import com.haier.alertmanager.model.MessageReceiverInfo; 9 | import org.springframework.core.io.DefaultResourceLoader; 10 | import org.springframework.core.io.Resource; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.io.BufferedReader; 15 | import java.io.IOException; 16 | import java.io.InputStreamReader; 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * @description 告警信息接收者容器 24 | * @date 2017/11/21 25 | * @author Niemingming 26 | */ 27 | @Component 28 | public class MessageReceiverContainer { 29 | /*消息接收者集合*/ 30 | private Map> messageRecevierMap; 31 | /** 32 | * @description 初始化方法,加载配置文件 33 | * @date 2017/11/21 34 | * @author Niemingming 35 | */ 36 | @PostConstruct 37 | public void init(){ 38 | messageRecevierMap = new HashMap>(); 39 | //读取配置文件classpath:notifysend/personlist.list 40 | DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader(); 41 | Resource resource = defaultResourceLoader.getResource(AlertConstVariable.MESSAGE_RECEIVER_LIST); 42 | if (resource != null) { 43 | try { 44 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream())); 45 | String line = null; 46 | Gson gson = new Gson(); 47 | while ((line = bufferedReader.readLine()) != null) { 48 | line = line.trim(); 49 | if ("".equals(line)){//如果是空行 50 | continue; 51 | } 52 | //不处理注释行 53 | if (line.charAt(0) == '#'){ 54 | continue; 55 | } 56 | String[] info = line.replaceAll(" +"," ").split(" "); 57 | if (info.length < 3) { 58 | continue; 59 | } 60 | //构建人员接收实体 61 | MessageReceiverInfo messageReceiverInfo = new MessageReceiverInfo(); 62 | messageReceiverInfo.setPersonId(info[0]); 63 | messageReceiverInfo.setPersonName(info[1]); 64 | JsonObject filters = gson.fromJson(info[2],JsonObject.class); 65 | Map filterMap = new HashMap(); 66 | for (Map.Entry entry:filters.entrySet()){ 67 | filterMap.put(entry.getKey(),entry.getValue().getAsString()); 68 | } 69 | messageReceiverInfo.setFilters(filterMap); 70 | //判断是否已经存入缓存,如果没有就创建一个集合存入,如果有直接添加。 71 | List messageReceiverInfos = messageRecevierMap.get(messageReceiverInfo.getId()); 72 | if (messageReceiverInfos == null) { 73 | messageReceiverInfos = new ArrayList(); 74 | messageRecevierMap.put(messageReceiverInfo.getId(),messageReceiverInfos); 75 | } 76 | messageReceiverInfos.add(messageReceiverInfo); 77 | } 78 | } catch (IOException e) { 79 | System.out.println("读取人员配置信息失败!【" + AlertConstVariable.MESSAGE_RECEIVER_LIST+ "】"); 80 | e.printStackTrace(); 81 | } 82 | } 83 | } 84 | /** 85 | * @description 刷新方法 86 | * @date 2017/11/21 87 | * @author Niemingming 88 | */ 89 | public synchronized void refresh(){ 90 | init(); 91 | } 92 | /** 93 | * @description 根据告警记录获取接收者 94 | * @date 2017/11/21 95 | * @author Niemingming 96 | */ 97 | public List getReceiversByRecord(AlertRecord record){ 98 | List messageReceiverInfos = new ArrayList(); 99 | Map map = record.toMap(); 100 | //遍历判断有哪些需要发送消息服务 101 | for (Map.Entry> entry : messageRecevierMap.entrySet()){ 102 | MessageReceiverInfo messageReceiverInfo = entry.getValue().get(0); 103 | //如果根据接收过滤关键属性得出的id值一致,那么这些用户都需要发送消息。 104 | if (messageReceiverInfo.algExculseId(map).equals(entry.getKey())){ 105 | messageReceiverInfos.addAll(entry.getValue()); 106 | } 107 | } 108 | return messageReceiverInfos; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/container/AlertDictionaryContainer.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.container; 2 | 3 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 4 | import com.haier.alertmanager.model.AlertDictionary; 5 | import com.haier.alertmanager.model.AlertRecord; 6 | import com.haier.alertmanager.template.SimpleTemplate; 7 | import com.mongodb.DBCursor; 8 | import com.mongodb.DBObject; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.data.mongodb.core.MongoTemplate; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.util.Date; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * @description 告警信息基础数据字典,包含了提示信息和原因分析,告警级别以及告警触发类型等信息。 20 | * @date 2017/11/16 21 | * @author Niemingming 22 | */ 23 | @Component 24 | public class AlertDictionaryContainer { 25 | /*数据字典表名*/ 26 | @Autowired 27 | private AlertConfigurationProp alertConfigurationProp; 28 | /**告警信息基础表*/ 29 | private Map alertDictionaryMap; 30 | @Autowired 31 | private MongoTemplate mongoTemplate; 32 | /*模板处理类*/ 33 | @Autowired 34 | private SimpleTemplate simpleTemplate; 35 | 36 | /** 37 | * @description 初始化方法,从数据库中加载基础配置信息 38 | * @date 2017/11/16 39 | * @author Niemingming 40 | */ 41 | @PostConstruct 42 | public void init(){ 43 | Map alertDictionaryMap = new HashMap(); 44 | Map projects = new HashMap(); 45 | //从表中读取所有数据字典 46 | DBCursor cursor = mongoTemplate.getCollection(alertConfigurationProp.alertDictionaryTableName).find(); 47 | while (cursor.hasNext()){ 48 | DBObject dict = cursor.next(); 49 | AlertDictionary dictionary = new AlertDictionary(dict); 50 | alertDictionaryMap.put(dictionary.getAlertname(),dictionary); 51 | projects.put(dictionary.getAlertname(),dictionary.getAlertType()); 52 | } 53 | this.alertDictionaryMap = alertDictionaryMap; 54 | alertConfigurationProp.alertType = projects; 55 | } 56 | 57 | /** 58 | * @description 根据告警名称,获取要发送的告警信息 59 | * @date 2017/11/16 60 | * @author Niemingming 61 | */ 62 | public String getNotifyMessage(AlertRecord record){ 63 | return getNotifyMessage(record,true); 64 | } 65 | /** 66 | * @description 根据告警名称获取要发送的告警信息,并指定是否附加告警原因分析 67 | * 告警提示信息格式。 68 | * 【level】系统:project 告警,描述:description 建议:suggest 69 | * @date 2017/11/16 70 | * @author Niemingming 71 | */ 72 | public String getNotifyMessage(AlertRecord record, boolean appedReason) { 73 | StringBuilder templateStr = new StringBuilder(); 74 | String alertname = record.getAlertname(); 75 | AlertDictionary alertDictionary = alertDictionaryMap.get(alertname); 76 | //未查询到告警配置信息 77 | if (alertDictionary == null){ 78 | System.out.println("未能查询到【" + alertname + "】的告警数据字典"); 79 | return ""; 80 | } 81 | //同时复制告警级别 82 | setAlertLevel(record,alertDictionary); 83 | String levelStr = alertConfigurationProp.alertlevel.get(record.getLevel()); 84 | if (record.getEndsAt() > record.getStartsAt()){//如果告警恢复,就不直接传入恢复级别 85 | levelStr = "恢复"; 86 | } 87 | //拼装消息头 88 | templateStr.append("【").append(levelStr).append("】 系统:").append(record.getProject()).append(" 告警,"); 89 | templateStr.append("描述:").append(alertDictionary.getDescription()); 90 | if (appedReason){ 91 | //判断原因和建议是否为空 92 | if (alertDictionary.getReason() != null && !"".equals(alertDictionary.getReason())){ 93 | templateStr.append("\n原因:").append(alertDictionary.getReason()); 94 | } 95 | if (alertDictionary.getSuggest() != null && !"".equals(alertDictionary.getSuggest())) { 96 | templateStr.append("\n建议:").append(alertDictionary.getSuggest()); 97 | } 98 | } 99 | return simpleTemplate.decodeTemplate(templateStr.toString(),record.toMap()); 100 | } 101 | /** 102 | * @description 设置告警的数据字典字段 103 | * @date 2017/11/21 104 | * @author Niemingming 105 | */ 106 | public void setAlertLevel(AlertRecord record, AlertDictionary alertDictionary) { 107 | record.setLevel(alertDictionary.getAlertlevel()); 108 | //设置告警分类 109 | record.setAlertCategory(alertDictionary.getAlertCategory()); 110 | //获取告警描述 111 | record.setDescription(simpleTemplate.decodeTemplate(alertDictionary.getDescription(),record.toMap())); 112 | //获取告警建议 113 | record.setSuggest(simpleTemplate.decodeTemplate(alertDictionary.getSuggest(),record.toMap())); 114 | //获取告警原因 115 | record.setReason(simpleTemplate.decodeTemplate(alertDictionary.getReason(),record.toMap())); 116 | 117 | } 118 | 119 | /** 120 | * @description 刷新配置信息 121 | * @date 2017/11/17 122 | * @author Niemingming 123 | */ 124 | public void refresh(){ 125 | init(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/model/AlertExcluse.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.model; 2 | 3 | import com.haier.alertmanager.configuration.AlertConstVariable; 4 | import com.mongodb.BasicDBObject; 5 | import com.mongodb.DBObject; 6 | import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; 7 | 8 | import java.io.UnsupportedEncodingException; 9 | import java.security.MessageDigest; 10 | import java.security.NoSuchAlgorithmException; 11 | import java.util.ArrayList; 12 | import java.util.Calendar; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * @description 告警通知的白名单对象,至少有startsAt和endsAt字段 18 | * @date 2017/11/16 19 | * @author Niemingming 20 | */ 21 | public class AlertExcluse { 22 | /*白名单生效时间*/ 23 | private long startsAt; 24 | /*白名单失效时间*/ 25 | private long endsAt; 26 | /*白名单id,有我们自己生成作为唯一标识,同样采用MD5算法生成*/ 27 | private String id; 28 | /*白名单过滤字段,该字段不做限制*/ 29 | private Map filters; 30 | private long max; 31 | 32 | public AlertExcluse() { 33 | //将最大值设置为1000年以后。用于表示无限大 34 | Calendar cal = Calendar.getInstance(); 35 | cal.set(Calendar.YEAR,3000); 36 | max = cal.getTimeInMillis()/1000; 37 | } 38 | /** 39 | * @description 通过数据库获取的白名单,去掉id,startsAt和endsAt字段 40 | * @date 2017/11/16 41 | * @author Niemingming 42 | */ 43 | public AlertExcluse(DBObject excluse) { 44 | this(); 45 | //从查询结果中,删除折扇项内容 46 | id = excluse.removeField("_id")+""; 47 | startsAt = excluse.get("startsAt") == null ? 0l : (Long)excluse.removeField("startsAt"); 48 | endsAt = excluse.get("endsAt") == null ? max : (Long)excluse.removeField("endsAt"); 49 | //将剩余key值作为白名单过滤字段 50 | filters = excluse.toMap(); 51 | } 52 | /** 53 | * @description 根据传入参数生成白名单对象 54 | * @date 2017/11/16 55 | * @author Niemingming 56 | */ 57 | public AlertExcluse(Map excluse){ 58 | this(); 59 | startsAt = excluse.get("startsAt") == null ? 0l : (Long)excluse.remove("startsAt"); 60 | endsAt = excluse.get("endsAt") == null ? max : (Long)excluse.remove("endsAt"); 61 | //计算id 62 | setFilters(excluse); 63 | } 64 | 65 | public long getStartsAt() { 66 | return startsAt; 67 | } 68 | 69 | public void setStartsAt(long startsAt) { 70 | this.startsAt = startsAt; 71 | } 72 | 73 | public long getEndsAt() { 74 | return endsAt; 75 | } 76 | 77 | public void setEndsAt(long endsAt) { 78 | this.endsAt = endsAt; 79 | } 80 | 81 | public String getId() { 82 | return id; 83 | } 84 | 85 | public void setId(String id) { 86 | this.id = id; 87 | } 88 | 89 | public Map getFilters() { 90 | return filters; 91 | } 92 | 93 | public void setFilters(Map filters) { 94 | this.filters = filters; 95 | setId(algExculseId(filters)); 96 | } 97 | 98 | public String algExculseId(Map data) { 99 | //计算id 100 | List algfields = new ArrayList(); 101 | for (String field : filters.keySet()){ 102 | algfields.add(field+"="+data.get(field)); 103 | } 104 | try { 105 | MessageDigest digest = MessageDigest.getInstance(AlertConstVariable.ALERT_ID_ALG); 106 | return HexBin.encode(digest.digest(algfields.toString().getBytes("UTF-8"))); 107 | } catch (NoSuchAlgorithmException e) { 108 | e.printStackTrace(); 109 | System.out.println("系统不支持配置的计算算法"); 110 | } catch (UnsupportedEncodingException e) { 111 | e.printStackTrace(); 112 | System.out.println("不支持的字符串编码格式"); 113 | } 114 | return "null"; 115 | } 116 | /** 117 | * @description 将属性值转为插入数据 118 | * @date 2017/11/16 119 | * @author Niemingming 120 | */ 121 | public DBObject toSql(){ 122 | DBObject object = new BasicDBObject(); 123 | object.put("_id",id); 124 | object.put("startsAt",startsAt); 125 | object.put("endsAt",endsAt); 126 | 127 | object.putAll(filters); 128 | return object; 129 | } 130 | 131 | /** 132 | * @description 输出以id为查询条件的mongo对象 133 | * @date 2017/11/16 134 | * @author Niemingming 135 | */ 136 | public DBObject toQuerySqlById(){ 137 | DBObject object = new BasicDBObject(); 138 | object.put("_id",id); 139 | return object; 140 | } 141 | 142 | @Override 143 | public boolean equals(Object o) { 144 | if (this == o) return true; 145 | if (o == null || getClass() != o.getClass()) return false; 146 | 147 | AlertExcluse that = (AlertExcluse) o; 148 | 149 | return id != null ? id.equals(that.id) : that.id == null; 150 | } 151 | 152 | @Override 153 | public int hashCode() { 154 | return id != null ? id.hashCode() : 0; 155 | } 156 | 157 | @Override 158 | public String toString() { 159 | return "AlertExcluse{" + 160 | "startsAt=" + startsAt + 161 | ", endsAt=" + endsAt + 162 | ", id='" + id + '\'' + 163 | ", filters=" + filters + 164 | '}'; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/notifyhandlers/ESNotifyStorageHandler.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.notifyhandlers; 2 | 3 | import com.google.gson.Gson; 4 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 5 | import com.haier.alertmanager.model.AlertRecord; 6 | import com.haier.alertmanager.service.LogService; 7 | import org.apache.http.HttpHost; 8 | import org.apache.http.entity.StringEntity; 9 | import org.elasticsearch.client.Response; 10 | import org.elasticsearch.client.ResponseListener; 11 | import org.elasticsearch.client.RestClient; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.data.mongodb.core.MongoTemplate; 15 | import org.springframework.stereotype.Component; 16 | 17 | import java.io.IOException; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * @description ES转储处理器,将告警历史数据转储到ES中,将ES转储作为默认方式,级别设置为最低 25 | * @date 2017/11/17 26 | * @author Niemingming 27 | */ 28 | @Order(999) 29 | @Component 30 | public class ESNotifyStorageHandler implements INotifyStorageHandler { 31 | @Autowired 32 | private AlertConfigurationProp alertConfigurationProp; 33 | @Autowired 34 | private MongoTemplate mongoTemplate; 35 | 36 | /*日志处理服务*/ 37 | @Autowired 38 | private LogService logService; 39 | /** 40 | * @description 默认ES实现,支持所有记录 41 | * @date 2017/11/17 42 | * @author Niemingming 43 | */ 44 | @Override 45 | public boolean shouldResolve(AlertRecord record) { 46 | return true; 47 | } 48 | /** 49 | * @description 通过Http转储到ES中,索引为recordId_yyyyMM 50 | * 类型为alertmanager,可通过配置 51 | * @date 2017/11/17 52 | * @author Niemingming 53 | */ 54 | @Override 55 | public void saveRecord(AlertRecord record) { 56 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(alertConfigurationProp.esDataPattern); 57 | HttpHost[] hosts = new HttpHost[alertConfigurationProp.esHostNames.size()]; 58 | for (int i = 0; i < hosts.length; i++ ){ 59 | hosts[i] = HttpHost.create(alertConfigurationProp.esHostNames.get(i)); 60 | } 61 | //创建ES请求客户端 62 | RestClient restClient = RestClient.builder(hosts).build(); 63 | //请求参数 64 | Map params = new HashMap(); 65 | String dateformat = simpleDateFormat.format(new Date()); 66 | //计算ES数据索引,ESid必须是小写字母 67 | String index = alertConfigurationProp.indexpre + dateformat; 68 | Gson requestBody = new Gson(); 69 | //ES数据内容,id作为ES关键字不能再数据体中出现 70 | Map bodymap = record.toSql().toMap(); 71 | bodymap.remove("_id"); 72 | bodymap.remove("alertId");//删除告警id,该值作为ESid使用 73 | 74 | String body = requestBody.toJson(bodymap); 75 | //获取ES数据id 76 | String id = record.getAlertId(); 77 | //获取ES保存接口endpoint 78 | String endpoint = "/" + index + "/" + alertConfigurationProp.esType + "/" + id; 79 | StringEntity queryBody = new StringEntity(body,"UTF-8"); 80 | queryBody.setContentType("application/json;charset=UTF-8"); 81 | try { 82 | restClient.performRequestAsync("PUT",endpoint,params,queryBody,new EsResponseLisnter(record,index,id,dateformat,restClient)); 83 | } catch (Exception e) { 84 | //抛出异常关闭连接 85 | e.printStackTrace(); 86 | if (restClient != null) { 87 | try { 88 | restClient.close(); 89 | } catch (IOException e1) { 90 | e1.printStackTrace(); 91 | } 92 | } 93 | } 94 | //错误信息存在日志文件中,我们需要删除记录 95 | mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).remove(record.toQuerySqlById()); 96 | 97 | } 98 | /** 99 | * @description 异步请求回调函数,防止因网络请求阻塞程序运行 100 | * @date 2017/11/17 101 | * @author Niemingming 102 | */ 103 | public class EsResponseLisnter implements ResponseListener { 104 | 105 | private AlertRecord record; 106 | private String index; 107 | private String id; 108 | private String dateformat; 109 | private RestClient restClient; 110 | public EsResponseLisnter(AlertRecord record, String index, String id, String dateformat, RestClient restClient){ 111 | this.record = record; 112 | this.index = index; 113 | this.id = id; 114 | this.dateformat = dateformat; 115 | this.restClient = restClient; 116 | } 117 | 118 | @Override 119 | public void onSuccess(Response response) { 120 | int code = response.getStatusLine().getStatusCode(); 121 | if (code >= 200 && code < 400){ 122 | System.out.println("【" + record.getAlertname() + "】转储ES成功"); 123 | }else { 124 | System.out.println("告警信息转储失败,转储信息如下:"); 125 | System.out.println(record.toString()); 126 | logService.writeLog(record,index,id,dateformat + ".log"); 127 | } 128 | if (restClient != null) { 129 | try { 130 | restClient.close(); 131 | } catch (IOException e) { 132 | e.printStackTrace(); 133 | } 134 | } 135 | } 136 | 137 | @Override 138 | public void onFailure(Exception e) { 139 | System.out.println("转储告警信息过程出现异常,信息如下:"); 140 | System.out.println(record); 141 | e.printStackTrace(); 142 | logService.writeLog(record,index,id,dateformat + ".log"); 143 | if (restClient != null) { 144 | try { 145 | restClient.close(); 146 | } catch (IOException e1) { 147 | e1.printStackTrace(); 148 | } 149 | } 150 | } 151 | } 152 | 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/notifyhandlers/NotifySendCommonHandler.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.notifyhandlers; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import com.haier.alertmanager.configuration.AlertConfigurationProp; 6 | import com.haier.alertmanager.container.AlertDictionaryContainer; 7 | import com.haier.alertmanager.container.AlertRecordContainer; 8 | import com.haier.alertmanager.container.MessageReceiverContainer; 9 | import com.haier.alertmanager.model.AlertRecord; 10 | import com.haier.alertmanager.model.MessageReceiverInfo; 11 | import com.mongodb.DBObject; 12 | import org.apache.http.HttpResponse; 13 | import org.apache.http.NameValuePair; 14 | import org.apache.http.client.HttpClient; 15 | import org.apache.http.client.config.RequestConfig; 16 | import org.apache.http.client.methods.HttpPost; 17 | import org.apache.http.entity.StringEntity; 18 | import org.apache.http.impl.client.HttpClients; 19 | import org.apache.http.message.BasicNameValuePair; 20 | import org.apache.http.util.EntityUtils; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.core.annotation.Order; 23 | import org.springframework.data.mongodb.core.MongoTemplate; 24 | import org.springframework.stereotype.Component; 25 | 26 | import javax.annotation.PostConstruct; 27 | import java.util.ArrayList; 28 | import java.util.Date; 29 | import java.util.List; 30 | 31 | /** 32 | * @description 通用告警发送处理器,规则为接收到消息,判断是否已经发送过,如果没有立刻发送。不考虑其他逻辑 33 | * @date 2017/11/17 34 | * @author Niemingming 35 | */ 36 | @Order(999)//将该发送处理器设置为最低级别,便于客户规则覆盖 37 | @Component 38 | public class NotifySendCommonHandler implements INotifySendHanlder { 39 | @Autowired 40 | private AlertRecordContainer alertRecordContainer; 41 | @Autowired 42 | private AlertConfigurationProp alertConfigurationProp; 43 | /*消息接收者容器*/ 44 | @Autowired 45 | private MessageReceiverContainer messageReceiverContainer; 46 | /*通知重发时间间隔,单位秒*/ 47 | private long resendinterval; 48 | /*MongoDB数据库操作*/ 49 | @Autowired 50 | private MongoTemplate mongoTemplate; 51 | /**数据字典*/ 52 | @Autowired 53 | private AlertDictionaryContainer alertDictionaryContainer; 54 | 55 | /** 56 | * @description 初始化方法 57 | * @date 2017/11/20 58 | * @author Niemingming 59 | */ 60 | @PostConstruct 61 | public void init(){ 62 | String interval = alertConfigurationProp.resendinterval; 63 | if ("".equals(interval)){ 64 | interval = "1h";//默认轮询间隔是1小时 65 | } 66 | char flag = interval.charAt(interval.length() - 1); 67 | resendinterval = 0l; 68 | //天数 69 | if (flag == 'd'){ 70 | resendinterval = Long.parseLong(interval.substring(0,interval.length()-1)); 71 | resendinterval *= 24*60*60; 72 | }else if (flag == 'h'){//小时 73 | resendinterval = Long.parseLong(interval.substring(0,interval.length()-1)); 74 | resendinterval *= 60*60; 75 | }else if (flag == 'm'){//分钟 76 | resendinterval = Long.parseLong(interval.substring(0,interval.length()-1)); 77 | resendinterval *= 60; 78 | }else if (flag == 's'){//秒 79 | resendinterval = Long.parseLong(interval.substring(0,interval.length()-1)); 80 | }else {//默认单位是秒 81 | resendinterval = Long.parseLong(interval); 82 | } 83 | } 84 | @Override 85 | public boolean supportRule(AlertRecord record) { 86 | //总是返回true,表示可以处理所有的告警信息。 87 | return true; 88 | } 89 | 90 | @Override 91 | public synchronized void sendNotify(AlertRecord record) { 92 | //修改了线程同步的,进入后重新校验上次通知时间,防止因发送间隔过短造成的消息重复发送 93 | DBObject recordRes = mongoTemplate.getCollection(alertConfigurationProp.alertRecordTalbeName).findOne(record.toQuerySqlById()); 94 | record = new AlertRecord(recordRes); 95 | long now = new Date().getTime()/1000; 96 | if (record.getLastNotifyTime() == 0 97 | || now - record.getLastNotifyTime() >= resendinterval 98 | || record.getEndsAt() > record.getLastNotifyTime()){ 99 | String message = alertDictionaryContainer.getNotifyMessage(record); 100 | record.setMessage(message); 101 | 102 | //将发送规则下沉到具体规则实现中,这里规则是当没有发送过通知,或者发送通知达到重发间隔时发送消息通知,或者消息结束时间大于上次通知时间,表示还没发送过。 103 | List messageReceiverInfos = messageReceiverContainer.getReceiversByRecord(record); 104 | if (messageReceiverInfos.isEmpty()) { 105 | System.out.println("告警信息【" + record.getAlertname() + "】未配置消息接收者!"); 106 | }else { 107 | //发送消息,先做成同步发送,看一下效果 108 | HttpClient client = HttpClients.createDefault(); 109 | HttpPost post = new HttpPost(alertConfigurationProp.messageUri); 110 | //设置访问超时时间 111 | RequestConfig config = RequestConfig.custom().setConnectTimeout(10000) 112 | .setSocketTimeout(10000).setConnectionRequestTimeout(10000).build(); 113 | post.setConfig(config); 114 | //获取所有请求人员 115 | List targets = new ArrayList(); 116 | for (MessageReceiverInfo messageReceiverInfo:messageReceiverInfos){ 117 | targets.add(messageReceiverInfo.getPersonId()); 118 | } 119 | 120 | //构建参数 121 | notifyParam param = new notifyParam(); 122 | //修改标题格式为 互联互通-告警平台: 123 | param.subject = "互联互通-告警平台:" + record.getProject() + "-" + alertConfigurationProp.alertType.get(record.getAlertname()); 124 | param.content = record.getMessage(); 125 | param.targets = targets; 126 | param.id = record.getAlertId(); 127 | try { 128 | //改为请求体格式 129 | StringEntity entity = new StringEntity(new Gson().toJson(param),"utf-8"); 130 | entity.setContentType("application/json;charset=utf-8"); 131 | post.setEntity(entity); 132 | //执行请求 133 | HttpResponse response = client.execute(post); 134 | String result = EntityUtils.toString(response.getEntity()); 135 | JsonObject res = new Gson().fromJson(result,JsonObject.class); 136 | if (res.get("isSuccess").getAsBoolean()) { 137 | record.setLastNotifyTime(new Date().getTime()/1000); 138 | alertRecordContainer.updateRecord(record); 139 | System.out.println("消息已经发送"); 140 | }else { 141 | System.out.println("消息发送失败! "+ res.get("msg").getAsString()); 142 | } 143 | } catch (Exception e) { 144 | e.printStackTrace(); 145 | System.out.println("调用消息服务失败!"); 146 | } 147 | } 148 | } 149 | 150 | } 151 | /** 152 | * @description 告警通知参数类 153 | * @date 2017/11/27 154 | * @author Niemingming 155 | */ 156 | public class notifyParam { 157 | /*通知主题*/ 158 | public String subject; 159 | /*通知目标*/ 160 | public List targets; 161 | /*通知内容*/ 162 | public String content; 163 | /*通知类型1:既发送邮件又发送iHaier消息*/ 164 | public int messageType = 1; 165 | /*告警id*/ 166 | public String id; 167 | /** 168 | * @description 返回post请求参数 169 | * @date 2017/11/27 170 | * @author Niemingming 171 | */ 172 | public List toParams(){ 173 | List pairs = new ArrayList(); 174 | NameValuePair subjectPair = new BasicNameValuePair("subject",subject); 175 | NameValuePair contentPair = new BasicNameValuePair("content",content); 176 | NameValuePair targetsPair = new BasicNameValuePair("targets",targets.toString()); 177 | NameValuePair messageTypePair = new BasicNameValuePair("messageType",messageType+""); 178 | pairs.add(subjectPair); 179 | pairs.add(contentPair); 180 | pairs.add(targetsPair); 181 | pairs.add(messageTypePair); 182 | return pairs; 183 | } 184 | 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /alertmanager.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/test/controller/ApiTest.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.test.controller; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonArray; 5 | import org.apache.http.HttpEntity; 6 | import org.apache.http.HttpResponse; 7 | import org.apache.http.client.HttpClient; 8 | import org.apache.http.client.methods.HttpGet; 9 | import org.apache.http.client.methods.HttpPost; 10 | import org.apache.http.entity.StringEntity; 11 | import org.apache.http.impl.client.HttpClients; 12 | import org.apache.http.util.EntityUtils; 13 | 14 | import java.io.*; 15 | import java.net.HttpURLConnection; 16 | import java.net.URL; 17 | 18 | /** 19 | * @description api服务调用测试 20 | * @date 2017/11/22 21 | * @author Niemingming 22 | */ 23 | public class ApiTest { 24 | 25 | public static void main(String[]args) throws IOException { 26 | // queryList(); 27 | // queryById(); 28 | // queryHistoryList(); 29 | // queryHistoryById(); 30 | searchHistoryList(); 31 | // queryGroup(); 32 | // testgson(); 33 | // queryLevelCode(); 34 | // queryCode("queryAlertLevels"); 35 | // queryCode("queryAlertCategories"); 36 | // queryCode("queryAlertTypes"); 37 | // queryCode("queryAlertCode"); 38 | // sendPostNotify("http://10.138.16.192:8080/api/queryAlertingList","{pageinfo:{currentPage:1,pageSize:10}}"); 39 | } 40 | 41 | 42 | public static void queryList() throws IOException { 43 | HttpClient client = HttpClients.createDefault(); 44 | HttpPost post = new HttpPost("http://10.138.16.192:8080/api/queryAlertingList"); 45 | //不分页查询,列表查询为POST请求方式,条件为project= 46 | StringBuilder stringBuilder = new StringBuilder(); 47 | stringBuilder.append("{") 48 | .append(" pageinfo:{currentPage:1,pageSize:1},") 49 | .append(" query:{") 50 | // .append(" \"project\":[\"project1\",\"project2\"],") 51 | .append(" \"times\":{$gt:1}") 52 | .append(" }") 53 | .append("}"); 54 | StringEntity stringEntity = new StringEntity(stringBuilder.toString()); 55 | post.setEntity(stringEntity); 56 | HttpResponse response = client.execute(post); 57 | HttpEntity res = response.getEntity(); 58 | System.out.println(EntityUtils.toString(res)); 59 | } 60 | 61 | public static void queryById() throws IOException { 62 | HttpClient client = HttpClients.createDefault(); 63 | HttpGet get = new HttpGet("http://localhost:8081/api/queryAlertingById/247D78214DCCD7FE830EC039F2B310C4"); 64 | HttpResponse response = client.execute(get); 65 | HttpEntity res = response.getEntity(); 66 | System.out.println(EntityUtils.toString(res)); 67 | } 68 | 69 | public static void queryHistoryList() throws IOException { 70 | HttpClient client = HttpClients.createDefault(); 71 | HttpPost post = new HttpPost("http://localhost:8081/api/queryHistoryList"); 72 | //不分页查询,列表查询为POST请求方式,条件为project= 73 | StringBuilder stringBuilder = new StringBuilder(); 74 | stringBuilder.append("{") 75 | .append(" pageinfo:{currentPage:1,pageSize:2},") 76 | .append(" query:{") 77 | .append(" \"project\":[\"project1\",\"project2\"],") 78 | .append(" times:{$gt:100}") 79 | .append(" }") 80 | .append("}"); 81 | StringEntity stringEntity = new StringEntity(stringBuilder.toString(),"UTF-8"); 82 | post.setEntity(stringEntity); 83 | HttpResponse response = client.execute(post); 84 | HttpEntity res = response.getEntity(); 85 | System.out.println(EntityUtils.toString(res)); 86 | } 87 | 88 | public static void queryHistoryById() throws IOException { 89 | HttpClient client = HttpClients.createDefault(); 90 | HttpGet get = new HttpGet("http://localhost:8081/api/queryHistoryById/alert-201711/FC6EF20EED02AA884745283049CDE2B2-1511772777"); 91 | HttpResponse response = client.execute(get); 92 | HttpEntity res = response.getEntity(); 93 | System.out.println(EntityUtils.toString(res)); 94 | } 95 | 96 | public static void searchHistoryList() throws IOException { 97 | HttpClient client = HttpClients.createDefault(); 98 | HttpPost post = new HttpPost("http://localhost:8081/api/searchHistoryList/my1"); 99 | //不分页查询,列表查询为POST请求方式,条件为project= 100 | StringBuilder stringBuilder = new StringBuilder(); 101 | stringBuilder.append("{") 102 | .append(" pageinfo:{currentPage:1,pageSize:2},") 103 | .append(" query:{") 104 | .append(" \"project\":[\"project1\",\"project2\"],") 105 | .append(" times:{$gte:10}") 106 | .append(" }") 107 | .append("}"); 108 | StringEntity stringEntity = new StringEntity(stringBuilder.toString(),"UTF-8"); 109 | post.setEntity(stringEntity); 110 | HttpResponse response = client.execute(post); 111 | HttpEntity res = response.getEntity(); 112 | System.out.println(EntityUtils.toString(res)); 113 | } 114 | 115 | public static void queryGroup() throws IOException { 116 | HttpClient client = HttpClients.createDefault(); 117 | HttpPost post = new HttpPost("http://localhost:8081/api/queryAlertingByGroup"); 118 | //不分页查询,列表查询为POST请求方式,条件为project= 119 | StringBuilder stringBuilder = new StringBuilder(); 120 | stringBuilder.append("{") 121 | .append(" query:{") 122 | .append(" \"project\":[\"project1\",\"project2\"]") 123 | .append(" },") 124 | .append(" group:[\"project\"]") 125 | .append("}"); 126 | StringEntity stringEntity = new StringEntity(stringBuilder.toString()); 127 | post.setEntity(stringEntity); 128 | HttpResponse response = client.execute(post); 129 | HttpEntity res = response.getEntity(); 130 | System.out.println(EntityUtils.toString(res)); 131 | } 132 | 133 | public static void queryLevelCode() throws IOException { 134 | HttpClient client = HttpClients.createDefault(); 135 | HttpGet get = new HttpGet("http://10.138.16.192:8080/api/queryAlertLevels"); 136 | HttpResponse response = client.execute(get); 137 | HttpEntity res = response.getEntity(); 138 | System.out.println(EntityUtils.toString(res)); 139 | } 140 | 141 | public static void queryCode(String uri) throws IOException { 142 | HttpClient client = HttpClients.createDefault(); 143 | HttpGet get = new HttpGet("http://localhost:8081/api/" + uri); 144 | HttpResponse response = client.execute(get); 145 | HttpEntity res = response.getEntity(); 146 | System.out.println(EntityUtils.toString(res)); 147 | } 148 | 149 | public static void testgson(){ 150 | Gson gson = new Gson(); 151 | JsonArray list= gson.fromJson("[1,2,3]", JsonArray.class); 152 | System.out.println(list); 153 | } 154 | 155 | public static void sendPostNotify(String strURL, String params) { 156 | System.out.println(strURL); 157 | System.out.println(params); 158 | // Response result=new Response(); 159 | try { 160 | URL url = new URL(strURL);// 创建连接 161 | HttpURLConnection connection = (HttpURLConnection) url 162 | .openConnection(); 163 | connection.setDoOutput(true); 164 | connection.setDoInput(true); 165 | connection.setUseCaches(false); 166 | connection.setInstanceFollowRedirects(true); 167 | connection.setRequestMethod("POST"); // 设置请求方式 168 | connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式 169 | connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式 170 | connection.connect(); 171 | OutputStreamWriter out = new OutputStreamWriter( 172 | connection.getOutputStream(), "UTF-8"); // utf-8编码 173 | out.append(params); 174 | out.flush(); 175 | out.close(); 176 | // 读取响应 177 | int length = (int) connection.getContentLength();// 获取长度 178 | InputStream is = connection.getInputStream(); 179 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 180 | byte[] temp = new byte[1024]; 181 | int readLen = 0; 182 | int destPos = 0; 183 | while ((readLen = is.read(temp)) > 0) { 184 | // System.arraycopy(temp, 0, data, destPos, readLen); 185 | // destPos += readLen; 186 | bos.write(temp,0,readLen); 187 | } 188 | // result=result.ok(new String(data, "UTF-8")); 189 | System.out.println(new String(bos.toByteArray())); 190 | if (length != -1) { 191 | } 192 | } catch (IOException e) { 193 | // log.error("【NotifyServiceImpl.sendPostNotify】调用方法报错"+e); 194 | // result=result.fail(Constant.CODE_ONE, "查询告警信息失败!"); 195 | // return result; 196 | } 197 | // return result; 198 | 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/main/java/com/haier/alertmanager/model/AlertRecord.java: -------------------------------------------------------------------------------- 1 | package com.haier.alertmanager.model; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonPrimitive; 6 | import com.haier.alertmanager.configuration.AlertConstVariable; 7 | import com.mongodb.BasicDBObject; 8 | import com.mongodb.DBObject; 9 | import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; 10 | 11 | import java.io.UnsupportedEncodingException; 12 | import java.math.BigDecimal; 13 | import java.security.MessageDigest; 14 | import java.security.NoSuchAlgorithmException; 15 | import java.text.ParseException; 16 | import java.text.SimpleDateFormat; 17 | import java.util.*; 18 | 19 | /** 20 | * @description 告警记录实体 21 | * @date 2017/11/16 22 | * @author Niemingming 23 | */ 24 | public class AlertRecord { 25 | /*系统编码,根据labels生成的md5码,也是告警信息的唯一标识*/ 26 | private String id; 27 | /*告警id与ESId相对应*/ 28 | private String alertId; 29 | /*告警名称*/ 30 | private String alertname; 31 | /*告警开始时间*/ 32 | private long startsAt; 33 | /*告警结束时间*/ 34 | private long endsAt; 35 | /*上次通知发出时间*/ 36 | private long lastNotifyTime; 37 | /*最后一次接收到告警时间*/ 38 | private long lastReceiveTime; 39 | /*告警信息的所有labels*/ 40 | private Map labels; 41 | /*排序后的labes字符串*/ 42 | private String sortLabels; 43 | /**告警状态*/ 44 | private String status; 45 | /*告警级别*/ 46 | private String level; 47 | /**接收通知次数*/ 48 | private int times = 0; 49 | /**通知消息*/ 50 | private String message; 51 | /*告警描述*/ 52 | private String description; 53 | /*告警建议*/ 54 | private String suggest; 55 | /*告警分类*/ 56 | private String alertCategory; 57 | /*项目名称*/ 58 | private String project; 59 | /*告警值*/ 60 | private Double value; 61 | /*度量单位*/ 62 | private String unit; 63 | /*告警原因*/ 64 | private String reason; 65 | /** 66 | * @description 空函数的初始化操作,用于该类的一些方法 67 | * @date 2017/11/16 68 | * @author Niemingming 69 | */ 70 | public AlertRecord(){ 71 | } 72 | /** 73 | * @description 接收到告警信息时的初始化操作 74 | * @date 2017/11/16 75 | * @author Niemingming 76 | */ 77 | public AlertRecord(JsonObject record){ 78 | //处理告警开始时间、结束时间和接收时间 79 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(AlertConstVariable.ALERT_TIME_PATTERN); 80 | startsAt = getAlertTime(record,"startsAt",simpleDateFormat); 81 | endsAt = getAlertTime(record,"endsAt",simpleDateFormat); 82 | lastReceiveTime = new Date().getTime()/1000;//精确到秒 83 | times = 1; 84 | status = AlertConstVariable.ALERT_STATUS_FIRING;//告警状态为触发状态 85 | //读取注解信息,从里面尝试获取单位和告警值 86 | JsonObject annotations = record.get("annotations") == null ? null:record.getAsJsonObject("annotations"); 87 | if (annotations != null){//有数据,尝试获取unit和value 88 | if (annotations.get("unit") != null && annotations.get("unit").isJsonPrimitive()){ 89 | unit = annotations.get("unit").getAsString(); 90 | } 91 | if (annotations.get("value") != null&& annotations.get("value").isJsonPrimitive()){ 92 | value = annotations.get("value").getAsDouble(); 93 | //value做精度处理 94 | if (value != null) { 95 | value = new BigDecimal(value).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue(); 96 | } 97 | } 98 | } 99 | Map labels = null; 100 | JsonObject jsonLabels = record.get("labels") == null ? null :record.get("labels").getAsJsonObject(); 101 | if (jsonLabels != null){ 102 | labels = new HashMap(); 103 | for (Map.Entry entry:jsonLabels.entrySet()){ 104 | labels.put(entry.getKey(),entry.getValue().getAsString()); 105 | } 106 | } 107 | 108 | if (labels == null){ 109 | System.out.println("未找到告警信息的【lables】标识,无法初始化"); 110 | }else { 111 | //labels中的monitor、severity、cluster属性,不用于id计算,不在存储。 112 | labels.remove("monitor"); 113 | labels.remove("severity"); 114 | labels.remove("cluster"); 115 | setLabels(labels);//使用所有的labels计算id 116 | //提取字段 117 | String alertname = labels.remove("alertname") + ""; 118 | setAlertname(alertname); 119 | //提取项目 120 | String project = labels.remove("project") + ""; 121 | setProject(project); 122 | } 123 | } 124 | /** 125 | * @description 获取指定的告警时间 126 | * @date 2017/11/16 127 | * @author Niemingming 128 | */ 129 | private long getAlertTime(JsonObject record, String key, SimpleDateFormat simpleDateFormat) { 130 | Object start = record.get(key); 131 | if (start != null) { 132 | String startstr = ((JsonPrimitive)start).getAsString().replace("T"," ").substring(0,Math.min(19,start.toString().length())); 133 | try { 134 | return simpleDateFormat.parse(startstr).getTime()/1000; 135 | } catch (ParseException e) { 136 | System.out.println("告警时间格式不正确!"); 137 | e.printStackTrace(); 138 | } 139 | } 140 | return 0; 141 | } 142 | 143 | /** 144 | * @description 从mongo查询出来的结果初始化操作 145 | * @date 2017/11/16 146 | * @author Niemingming 147 | */ 148 | public AlertRecord(DBObject record){ 149 | 150 | //提取非labels字段,并赋值 151 | String mid = record.removeField("_id")+""; 152 | startsAt = record.get("startsAt") == null ? 0l :(Long) record.removeField("startsAt"); 153 | endsAt = record.get("endsAt") == null ? 0l :(Long) record.removeField("endsAt"); 154 | lastReceiveTime = record.get("lastReceiveTime") == null ? 0l :(Long) record.removeField("lastReceiveTime"); 155 | lastNotifyTime = record.get("lastNotifyTime") == null ? 0l :(Long) record.removeField("lastNotifyTime"); 156 | times = record.get("times") == null ? 0 :(Integer) record.removeField("times"); 157 | status = record.removeField("status")+""; 158 | alertId = record.removeField("alertId")+""; 159 | level = record.removeField("level") + ""; 160 | //抽取project、suggest、description、alertname、alertCategory 161 | project = record.get("project") + ""; 162 | alertname = record.get("alertname") + ""; 163 | suggest = record.get("suggest") + ""; 164 | description = record.get("description") + ""; 165 | alertCategory = record.get("alertCategory") + ""; 166 | message = description +"\n" + suggest; 167 | value = record.get("value") == null ? null : (Double) record.removeField("value"); 168 | unit = record.get("unit") == null ? null : record.get("unit")+""; 169 | reason = record.get("reason") == null ? null : record.get("reason")+""; 170 | //形成labels字段,并计算id 171 | setLabels(record.get("labels") == null ? new HashMap() : (Map) record.get("labels")); 172 | id = mid; 173 | } 174 | 175 | public String getId() { 176 | return id; 177 | } 178 | 179 | public void setId(String id) { 180 | this.id = id; 181 | setAlertId(id + "-" + startsAt); 182 | } 183 | 184 | public String getAlertname() { 185 | return alertname; 186 | } 187 | 188 | public void setAlertname(String alertname) { 189 | this.alertname = alertname; 190 | } 191 | 192 | public long getStartsAt() { 193 | return startsAt; 194 | } 195 | 196 | public void setStartsAt(long startAt) { 197 | this.startsAt = startAt; 198 | } 199 | 200 | public long getEndsAt() { 201 | return endsAt; 202 | } 203 | 204 | public void setEndsAt(long endsAt) { 205 | this.endsAt = endsAt; 206 | } 207 | 208 | public long getLastNotifyTime() { 209 | return lastNotifyTime; 210 | } 211 | 212 | public void setLastNotifyTime(long lastNotifyTime) { 213 | this.lastNotifyTime = lastNotifyTime; 214 | } 215 | 216 | public long getLastReceiveTime() { 217 | return lastReceiveTime; 218 | } 219 | 220 | public void setLastReceiveTime(long lastReceiveTime) { 221 | this.lastReceiveTime = lastReceiveTime; 222 | } 223 | 224 | public String getProject() { 225 | return project; 226 | } 227 | 228 | public void setProject(String project) { 229 | this.project = project; 230 | } 231 | 232 | public String getDescription() { 233 | return description; 234 | } 235 | 236 | public void setDescription(String description) { 237 | this.description = description; 238 | } 239 | 240 | public String getSuggest() { 241 | return suggest; 242 | } 243 | 244 | public void setSuggest(String suggest) { 245 | this.suggest = suggest; 246 | } 247 | 248 | public String getAlertCategory() { 249 | return alertCategory; 250 | } 251 | 252 | public void setAlertCategory(String alertCategory) { 253 | this.alertCategory = alertCategory; 254 | } 255 | 256 | public Map getLabels() { 257 | return labels; 258 | } 259 | 260 | public double getValue() { 261 | return value; 262 | } 263 | 264 | public void setValue(double value) { 265 | this.value = value; 266 | } 267 | 268 | public String getReason() { 269 | return reason; 270 | } 271 | 272 | public void setReason(String reason) { 273 | this.reason = reason; 274 | } 275 | 276 | public void setLabels(Map labels) { 277 | this.labels = labels; 278 | List labelstr = new ArrayList(); 279 | for (Object key : labels.keySet()){ 280 | if (key == null){ 281 | continue;//忽略null值对告警信息的判断 282 | } 283 | Object value = labels.get(key); 284 | labelstr.add(key+"="+value); 285 | } 286 | //将labels排序后形成字符串,为后面id计算准备 287 | Collections.sort(labelstr); 288 | setSortLabels(labelstr.toString()); 289 | } 290 | 291 | public String getSortLabels() { 292 | return sortLabels; 293 | } 294 | /** 295 | * @description 设置排序后的整体字符串,同时计算id值 296 | * @date 2017/11/16 297 | * @author Niemingming 298 | */ 299 | public void setSortLabels(String sortLabels) { 300 | this.sortLabels = sortLabels; 301 | //计算labels的md5码 302 | try { 303 | MessageDigest messageDigest = MessageDigest.getInstance(AlertConstVariable.ALERT_ID_ALG); 304 | //ES不支持大写字母,统一双方字符 305 | setId(HexBin.encode(messageDigest.digest(sortLabels.getBytes("UTF-8")))); 306 | } catch (NoSuchAlgorithmException e) { 307 | e.printStackTrace(); 308 | System.out.println("系统不支持配置的计算算法"); 309 | } catch (UnsupportedEncodingException e) { 310 | e.printStackTrace(); 311 | System.out.println("不支持的字符串编码格式"); 312 | } 313 | } 314 | public int getTimes() { 315 | return times; 316 | } 317 | 318 | public void setTimes(int times) { 319 | this.times = times; 320 | } 321 | @Override 322 | public boolean equals(Object o) { 323 | if (this == o) return true; 324 | if (o == null || getClass() != o.getClass()) return false; 325 | 326 | AlertRecord that = (AlertRecord) o; 327 | 328 | return id.equals(that.id); 329 | } 330 | 331 | public String getStatus() { 332 | return status; 333 | } 334 | 335 | public void setStatus(String status) { 336 | this.status = status; 337 | } 338 | 339 | public String getMessage() { 340 | return message; 341 | } 342 | 343 | public void setMessage(String message) { 344 | this.message = message; 345 | } 346 | 347 | public String getLevel() { 348 | return level; 349 | } 350 | 351 | public void setLevel(String level) { 352 | this.level = level; 353 | } 354 | 355 | public String getAlertId() { 356 | return alertId; 357 | } 358 | 359 | public void setAlertId(String alertId) { 360 | this.alertId = alertId; 361 | } 362 | 363 | public void setValue(Double value) { 364 | this.value = value; 365 | } 366 | 367 | public String getUnit() { 368 | return unit; 369 | } 370 | 371 | public void setUnit(String unit) { 372 | this.unit = unit; 373 | } 374 | 375 | /** 376 | * @description 将属性值转为插入数据 377 | * @date 2017/11/16 378 | * @author Niemingming 379 | */ 380 | public DBObject toSql(){ 381 | DBObject object = new BasicDBObject(); 382 | object.put("_id",id); 383 | object.put("startsAt",startsAt); 384 | object.put("endsAt",endsAt); 385 | object.put("lastNotifyTime",lastNotifyTime); 386 | object.put("lastReceiveTime",lastReceiveTime); 387 | object.put("times",times); 388 | object.put("status",status); 389 | object.put("level",level); 390 | object.put("alertId",alertId); 391 | object.put("project",project); 392 | object.put("suggest",suggest); 393 | object.put("description",description); 394 | object.put("alertCategory",alertCategory); 395 | object.put("alertname",alertname); 396 | object.put("value",value); 397 | object.put("unit",unit); 398 | object.put("reason",reason); 399 | object.put("labels",this.labels); 400 | return object; 401 | } 402 | /** 403 | * @description 生成模板替换需要的数据 404 | * @date 2017/11/16 405 | * @author Niemingming 406 | */ 407 | public Map toMap(){ 408 | DBObject object = toSql(); 409 | object.put("startsAt",new Date(this.startsAt*1000)); 410 | object.put("endsAt",new Date(this.endsAt*1000)); 411 | object.put("lastNotifyTime",new Date(this.lastNotifyTime*1000)); 412 | object.put("lastReceiveTime",new Date(this.lastReceiveTime*1000)); 413 | return object.toMap(); 414 | } 415 | /** 416 | * @description 输出以id为查询条件的mongo对象 417 | * @date 2017/11/16 418 | * @author Niemingming 419 | */ 420 | public DBObject toQuerySqlById(){ 421 | DBObject object = new BasicDBObject(); 422 | object.put("_id",id); 423 | return object; 424 | } 425 | 426 | @Override 427 | public int hashCode() { 428 | return id.hashCode(); 429 | } 430 | 431 | @Override 432 | public String toString() { 433 | return "AlertRecord{" + 434 | "id='" + id + '\'' + 435 | ", alertId='" + alertId + '\'' + 436 | ", alertname='" + alertname + '\'' + 437 | ", startsAt=" + startsAt + 438 | ", endsAt=" + endsAt + 439 | ", lastNotifyTime=" + lastNotifyTime + 440 | ", lastReceiveTime=" + lastReceiveTime + 441 | ", labels=" + labels + 442 | ", sortLabels='" + sortLabels + '\'' + 443 | ", status='" + status + '\'' + 444 | ", level='" + level + '\'' + 445 | ", times=" + times + 446 | ", message='" + message + '\'' + 447 | ", description='" + description + '\'' + 448 | ", suggest='" + suggest + '\'' + 449 | ", alertCategory='" + alertCategory + '\'' + 450 | ", project='" + project + '\'' + 451 | ", value='" + value + '\'' + 452 | ", unit='" + unit + '\'' + 453 | '}'; 454 | } 455 | } 456 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # alertmanager 2 | ## 目录 3 | * [1.数据查询](#1) 4 | * [1.1.当前告警查询](#1.1) 5 | * [1.1.1.告警列表查询](#1.1.1) 6 | * [1.1.2.告警详情查询](#1.1.2) 7 | * [1.1.3.告警数据统计](#1.1.3) 8 | * [1.2.历史告警查询](#1.2) 9 | * [1.2.1.历史告警列表查询](#1.2.1) 10 | * [1.2.2.历史告警详情查询](#1.2.2) 11 | * [1.2.3.历史告警搜索](#1.2.3) 12 | * [1.3.公共编码查询](#1.3) 13 | * [1.3.1.告警级别编码查询](#1.3.1) 14 | * [1.3.2.告警分类编码查询](#1.3.2) 15 | * [1.3.3.告警类型编码查询](#1.3.3) 16 | * [1.3.4.告警编码查询](#1.3.4) 17 | * [2.系统配置](#2) 18 | * [2.1.配置信息刷新](#2.1) 19 | 20 |

1.数据查询

21 | 数据查询底层是http协议,采用rest风格url作为服务提供。主要包括当前正在告警的数据查询和历史告警数据查询。 22 |

1.1当前告警查询

23 | 提供当前正在发生的告警记录查询接口。 24 |
1.1.1.告警列表查询
25 | 查询当前告警列表数据,如果不传分页信息,则查询当前所有的告警记录,否则查询当页告警记录。具体格式如下: 26 |
查询格式 27 | 28 | ``` 29 | POST /api/queryAlertingList 30 | { 31 | pageinfo:{//分页信息如果不传,表示不分页 32 |         currentPage:10, //当前页码,从1开始 33 |         pageSize:10 //每页显示多少条,默认10条, 34 | }, 35 | query:{//查询条件,遵循mongo的查询格式 36 | alertname:"testalert", 37 | "labels.job":"tomcat", 38 | times:{$gte:"10"} 39 | } 40 | } 41 | ``` 42 | 返回数据格式 43 | 44 | ``` 45 | { 46 | success:bool(true/false),//表示是否成功 47 | code:0/1 ,//执行结果编码,目前只有0成功,1失败 48 |      data:{ 49 |        page:{ 50 | total:4, 51 | currentPage:1 52 | }, 53 | list:[ 54 | { 55 | startsAt:... 56 | } 57 | ] 58 |      }, //表示返回的记录列表详情 59 | msg:string //服务器返回的提示信息,一般在访问失败时给出。 60 | } 61 | ``` 62 | 我们用httpClient来模拟post请求,尝试查询project=project1的数据。具体请求代码如下: 63 | 64 | ``` 65 | HttpClient client = HttpClients.createDefault(); 66 | HttpPost post = new HttpPost("http://localhost:8081/api/queryAlertingList"); 67 | //不分页查询,列表查询为POST请求方式,条件为project= 68 | StringBuilder stringBuilder = new StringBuilder(); 69 | stringBuilder.append("{") 70 | .append(" pageinfo:{currentPage:1,pageSize:1},") 71 | .append(" query:{") 72 |              .append(" \"project\":[\"project1\",\"project2\"],") //支持in查询 73 |              .append(" }") 74 | .append("}"); 75 | StringEntity stringEntity = new StringEntity(stringBuilder.toString()); 76 | post.setEntity(stringEntity); 77 | HttpResponse response = client.execute(post); 78 | HttpEntity res = response.getEntity(); 79 | System.out.println(EntityUtils.toString(res)); 80 | ``` 81 | 82 | 上面例子,就是查询project为project1的数据,等价于: 83 | 84 | ``` 85 | POST /api/queryAlertingList 86 | { 87 | pageinfo:{currentPage:1,pageSize:1} 88 | query:{ 89 | "project":["project1","project2"] 90 | } 91 | } 92 | ``` 93 | 返回的数据格式为: 94 | 95 | ``` 96 | { 97 | "success":true, 98 | "code":0, 99 | "data":{ 100 | "page":{ 101 | "total":2, 102 | "currentPage":1 103 | }, 104 | "list":[{ 105 | "_id":"FC6EF20EED02AA884745283049CDE2B2", 106 | "startsAt":1511778207, 107 | "endsAt":-62135798400, 108 | "lastNotifyTime":1511778214, 109 | "lastReceiveTime":1511778292, 110 | "times":18, 111 | "status":"firing", 112 | "level":"warning", 113 | "alertId":"FC6EF20EED02AA884745283049CDE2B2-1511778207", 114 | "project":"project2", 115 | "alertname":"mymetric11", 116 | "labels":{ 117 | "instance":"localhost:8080", 118 | "monitor":"codelab-monitor", 119 | "job":"tomcat", 120 | "group":"my1" 121 | } 122 | } 123 | ] 124 | } 125 | } 126 | ``` 127 |
1.1.2.告警详情查询
128 | 根据记录id查询当前告警详情。具体格式如下: 129 |
查询格式 130 | 131 | ``` 132 | GET /api/queryAlertingById/{id}//id为记录id 133 | ``` 134 | 返回数据格式 135 | 136 | ``` 137 | { 138 | success:bool(true/false),//表示是否成功 139 | code:0/1 ,//执行结果编码,目前只有0成功,1失败 140 | total:long,//表示查询到的记录数 141 |      data:{}, //表示返回的记录详情信息 142 |      msg:string //服务器返回的提示信息,一般在访问失败时给出。 143 | } 144 | ``` 145 | 我们用httpClient来模拟GET请求,查询具体某一条告警信息详情,我们查询id为:247D78214DCCD7FE830EC039F2B310C4,代码如下: 146 | 147 | ``` 148 | HttpClient client = HttpClients.createDefault(); 149 | HttpGet get = new HttpGet("http://localhost:8081/api/queryAlertingById/247D78214DCCD7FE830EC039F2B310C4"); 150 | HttpResponse response = client.execute(get); 151 | HttpEntity res = response.getEntity(); 152 | System.out.println(EntityUtils.toString(res)); 153 | ``` 154 | 上面代码等价于: 155 | 156 | ``` 157 | GET /api/queryAlertingById/247D78214DCCD7FE830EC039F2B310C4 158 | ``` 159 | 返回的数据格式: 160 | 161 | ``` 162 | { 163 | "success":true, 164 | "code":0, 165 | "data":{ 166 | "_id":"247D78214DCCD7FE830EC039F2B310C4", 167 | "startsAt":1511778207, 168 | "endsAt":-62135798400, 169 | "lastNotifyTime":1511778350, 170 | "lastReceiveTime":1511778427, 171 | "times":44, 172 | "status":"firing", 173 | "level":"warning", 174 | "alertId":"247D78214DCCD7FE830EC039F2B310C4-1511778207", 175 | "project":"project1", 176 | "alertname":"mymetric11", 177 | "labels":{ 178 | "instance":"localhost:8080", 179 | "monitor":"codelab-monitor", 180 | "job":"tomcat", 181 | "group":"my1" 182 | } 183 | } 184 | } 185 | ``` 186 |
1.1.3.告警数据统计
187 | 查询条件和统计项,统计当前告警信息。具体格式如下: 188 |
查询格式 189 | 190 | ``` 191 | * POST /api/queryAlertingByGroup 192 | * { 193 |     *     query:{//查询条件,遵循mongo的查询格式,如果为空,则查询全部数据 194 |     *         alertname:"testalert", 195 | * "labels.job":"tomcat", 196 | * times:{$gte:"10"} 197 | * }, 198 | * group:["level","project"]//可以按照多个字段,也可以按照一个字段 199 | * } 200 | 201 | ``` 202 | 返回数据格式: 203 | 204 | ``` 205 | *{ 206 | * success:bool(true/false),//表示是否成功 207 | * code:0/1 ,//执行结果编码,目前只有0成功,1失败 208 | * data:{ 209 | * list:[] 210 | * }, //表示返回的记录列表详情 211 | ``` 212 | 以下示例使用httpclient实现,查询project的name为"project1","project2"的记录,并按照"project"分组。代码如下: 213 | 214 | ``` 215 | HttpClient client = HttpClients.createDefault(); 216 | HttpPost post = new HttpPost("http://localhost:8081/api/queryAlertingByGroup"); 217 | //不分页查询,列表查询为POST请求方式,条件为project= 218 | StringBuilder stringBuilder = new StringBuilder(); 219 | stringBuilder.append("{") 220 | .append(" query:{") 221 | .append(" \"project\":[\"project1\",\"project2\"]") 222 | .append(" },") 223 | .append(" group:[\"project\"]") 224 | .append("}"); 225 | StringEntity stringEntity = new StringEntity(stringBuilder.toString()); 226 | post.setEntity(stringEntity); 227 | HttpResponse response = client.execute(post); 228 | HttpEntity res = response.getEntity(); 229 | System.out.println(EntityUtils.toString(res)); 230 | ``` 231 | 以上代码等价于: 232 | 233 | ``` 234 | POST /api/queryAlertingByGroup 235 | { 236 | "query":{"project":["project1","project2"]}, 237 | group:["project"] 238 | } 239 | ``` 240 | 返回数据为: 241 | 242 | ``` 243 | { 244 | "success":true, 245 | "code":0, 246 | "data":{ 247 | "list":[{ 248 | "count":1, 249 | "project":"project1" 250 | },{ 251 | "count":1, 252 | "project":"project2" 253 | } 254 | ] 255 | } 256 | } 257 | ``` 258 |

1.2历史告警查询

259 | 历史告警信息查询,按照统一性原则,与当前告警查询格式一致,只不过数据来源有区别。当前告警数据来源于MongoDB数据库,历史告警数据来源于ElasticSearch。 260 |
1.2.1.历史告警列表查询
261 | 查询格式 262 | 263 | ``` 264 | POST /api/queryHistoryList 265 | { 266 | pageinfo:{//分页信息如果不传,表示不分页 267 |         currentPage:10, //当前页码,从1开始 268 |         pageSize:10 //每页显示多少条,默认10条 269 |     }, 270 | query:{//查询条件,遵循mongo的查询格式 271 | alertname:"testalert", 272 | "labels.job":"tomcat", 273 | times:{$gte:"10"} 274 | } 275 | } 276 | ``` 277 | 返回数据格式 278 | 279 | ``` 280 | { 281 | success:bool(true/false),//表示是否成功 282 | code:0/1 ,//执行结果编码,目前只有0成功,1失败 283 | data:{ 284 | page:{ 285 | total:4, 286 | currentPage:1 287 | }, 288 | list:[] 289 | }, //表示返回的记录列表详情 290 | msg:string //服务器返回的提示信息,一般在访问失败时给出。 291 | } 292 | ``` 293 | 以下示例使用httpClient实现,查询times>10的历史记录,采用分页查询,查第一页数据。代码如下: 294 | 295 | ``` 296 | HttpClient client = HttpClients.createDefault(); 297 | HttpPost post = new HttpPost("http://localhost:8081/api/queryHistoryList"); 298 | //不分页查询,列表查询为POST请求方式,条件为project= 299 | StringBuilder stringBuilder = new StringBuilder(); 300 | stringBuilder.append("{") 301 | .append(" pageinfo:{currentPage:1,pageSize:2},") 302 | .append(" query:{") 303 | .append(" \"project\":[\"project1\",\"project2\"],") 304 | .append(" times:{$gt:10}") 305 | .append(" }") 306 | .append("}"); 307 | StringEntity stringEntity = new StringEntity(stringBuilder.toString()); 308 | post.setEntity(stringEntity); 309 | HttpResponse response = client.execute(post); 310 | HttpEntity res = response.getEntity(); 311 | System.out.println(EntityUtils.toString(res)); 312 | ``` 313 | 以上代码等价于如下请求体: 314 | 315 | ``` 316 | POST /api/queryHistoryList 317 | { 318 | pageinfo:{ 319 |   currentPage:1, 320 | pageSize:1 321 | }, 322 | query:{ 323 | "project":["project1","project2"], 324 |   times:{$gt:10} 325 | } 326 | } 327 | ``` 328 | 返回结果为: 329 | 330 | ``` 331 | { 332 | "success":true, 333 | "code":0, 334 | "data":{ 335 | "page":{ 336 | "total":4, 337 | "currentPage":1 338 | }, 339 | "list":[{ 340 | "startsAt":1511772777, 341 | "endsAt":1511778097, 342 | "lastNotifyTime":1511774254, 343 | "lastReceiveTime":1511778097, 344 | "times":473, 345 | "status":"resolve", 346 | "level":"warning", 347 | "project":"project1", 348 | "alertname":"mymetric11", 349 | "labels":{ 350 | "instance":"localhost:8080", 351 | "monitor":"codelab-monitor", 352 | "job":"tomcat", 353 | "group":"my1" 354 | }, 355 | "_index":"alert-201711", 356 | "_id":"247D78214DCCD7FE830EC039F2B310C4-1511772777" 357 | },{ 358 | "startsAt":1511772777, 359 | "endsAt":1511778097, 360 | "lastNotifyTime":1511774239, 361 | "lastReceiveTime":1511778107, 362 | "times":470, 363 | "status":"resolve", 364 | "level":"warning", 365 | "project":"project2", 366 | "alertname":"mymetric11", 367 | "labels":{ 368 | "instance":"localhost:8080", 369 | "monitor":"codelab-monitor", 370 | "job":"tomcat", 371 | "group":"my1" 372 | }, 373 | "_index":"alert-201711", 374 | "_id":"FC6EF20EED02AA884745283049CDE2B2-1511772777" 375 | } 376 | ] 377 | } 378 | } 379 | ``` 380 |
1.2.2.历史告警详情查询
381 | 查询格式 382 | 383 | ``` 384 | GET /queryAlertingById/{id}//id为记录id 385 | ``` 386 | 返回数据格式 387 | 388 | ``` 389 | { 390 | success:bool(true/false),//表示是否成功 391 | code:0/1 ,//执行结果编码,目前只有0成功,1失败 392 | total:long,//表示查询到的记录数 393 |      data:{}, //表示返回的记录详情信息 394 |      msg:string //服务器返回的提示信息,一般在访问失败时给出。 395 | } 396 | ``` 397 | 我们使用httpclient模拟GET请求,查询指定id的历史数据详情,代码如下: 398 | 399 | ``` 400 | HttpClient client = HttpClients.createDefault(); 401 | HttpGet get = 402 | new HttpGet("http://localhost:8081/api/queryHistoryById/alert-201711/FC6EF20EED02AA884745283049CDE2B2-1511772777"); 403 | HttpResponse response = client.execute(get); 404 | HttpEntity res = response.getEntity(); 405 | System.out.println(EntityUtils.toString(res)); 406 | ``` 407 | 以上代码等价于: 408 | 409 | ``` 410 | GET /api/queryHistoryById/alert-201711/FC6EF20EED02AA884745283049CDE2B2-1511772777 411 | ``` 412 | 返回的数据格式为: 413 | 414 | ``` 415 | { 416 | "success":true, 417 | "code":0,"data":{ 418 | "startsAt":1511772777, 419 | "endsAt":1511778097, 420 | "lastNotifyTime":1511774239, 421 | "lastReceiveTime":1511778107, 422 | "times":470, 423 | "status":"resolve", 424 | "level":"warning", 425 | "project":"project2", 426 | "alertname":"mymetric11", 427 | "labels":{ 428 | "instance":"localhost:8080", 429 | "monitor":"codelab-monitor", 430 | "job":"tomcat", 431 | "group":"my1" 432 | }, 433 | "_index":"alert-201711", 434 | "_id":"FC6EF20EED02AA884745283049CDE2B2-1511772777" 435 | } 436 | } 437 | ``` 438 |
1.2.3.历史告警搜索
439 | 历史告警搜索是指,根据输入的关键字查询与之相关的历史告警数据,返回符合条件的前10条记录。访问的数据格式为: 440 | 441 | ``` 442 | GET /api/searchHistoryList/{searchstr}?currentPage=1&pageSize=10 443 | ``` 444 | 返回的数据格式为: 445 | 446 | ``` 447 | { 448 | success:bool(true/false),//表示是否成功 449 | code:0/1 ,//执行结果编码,目前只有0成功,1失败 450 |      data:{ 451 | page:{ 452 | total:4, 453 | currentPage:1 454 | } , 455 | list:[] 456 | }, //表示返回的记录列表详情 457 | hint:string //服务器返回的提示信息,一般在访问失败时给出。 458 | } 459 | ``` 460 | 我们用HTTPClient来模拟GET请求,查询包含tomcat字符串的记录: 461 | 462 | ``` 463 | HttpClient client = HttpClients.createDefault(); 464 | HttpGet get = new HttpGet("http://localhost:8081/api/searchHistoryList/tomcat"); 465 | HttpResponse response = client.execute(get); 466 | HttpEntity res = response.getEntity(); 467 | System.out.println(EntityUtils.toString(res)); 468 | ``` 469 | 以上代码等价于: 470 | 471 | ``` 472 | //如果不传currentPage和pageSize,系统会默认currentPage=1,pageSize=10 473 | GET /api/searchHistoryList/tomcat?currentPage=1&pageSize=10 474 | ``` 475 | 返回的数据格式为: 476 | 477 | ``` 478 | { 479 | "success":true, 480 | "code":0, 481 | "data":{ 482 | "page":{ 483 | "total":32, 484 | "currentPage":1 485 | }, 486 | ``` 487 |

1.3公共编码查询

488 | 查询告警板中用到的公共编码。 489 |
1.3.1告警级别编码查询
490 | 查询告警板配置的公共编码 491 | 访问格式为: 492 | 493 | ``` 494 | GET /api/queryAlertLevels 495 | ``` 496 | 返回的数据格式为: 497 | 498 | ``` 499 | { 500 | * success:true, 501 | * code:0/1, 502 | * data:{ 503 | * error:"紧急", 504 | * warn:"严重", 505 | * info:"一般", 506 | * debug:"提示" 507 | * } 508 | * } 509 | ``` 510 | 下面我们使用httpClient模拟访问操作如下: 511 | 512 | ``` 513 | HttpClient client = HttpClients.createDefault(); 514 | HttpGet get = new HttpGet("http://localhost:8081/api/queryAlertLevels"); 515 | HttpResponse response = client.execute(get); 516 | HttpEntity res = response.getEntity(); 517 | System.out.println(EntityUtils.toString(res)); 518 | ``` 519 | 返回的数据为: 520 | 521 | ``` 522 | { 523 | "success":true, 524 | "code":0, 525 | "data":{ 526 | "page":{ 527 | "total":44 528 | }, 529 | "list":[{ 530 | "startsAt":1511772777, 531 | "endsAt":1511778097, 532 | "lastNotifyTime":1511774254, 533 | "lastReceiveTime":1511778097, 534 | "times":473, 535 | "status":"resolve", 536 | "level":"warning", 537 | "project":"project1", 538 | "alertname":"mymetric11", 539 | "labels":{ 540 | "instance":"localhost:8080", 541 | "monitor":"codelab-monitor", 542 | "job":"tomcat", 543 | "group":"my1" 544 | }, 545 | "_index":"alert-201711", 546 | "_id":"247D78214DCCD7FE830EC039F2B310C4-1511772777" 547 |   }, 548 | ··· 549 | ] 550 | } 551 | } 552 | ``` 553 |
1.3.2告警分类编码查询
554 | 查询告警板配置的告警分类编码 555 | 访问格式为: 556 | 557 | ``` 558 | GET /api/queryAlertCategories 559 | ``` 560 | 返回数据为: 561 | 562 | ``` 563 | { 564 | "success":true, 565 | "code":0, 566 | "data":{ 567 | "machine":"机器", 568 | "app":"应用" 569 | } 570 | } 571 | ``` 572 |
1.3.3告警类型编码查询
573 | 查询告警板配置的告警类型编码 574 | 访问格式为: 575 | 576 | ``` 577 | GET /api/queryAlertTypes 578 | ``` 579 | 返回数据为: 580 | 581 | ``` 582 | { 583 | "success":true, 584 | "code":0, 585 | "data":{ 586 | "cockpit_schedule_task_exit":"容器实例退出", 587 | "mysql_status_handlers_read_rnd":"mysql索引不合理", 588 | "service_down":"服务不可用", 589 | "node_reboot":"系统重启", 590 | "node_cpu_pct_threshold_exceeded":"节点CPU使用率过高", 591 | "node_mem_threshold_exceeded":"节点剩余内存不足", 592 | "node_mem_pct_threshold_exceeded":"节点内存使用率过高", 593 | "node_fs_pct_threshold_exceeded":"节点文件系统使用率过高", 594 | "node_tcp_conn_toomuch":"节点TCP连接数过高", 595 | "node_disk_io_util_threshold_exceeded":"节点磁盘IO过高", 596 | "redis_service_down":"redis服务不可用", 597 | "redis_mem_pct_threshold_exceeded":"Redis内存使用率过高", 598 | "redis_mem_threshold_exceeded":"Redis内存不足", 599 | "redis_toomany_command_executed":"Redis命令执行频繁", 600 | "redis_dangerous_command_executed":"Redis执行危险命令" 601 | } 602 | } 603 | ``` 604 |
1.3.4告警编码查询
605 | 查询告警板配置的所有告警编码 606 | 访问格式为: 607 | 608 | ``` 609 | GET /api/queryAlertCode 610 | ``` 611 | 返回的数据格式为: 612 | 613 | ``` 614 | { 615 | "success":true, 616 | "code":0, 617 | "data":{ 618 | "alertType":{ 619 | "cockpit_schedule_task_exit":"容器实例退出", 620 | "mysql_status_handlers_read_rnd":"mysql索引不合理", 621 | "service_down":"服务不可用", 622 | "node_reboot":"系统重启", 623 | "node_cpu_pct_threshold_exceeded":"节点CPU使用率过高", 624 | "node_mem_threshold_exceeded":"节点剩余内存不足", 625 | "node_mem_pct_threshold_exceeded":"节点内存使用率过高", 626 | "node_fs_pct_threshold_exceeded":"节点文件系统使用率过高", 627 | "node_tcp_conn_toomuch":"节点TCP连接数过高", 628 | "node_disk_io_util_threshold_exceeded":"节点磁盘IO过高", 629 | "redis_service_down":"redis服务不可用", 630 | "redis_mem_pct_threshold_exceeded":"Redis内存使用率过高", 631 | "redis_mem_threshold_exceeded":"Redis内存不足", 632 | "redis_toomany_command_executed":"Redis命令执行频繁", 633 | "redis_dangerous_command_executed":"Redis执行危险命令" 634 | }, 635 | "alertCategory":{ 636 | "machine":"机器", 637 | "app":"应用" 638 | }, 639 | "alertLevel":{ 640 | "error":"紧急", 641 | "warn":"严重", 642 | "info":"一般", 643 | "debug":"提示" 644 | } 645 | } 646 | } 647 | ``` 648 |

2.系统配置

649 |

2.1配置信息刷新

650 | --------------------------------------------------------------------------------