From 872e35fcc9883c63145517d42bb2bc927ee7599f Mon Sep 17 00:00:00 2001 From: emeroad Date: Mon, 28 Aug 2023 14:13:38 +0900 Subject: [PATCH] [#10252] Improve Dynamic Registration of AlarmChecker --- .../navercorp/pinpoint/batch/BatchModule.java | 4 +- .../batch/alarm/AlarmCheckerFactory.java | 1 + .../pinpoint/batch/alarm/AlarmProcessor.java | 22 +- .../pinpoint/batch/alarm/CheckerRegistry.java | 183 ++-------- .../AlarmCheckerConfiguration.java | 339 ++++++++++++++++++ .../batch/configuration/AlarmJobModule.java | 45 +++ .../job/applicationContext-alarmJob.xml | 4 - .../batch/alarm/AlarmProcessorTest.java | 17 +- .../batch/alarm/CheckerCategoryTest.java | 20 +- 9 files changed, 456 insertions(+), 179 deletions(-) create mode 100644 batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmCheckerConfiguration.java create mode 100644 batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmJobModule.java diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/BatchModule.java b/batch/src/main/java/com/navercorp/pinpoint/batch/BatchModule.java index e2cab2ba3aa5..237c7ee2ef47 100644 --- a/batch/src/main/java/com/navercorp/pinpoint/batch/BatchModule.java +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/BatchModule.java @@ -18,6 +18,7 @@ package com.navercorp.pinpoint.batch; import com.navercorp.pinpoint.batch.alarm.AlarmSenderConfiguration; +import com.navercorp.pinpoint.batch.configuration.AlarmJobModule; import com.navercorp.pinpoint.common.server.config.RestTemplateConfiguration; import com.navercorp.pinpoint.common.server.config.TypeLoaderConfiguration; import com.navercorp.pinpoint.datasource.MainDataSourceConfiguration; @@ -36,7 +37,6 @@ "classpath:applicationContext-batch-dao-config.xml", "classpath:applicationContext-batch-web-component.xml", - "classpath:job/applicationContext-alarmJob.xml", "classpath:job/applicationContext-agentCountJob.xml", "classpath:job/applicationContext-flinkCheckJob.xml", "classpath:job/applicationContext-cleanupInactiveAgentsJob.xml" @@ -49,6 +49,8 @@ MainDataSourceConfiguration.class, MetaDataSourceConfiguration.class, + AlarmJobModule.class, + WebhookModule.class, WebHbaseModule.class, RestTemplateConfiguration.class, diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmCheckerFactory.java b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmCheckerFactory.java index 27ceef27ceb6..e20096fc6c6c 100644 --- a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmCheckerFactory.java +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmCheckerFactory.java @@ -7,4 +7,5 @@ public interface AlarmCheckerFactory { AlarmChecker createChecker(DataCollector dataCollector, Rule rule); + String getCategory(); } diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessor.java b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessor.java index cf63db88cb58..c7dc844a7a5e 100644 --- a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessor.java +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessor.java @@ -32,7 +32,11 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -52,16 +56,20 @@ public class AlarmProcessor implements ItemProcessor> getAlarmCheckers(Application application) { long now = System.currentTimeMillis(); List agentIds = prepareActiveAgentIds(application, rules, now); - RuleTransformer transformer = new RuleTransformer(application, agentIds, now, dataCollectorFactory); + RuleTransformer transformer = new RuleTransformer(application, agentIds, now, dataCollectorFactory, checkerRegistry); for (Rule rule: rules) { checkers.add(transformer.apply(rule)); } @@ -119,25 +127,25 @@ private List fetchActiveAgents(String applicationId, Range activeRange) private static class RuleTransformer implements Function> { - private static final CheckerRegistry checkerRegistry = CheckerRegistry.newCheckerRegistry(); - private final long timeSlotEndTime; private final Map collectorMap = new HashMap<>(); private final Application application; private final List agentIds; private final DataCollectorFactory dataCollectorFactory; + private final CheckerRegistry checkerRegistry; public RuleTransformer( Application application, List agentIds, long timeSlotEndTime, - DataCollectorFactory dataCollectorFactory - ) { + DataCollectorFactory dataCollectorFactory, + CheckerRegistry checkerRegistry) { this.application = application; this.agentIds = agentIds; this.timeSlotEndTime = timeSlotEndTime; this.dataCollectorFactory = dataCollectorFactory; + this.checkerRegistry = Objects.requireNonNull(checkerRegistry, "checkerRegistry"); } @Override diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java index a11ae0f92491..729c0bc2cbf7 100644 --- a/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java @@ -1,183 +1,52 @@ package com.navercorp.pinpoint.batch.alarm; -import com.navercorp.pinpoint.batch.alarm.checker.AlarmChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ApdexScoreChecker; -import com.navercorp.pinpoint.batch.alarm.checker.DataSourceConnectionUsageRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.DeadlockChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ErrorCountChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ErrorCountToCalleeChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ErrorRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ErrorRateToCalleeChecker; -import com.navercorp.pinpoint.batch.alarm.checker.FileDescriptorChecker; -import com.navercorp.pinpoint.batch.alarm.checker.HeapUsageRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.JvmCpuUsageRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.ResponseCountChecker; -import com.navercorp.pinpoint.batch.alarm.checker.SlowCountChecker; -import com.navercorp.pinpoint.batch.alarm.checker.SlowCountToCalleeChecker; -import com.navercorp.pinpoint.batch.alarm.checker.SlowRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.SlowRateToCalleeChecker; -import com.navercorp.pinpoint.batch.alarm.checker.SystemCpuUsageRateChecker; -import com.navercorp.pinpoint.batch.alarm.checker.TotalCountToCalleeChecker; -import com.navercorp.pinpoint.batch.alarm.collector.AgentEventDataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.AgentStatDataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.DataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.DataSourceDataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.FileDescriptorDataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.MapStatisticsCallerDataCollector; -import com.navercorp.pinpoint.batch.alarm.collector.ResponseTimeDataCollector; - import com.navercorp.pinpoint.web.alarm.CheckerCategory; -import com.navercorp.pinpoint.web.alarm.vo.Rule; import java.util.HashMap; import java.util.Map; +import java.util.Objects; public class CheckerRegistry { - public final Map registry = new HashMap<>(); + public final Map registry; - public static CheckerRegistry newCheckerRegistry() { - CheckerRegistry checkerRegistry = new CheckerRegistry(); - checkerRegistry.setup(); - return checkerRegistry; + private CheckerRegistry(Map registry) { + this.registry = Objects.requireNonNull(registry, "registry"); } - private CheckerRegistry() { + public AlarmCheckerFactory getCheckerFactory(CheckerCategory checkerCategory) { + Objects.requireNonNull(checkerCategory, "checkerCategory"); + return getCheckerFactory(checkerCategory.name()); } - public AlarmCheckerFactory getCheckerFactory(CheckerCategory name) { + public AlarmCheckerFactory getCheckerFactory(String name) { + Objects.requireNonNull(name, "name"); return registry.get(name); } - private void put(CheckerCategory category, AlarmCheckerFactory factory) { - this.registry.put(category, factory); - } - - private void setup() { - put(CheckerCategory.SLOW_COUNT, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new SlowCountChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.SLOW_RATE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new SlowRateChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - - put(CheckerCategory.ERROR_COUNT, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ErrorCountChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.ERROR_RATE, new AlarmCheckerFactory() { - - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ErrorRateChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.TOTAL_COUNT, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ResponseCountChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.APDEX_SCORE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ApdexScoreChecker((ResponseTimeDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.SLOW_COUNT_TO_CALLEE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new SlowCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.SLOW_RATE_TO_CALLEE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new SlowRateToCalleeChecker(dataCollector, rule); - } - }); - - put(CheckerCategory.ERROR_COUNT_TO_CALLEE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ErrorCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); - } - }); - - put(CheckerCategory.ERROR_RATE_TO_CALLEE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new ErrorRateToCalleeChecker(dataCollector, rule); - } - }); - - put(CheckerCategory.TOTAL_COUNT_TO_CALLEE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new TotalCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); - } - }); - put(CheckerCategory.HEAP_USAGE_RATE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new HeapUsageRateChecker((AgentStatDataCollector) dataCollector, rule); - } - }); + public static CheckerRegistry.Builder newBuilder() { + return new Builder(); + } -// put(CheckerCategory.GC_COUNT, new AlarmCheckerFactory() { -// @Override -// public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { -// return new GcCountChecker((AgentStatDataCollector)dataCollector, rule); -// } -// }); + public static class Builder { + private final Map registry = new HashMap<>(); - put(CheckerCategory.JVM_CPU_USAGE_RATE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new JvmCpuUsageRateChecker((AgentStatDataCollector) dataCollector, rule); - } - }); + private Builder() { + } - put(CheckerCategory.SYSTEM_CPU_USAGE_RATE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new SystemCpuUsageRateChecker((AgentStatDataCollector) dataCollector, rule); + public void addChecker(AlarmCheckerFactory factory) { + Objects.requireNonNull(factory, "factory"); + AlarmCheckerFactory duplicate = this.registry.put(factory.getCategory(), factory); + if (duplicate != null) { + throw new IllegalStateException("Duplicate AlarmCheckerFactory " + factory + " - " + duplicate); } - }); + } - put(CheckerCategory.DATASOURCE_CONNECTION_USAGE_RATE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new DataSourceConnectionUsageRateChecker((DataSourceDataCollector) dataCollector, rule); - } - }); - put(CheckerCategory.DEADLOCK_OCCURRENCE, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new DeadlockChecker((AgentEventDataCollector) dataCollector, rule); - } - }); - put(CheckerCategory.FILE_DESCRIPTOR_COUNT, new AlarmCheckerFactory() { - @Override - public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { - return new FileDescriptorChecker((FileDescriptorDataCollector) dataCollector, rule); - } - }); + public CheckerRegistry build() { + Map copy = new HashMap<>(registry); + return new CheckerRegistry(copy); + } } } diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmCheckerConfiguration.java b/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmCheckerConfiguration.java new file mode 100644 index 000000000000..e7de4e22eecc --- /dev/null +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmCheckerConfiguration.java @@ -0,0 +1,339 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.navercorp.pinpoint.batch.configuration; + +import com.navercorp.pinpoint.batch.alarm.AlarmCheckerFactory; +import com.navercorp.pinpoint.batch.alarm.CheckerRegistry; +import com.navercorp.pinpoint.batch.alarm.checker.AlarmChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ApdexScoreChecker; +import com.navercorp.pinpoint.batch.alarm.checker.DataSourceConnectionUsageRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.DeadlockChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ErrorCountChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ErrorCountToCalleeChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ErrorRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ErrorRateToCalleeChecker; +import com.navercorp.pinpoint.batch.alarm.checker.FileDescriptorChecker; +import com.navercorp.pinpoint.batch.alarm.checker.HeapUsageRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.JvmCpuUsageRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.ResponseCountChecker; +import com.navercorp.pinpoint.batch.alarm.checker.SlowCountChecker; +import com.navercorp.pinpoint.batch.alarm.checker.SlowCountToCalleeChecker; +import com.navercorp.pinpoint.batch.alarm.checker.SlowRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.SlowRateToCalleeChecker; +import com.navercorp.pinpoint.batch.alarm.checker.SystemCpuUsageRateChecker; +import com.navercorp.pinpoint.batch.alarm.checker.TotalCountToCalleeChecker; +import com.navercorp.pinpoint.batch.alarm.collector.AgentEventDataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.AgentStatDataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.DataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.DataSourceDataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.FileDescriptorDataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.MapStatisticsCallerDataCollector; +import com.navercorp.pinpoint.batch.alarm.collector.ResponseTimeDataCollector; +import com.navercorp.pinpoint.web.alarm.CheckerCategory; +import com.navercorp.pinpoint.web.alarm.vo.Rule; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +@Configuration +public class AlarmCheckerConfiguration { + + private final Logger logger = LogManager.getLogger(AlarmCheckerConfiguration.class); + + + public AlarmCheckerConfiguration() { + logger.info("Install AlarmCheckerConfiguration"); + } + + @Bean + public CheckerRegistry checkerRegistry(List factories) { + CheckerRegistry.Builder builder = CheckerRegistry.newBuilder(); + for (AlarmCheckerFactory factory : factories) { + logger.info("Add AlarmCheckerFactory Category:{} {}", factory.getCategory(), factory.getClass().getSimpleName()); + builder.addChecker(factory); + } + return builder.build(); + } + + + @Bean + public AlarmCheckerFactory slowCountChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new SlowCountChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.SLOW_COUNT.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory slowRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new SlowRateChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.SLOW_RATE.name(); + } + }; + } + + + @Bean + public AlarmCheckerFactory errorCountChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ErrorCountChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.ERROR_COUNT.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory errorRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ErrorRateChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.ERROR_RATE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory totalCountChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ResponseCountChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.TOTAL_COUNT.name(); + } + }; + } + + + @Bean + public AlarmCheckerFactory apdexScoreChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ApdexScoreChecker((ResponseTimeDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.APDEX_SCORE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory slowCountToCalleeChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new SlowCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.SLOW_COUNT_TO_CALLEE.name(); + } + }; + } + + + @Bean + public AlarmCheckerFactory slowRateToCalleeChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new SlowRateToCalleeChecker(dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.SLOW_RATE_TO_CALLEE.name(); + } + }; + } + + + @Bean + public AlarmCheckerFactory errorCountToCalleeChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ErrorCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.ERROR_COUNT_TO_CALLEE.name(); + } + }; + } + + + @Bean + public AlarmCheckerFactory errorRateToCalleeChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new ErrorRateToCalleeChecker(dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.ERROR_RATE_TO_CALLEE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory totalCountToCalleeChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new TotalCountToCalleeChecker((MapStatisticsCallerDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.TOTAL_COUNT_TO_CALLEE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory heapUsageRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new HeapUsageRateChecker((AgentStatDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.HEAP_USAGE_RATE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory jvmCpuUsageRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new JvmCpuUsageRateChecker((AgentStatDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.JVM_CPU_USAGE_RATE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory systemCpuUsageRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new SystemCpuUsageRateChecker((AgentStatDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.SYSTEM_CPU_USAGE_RATE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory dataSourceConnectionUsageRateChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new DataSourceConnectionUsageRateChecker((DataSourceDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.DATASOURCE_CONNECTION_USAGE_RATE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory deadlockChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new DeadlockChecker((AgentEventDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.DEADLOCK_OCCURRENCE.name(); + } + }; + } + + @Bean + public AlarmCheckerFactory fileDescriptorChecker() { + return new AlarmCheckerFactory() { + @Override + public AlarmChecker createChecker(DataCollector dataCollector, Rule rule) { + return new FileDescriptorChecker((FileDescriptorDataCollector) dataCollector, rule); + } + + @Override + public String getCategory() { + return CheckerCategory.FILE_DESCRIPTOR_COUNT.name(); + } + }; + } + + + +} diff --git a/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmJobModule.java b/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmJobModule.java new file mode 100644 index 000000000000..b91b0c697903 --- /dev/null +++ b/batch/src/main/java/com/navercorp/pinpoint/batch/configuration/AlarmJobModule.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.navercorp.pinpoint.batch.configuration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportResource; + + +@ImportResource({ + "classpath:job/applicationContext-alarmJob.xml", +}) +@ComponentScan({ + "com.navercorp.pinpoint.batch.alarm" +}) +@Import({ + AlarmCheckerConfiguration.class +}) +@Configuration +public class AlarmJobModule { + + private final Logger logger = LogManager.getLogger(AlarmJobModule.class); + + public AlarmJobModule() { + logger.info("Install AlarmJobModule"); + } +} diff --git a/batch/src/main/resources/job/applicationContext-alarmJob.xml b/batch/src/main/resources/job/applicationContext-alarmJob.xml index 4af570278801..c9b15b2c04ee 100644 --- a/batch/src/main/resources/job/applicationContext-alarmJob.xml +++ b/batch/src/main/resources/job/applicationContext-alarmJob.xml @@ -2,16 +2,12 @@ - - diff --git a/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessorTest.java b/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessorTest.java index 90dfd493cc84..e149a533895d 100644 --- a/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessorTest.java +++ b/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/AlarmProcessorTest.java @@ -2,6 +2,7 @@ import com.navercorp.pinpoint.batch.alarm.collector.AgentStatDataCollector; import com.navercorp.pinpoint.batch.alarm.vo.AppAlarmChecker; +import com.navercorp.pinpoint.batch.configuration.AlarmCheckerConfiguration; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.web.alarm.CheckerCategory; import com.navercorp.pinpoint.web.alarm.vo.Rule; @@ -13,6 +14,9 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; import java.util.Map; @@ -29,10 +33,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@ExtendWith(MockitoExtension.class) +@ExtendWith({MockitoExtension.class, SpringExtension.class}) +@ContextConfiguration( + classes = AlarmCheckerConfiguration.class +) public class AlarmProcessorTest { - @Mock private DataCollectorFactory dataCollectorFactory; @@ -48,6 +54,9 @@ public class AlarmProcessorTest { @Mock private AgentStatDataCollector agentStatDataCollector; + @Autowired + CheckerRegistry checkerRegistry; + private static final String SERVICE_NAME = "local_tomcat"; private static final List agentIds = List.of("agent0", "agent1", "agent2"); @@ -58,7 +67,7 @@ public void shouldSkipIfNoRule() { when(alarmService.selectRuleByApplicationId(SERVICE_NAME)).thenReturn(List.of()); - AlarmProcessor proc = new AlarmProcessor(dataCollectorFactory, alarmService, applicationIndexDao, agentInfoService); + AlarmProcessor proc = new AlarmProcessor(dataCollectorFactory, alarmService, applicationIndexDao, agentInfoService, checkerRegistry); AppAlarmChecker checker = proc.process(app); assertNull(checker, "should be skipped"); @@ -82,7 +91,7 @@ public void test() { when(agentStatDataCollector.getHeapUsageRate()).thenReturn(heapUsageRate); // Executions - AlarmProcessor processor = new AlarmProcessor(dataCollectorFactory, alarmService, applicationIndexDao, agentInfoService); + AlarmProcessor processor = new AlarmProcessor(dataCollectorFactory, alarmService, applicationIndexDao, agentInfoService, checkerRegistry); AppAlarmChecker appChecker = processor.process(application); // Validations diff --git a/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/CheckerCategoryTest.java b/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/CheckerCategoryTest.java index feff717b895b..952b3653e417 100644 --- a/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/CheckerCategoryTest.java +++ b/batch/src/test/java/com/navercorp/pinpoint/batch/alarm/CheckerCategoryTest.java @@ -17,22 +17,31 @@ package com.navercorp.pinpoint.batch.alarm; import com.navercorp.pinpoint.batch.alarm.checker.SlowCountChecker; +import com.navercorp.pinpoint.batch.configuration.AlarmCheckerConfiguration; import com.navercorp.pinpoint.web.alarm.CheckerCategory; import com.navercorp.pinpoint.web.alarm.vo.Rule; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; +@ExtendWith(SpringExtension.class) +@ContextConfiguration( + classes = AlarmCheckerConfiguration.class +) public class CheckerCategoryTest { - private final CheckerRegistry registry = CheckerRegistry.newCheckerRegistry(); - @Test - public void createCheckerTest() { + @Autowired + CheckerRegistry registry; - CheckerCategory slowCount = CheckerCategory.getValue("slow count"); - AlarmCheckerFactory checkerFactory = registry.getCheckerFactory(slowCount); + @Test + public void configuration() { + AlarmCheckerFactory checkerFactory = registry.getCheckerFactory(CheckerCategory.SLOW_COUNT); Rule rule = new Rule(null, "", CheckerCategory.SLOW_COUNT.getName(), 75, "testGroup", false, false, false, ""); SlowCountChecker checker = (SlowCountChecker) checkerFactory.createChecker(null, rule); @@ -47,5 +56,4 @@ public void createCheckerTest() { assertNotNull(checker2); assertEquals(63, (int) checker2.getRule().getThreshold()); } - }