Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#10252] Improve Dynamic Registration of AlarmChecker #10253

Merged
merged 1 commit into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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"
Expand All @@ -49,6 +49,8 @@
MainDataSourceConfiguration.class,
MetaDataSourceConfiguration.class,

AlarmJobModule.class,

WebhookModule.class,
WebHbaseModule.class,
RestTemplateConfiguration.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
public interface AlarmCheckerFactory {
AlarmChecker<?> createChecker(DataCollector dataCollector, Rule rule);

String getCategory();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -52,16 +56,20 @@ public class AlarmProcessor implements ItemProcessor<Application, AppAlarmChecke

private final AgentInfoService agentInfoService;

private final CheckerRegistry checkerRegistry;

public AlarmProcessor(
DataCollectorFactory dataCollectorFactory,
AlarmService alarmService,
ApplicationIndexDao applicationIndexDao,
AgentInfoService agentInfoService
AgentInfoService agentInfoService,
CheckerRegistry checkerRegistry
) {
this.dataCollectorFactory = Objects.requireNonNull(dataCollectorFactory, "dataCollectorFactory");
this.alarmService = Objects.requireNonNull(alarmService, "alarmService");
this.applicationIndexDao = Objects.requireNonNull(applicationIndexDao, "applicationIndexDao");
this.agentInfoService = Objects.requireNonNull(agentInfoService, "agentInfoService");
this.checkerRegistry = Objects.requireNonNull(checkerRegistry, "checkerRegistry");
}

public AppAlarmChecker process(@Nonnull Application application) {
Expand All @@ -83,7 +91,7 @@ private List<AlarmChecker<?>> getAlarmCheckers(Application application) {
long now = System.currentTimeMillis();
List<String> 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));
}
Expand Down Expand Up @@ -119,25 +127,25 @@ private List<String> fetchActiveAgents(String applicationId, Range activeRange)

private static class RuleTransformer implements Function<Rule, AlarmChecker<?>> {

private static final CheckerRegistry checkerRegistry = CheckerRegistry.newCheckerRegistry();

private final long timeSlotEndTime;
private final Map<DataCollectorCategory, DataCollector> collectorMap = new HashMap<>();

private final Application application;
private final List<String> agentIds;
private final DataCollectorFactory dataCollectorFactory;
private final CheckerRegistry checkerRegistry;

public RuleTransformer(
Application application,
List<String> 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<CheckerCategory, AlarmCheckerFactory> registry = new HashMap<>();
public final Map<String, AlarmCheckerFactory> registry;

public static CheckerRegistry newCheckerRegistry() {
CheckerRegistry checkerRegistry = new CheckerRegistry();
checkerRegistry.setup();
return checkerRegistry;
private CheckerRegistry(Map<String, AlarmCheckerFactory> 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<String, AlarmCheckerFactory> 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);

Check warning on line 42 in batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java

View check run for this annotation

Codecov / codecov/patch

batch/src/main/java/com/navercorp/pinpoint/batch/alarm/CheckerRegistry.java#L42

Added line #L42 was not covered by tests
}
});
}

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<String, AlarmCheckerFactory> copy = new HashMap<>(registry);
return new CheckerRegistry(copy);
}

}
}
Loading