package com.linkedin.thirdeye.anomaly; import com.linkedin.thirdeye.anomaly.alert.v2.AlertJobSchedulerV2; import com.linkedin.thirdeye.anomaly.grouping.GroupingJobScheduler; import com.linkedin.thirdeye.anomalydetection.alertFilterAutotune.AlertFilterAutotuneFactory; import com.linkedin.thirdeye.dashboard.resources.AnomalyFunctionResource; import com.linkedin.thirdeye.detector.email.filter.AlertFilterFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import com.linkedin.thirdeye.anomaly.alert.AlertJobResource; import com.linkedin.thirdeye.anomaly.alert.AlertJobScheduler; import com.linkedin.thirdeye.anomaly.detection.DetectionJobResource; import com.linkedin.thirdeye.anomaly.detection.DetectionJobScheduler; import com.linkedin.thirdeye.anomaly.merge.AnomalyMergeExecutor; import com.linkedin.thirdeye.anomaly.monitor.MonitorJobScheduler; import com.linkedin.thirdeye.anomaly.task.TaskDriver; import com.linkedin.thirdeye.autoload.pinot.metrics.AutoLoadPinotMetricsService; import com.linkedin.thirdeye.client.ThirdEyeCacheRegistry; import com.linkedin.thirdeye.common.BaseThirdEyeApplication; import com.linkedin.thirdeye.completeness.checker.DataCompletenessScheduler; import com.linkedin.thirdeye.detector.function.AnomalyFunctionFactory; import io.dropwizard.assets.AssetsBundle; import io.dropwizard.lifecycle.Managed; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; public class ThirdEyeAnomalyApplication extends BaseThirdEyeApplication<ThirdEyeAnomalyConfiguration> { private DetectionJobScheduler detectionJobScheduler = null; private TaskDriver taskDriver = null; private MonitorJobScheduler monitorJobScheduler = null; private AlertJobScheduler alertJobScheduler = null; private AlertJobSchedulerV2 alertJobSchedulerV2; private AnomalyFunctionFactory anomalyFunctionFactory = null; private AnomalyMergeExecutor anomalyMergeExecutor = null; private AutoLoadPinotMetricsService autoLoadPinotMetricsService = null; private DataCompletenessScheduler dataCompletenessScheduler = null; private AlertFilterFactory alertFilterFactory = null; private AlertFilterAutotuneFactory alertFilterAutotuneFactory = null; private GroupingJobScheduler groupingJobScheduler = null; public static void main(final String[] args) throws Exception { List<String> argList = new ArrayList<>(Arrays.asList(args)); if (argList.size() == 1) { argList.add(0, "server"); } int lastIndex = argList.size() - 1; String thirdEyeConfigDir = argList.get(lastIndex); System.setProperty("dw.rootDir", thirdEyeConfigDir); String detectorApplicationConfigFile = thirdEyeConfigDir + "/" + "detector.yml"; argList.set(lastIndex, detectorApplicationConfigFile); // replace config dir with the // actual config file new ThirdEyeAnomalyApplication().run(argList.toArray(new String[argList.size()])); } @Override public String getName() { return "Thirdeye Controller"; } @Override public void initialize(final Bootstrap<ThirdEyeAnomalyConfiguration> bootstrap) { bootstrap.addBundle(new AssetsBundle("/assets/", "/", "index.html")); } @Override public void run(final ThirdEyeAnomalyConfiguration config, final Environment environment) throws Exception { LOG.info("Starting ThirdeyeAnomalyApplication : Scheduler {} Worker {}", config.isScheduler(), config.isWorker()); super.initDAOs(); ThirdEyeCacheRegistry.initializeCaches(config); environment.lifecycle().manage(new Managed() { @Override public void start() throws Exception { if (config.isWorker()) { anomalyFunctionFactory = new AnomalyFunctionFactory(config.getFunctionConfigPath()); alertFilterFactory = new AlertFilterFactory(config.getAlertFilterConfigPath()); taskDriver = new TaskDriver(config, anomalyFunctionFactory, alertFilterFactory); taskDriver.start(); } if (config.isScheduler()) { detectionJobScheduler = new DetectionJobScheduler(); alertFilterFactory = new AlertFilterFactory(config.getAlertFilterConfigPath()); alertFilterAutotuneFactory = new AlertFilterAutotuneFactory(config.getFilterAutotuneConfigPath()); detectionJobScheduler.start(); environment.jersey().register(new DetectionJobResource(detectionJobScheduler, alertFilterFactory, alertFilterAutotuneFactory)); environment.jersey().register(new AnomalyFunctionResource(config.getFunctionConfigPath())); } if (config.isMonitor()) { monitorJobScheduler = new MonitorJobScheduler(config.getMonitorConfiguration()); monitorJobScheduler.start(); } if (config.isAlert()) { alertJobScheduler = new AlertJobScheduler(); alertJobScheduler.start(); // start alert scheduler v2 alertJobSchedulerV2 = new AlertJobSchedulerV2(); alertJobSchedulerV2.start(); environment.jersey() .register(new AlertJobResource(alertJobScheduler, emailConfigurationDAO)); } if (config.isMerger()) { // anomalyFunctionFactory might have initiated if current machine is also a worker if (anomalyFunctionFactory == null) { anomalyFunctionFactory = new AnomalyFunctionFactory(config.getFunctionConfigPath()); } ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); anomalyMergeExecutor = new AnomalyMergeExecutor(executorService, anomalyFunctionFactory); anomalyMergeExecutor.start(); } if (config.isAutoload()) { autoLoadPinotMetricsService = new AutoLoadPinotMetricsService(config); autoLoadPinotMetricsService.start(); } if (config.isDataCompleteness()) { dataCompletenessScheduler = new DataCompletenessScheduler(); dataCompletenessScheduler.start(); } if (config.isGrouper()) { groupingJobScheduler = new GroupingJobScheduler(); groupingJobScheduler.start(); } } @Override public void stop() throws Exception { if (config.isWorker()) { taskDriver.shutdown(); } if (config.isScheduler()) { detectionJobScheduler.shutdown(); } if (config.isMonitor()) { monitorJobScheduler.shutdown(); } if (config.isAlert()) { alertJobScheduler.shutdown(); alertJobSchedulerV2.shutdown(); } if (config.isMerger()) { anomalyMergeExecutor.stop(); } if (config.isAutoload()) { autoLoadPinotMetricsService.shutdown(); } if (config.isDataCompleteness()) { dataCompletenessScheduler.shutdown(); } if (config.isGrouper()) { groupingJobScheduler.shutdown(); } } }); } }