/** * {@inheritDoc} */ @Override public void run() { if (log.isDebugEnabled()) { log.debug("|-Checking alert definitions..."); } long currentTime = System.currentTimeMillis(); for (AlertingState alertingState : alertingStates) { try { long nextCheckTime = alertingState.getLastCheckTime() + alertingState.getAlertingDefinition().getTimeRange(TimeUnit.MILLISECONDS); if (nextCheckTime <= currentTime) { thresholdChecker.checkThreshold(alertingState); } } catch (Exception e) { if (log.isErrorEnabled()) { log.error("Unexpected exception occured.", e); } } } }
/** * Creates a query that retrieves the max / min value from a metric to check whether it violates * a threshold. * * @param alertingState * {@link AlertingState} defining the alerting rule and state to check the threshold * for. * @param currentTime * The current system time. * @return The influxDB query as String. */ public static String buildThresholdCheckForAlertingStateQuery(AlertingState alertingState, long currentTime) { AlertingDefinition definition = alertingState.getAlertingDefinition(); String aggregationFunction; if (definition.getThresholdType() == ThresholdType.UPPER_THRESHOLD) { aggregationFunction = "MAX"; } else { aggregationFunction = "MIN"; } StringBuilder builder = new StringBuilder(); builder.append("SELECT " + aggregationFunction + "(\"").append(definition.getField()).append("\") FROM \"").append(definition.getMeasurement()).append("\" WHERE "); for (Entry<String, String> entry : definition.getTags().entrySet()) { builder.append('"').append(entry.getKey()); builder.append("\" = '").append(entry.getValue()).append("' AND "); } long leftCheckIntervalBorder = alertingState.getLastCheckTime() - definition.getTimeRange(TimeUnit.MILLISECONDS); builder.append("time <= ").append(currentTime).append("ms AND time > ").append(leftCheckIntervalBorder).append("ms"); return builder.toString(); }
@Test @SuppressWarnings("unchecked") public void upperThreshold() { IAlertAction alertAction = Mockito.mock(IAlertAction.class); Iterator<IAlertAction> iterator = Mockito.mock(Iterator.class); when(iterator.hasNext()).thenReturn(true, false); when(iterator.next()).thenReturn(alertAction); when(alertActions.iterator()).thenReturn(iterator); AlertingDefinition alertingDefinition = Mockito.mock(AlertingDefinition.class); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.UPPER_THRESHOLD); AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(1234L); when(alertingState.getExtremeValue()).thenReturn(5D); alertingService.alertOngoing(alertingState, 3D); verify(alertingState).setExtremeValue(5D); verify(alertingState).getExtremeValue(); verify(alertingState).getAlertingDefinition(); verifyNoMoreInteractions(alertingState); verify(alertAction).onOngoing(alertingState); verifyNoMoreInteractions(alertAction); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verifyZeroInteractions(alertRegistry); }
@Test @SuppressWarnings("unchecked") public void startAlert() { IAlertAction alertAction = Mockito.mock(IAlertAction.class); Iterator<IAlertAction> iterator = Mockito.mock(Iterator.class); when(iterator.hasNext()).thenReturn(true, false); when(iterator.next()).thenReturn(alertAction); when(alertActions.iterator()).thenReturn(iterator); AlertingState alertingState = Mockito.mock(AlertingState.class); AlertingDefinition alertingDefinition = Mockito.mock(AlertingDefinition.class); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(1234L); alertingService.alertStarting(alertingState, 1.0D); ArgumentCaptor<Alert> captor = ArgumentCaptor.forClass(Alert.class); verify(alertRegistry).registerAlert(captor.capture()); verifyNoMoreInteractions(alertRegistry); assertThat(captor.getValue().getAlertingDefinition(), is(alertingDefinition)); assertThat(captor.getValue().getStartTimestamp(), is(1234L)); verify(alertAction).onStarting(alertingState); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verify(alertingState).getAlertingDefinition(); verify(alertingState).getLastCheckTime(); verify(alertingState).setAlert(any(Alert.class)); verify(alertingState).setExtremeValue(1.0D); verifyNoMoreInteractions(alertingState); }
@Test @SuppressWarnings("unchecked") public void upperThresholdNewExtremeValue() { IAlertAction alertAction = Mockito.mock(IAlertAction.class); Iterator<IAlertAction> iterator = Mockito.mock(Iterator.class); when(iterator.hasNext()).thenReturn(true, false); when(iterator.next()).thenReturn(alertAction); when(alertActions.iterator()).thenReturn(iterator); AlertingDefinition alertingDefinition = Mockito.mock(AlertingDefinition.class); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.UPPER_THRESHOLD); AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(1234L); when(alertingState.getExtremeValue()).thenReturn(5D); alertingService.alertOngoing(alertingState, 10D); verify(alertingState).setExtremeValue(10D); verify(alertingState).getExtremeValue(); verify(alertingState).getAlertingDefinition(); verifyNoMoreInteractions(alertingState); verify(alertAction).onOngoing(alertingState); verifyNoMoreInteractions(alertAction); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verifyZeroInteractions(alertRegistry); }
@Test @SuppressWarnings("unchecked") public void lowerThreshold() { IAlertAction alertAction = Mockito.mock(IAlertAction.class); Iterator<IAlertAction> iterator = Mockito.mock(Iterator.class); when(iterator.hasNext()).thenReturn(true, false); when(iterator.next()).thenReturn(alertAction); when(alertActions.iterator()).thenReturn(iterator); AlertingDefinition alertingDefinition = Mockito.mock(AlertingDefinition.class); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.LOWER_THRESHOLD); AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(1234L); when(alertingState.getExtremeValue()).thenReturn(5D); alertingService.alertOngoing(alertingState, 10D); verify(alertingState).setExtremeValue(5D); verify(alertingState).getExtremeValue(); verify(alertingState).getAlertingDefinition(); verifyNoMoreInteractions(alertingState); verify(alertAction).onOngoing(alertingState); verifyNoMoreInteractions(alertAction); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verifyZeroInteractions(alertRegistry); }
/** * This method is called when a new alert is started. * * @param alertingState * the started alert * @param violationValue * the value has violated the threshold */ public void alertStarting(AlertingState alertingState, double violationValue) { if (alertingState == null) { throw new IllegalArgumentException("The given alerting state may not be null."); } Alert alert = new Alert(alertingState.getAlertingDefinition(), alertingState.getLastCheckTime()); alertRegistry.registerAlert(alert); alertingState.setAlert(alert); alertingState.setExtremeValue(violationValue); for (IAlertAction alertAction : alertActions) { alertAction.onStarting(alertingState); } }
@Test @SuppressWarnings("unchecked") public void lowerThresholdNewExtremeValue() { IAlertAction alertAction = Mockito.mock(IAlertAction.class); Iterator<IAlertAction> iterator = Mockito.mock(Iterator.class); when(iterator.hasNext()).thenReturn(true, false); when(iterator.next()).thenReturn(alertAction); when(alertActions.iterator()).thenReturn(iterator); AlertingDefinition alertingDefinition = Mockito.mock(AlertingDefinition.class); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.LOWER_THRESHOLD); AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(1234L); when(alertingState.getExtremeValue()).thenReturn(5D); alertingService.alertOngoing(alertingState, 3D); verify(alertingState).setExtremeValue(3D); verify(alertingState).getExtremeValue(); verify(alertingState).getAlertingDefinition(); verifyNoMoreInteractions(alertingState); verify(alertAction).onOngoing(alertingState); verifyNoMoreInteractions(alertAction); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verifyZeroInteractions(alertRegistry); }
@Test public void neverChecked() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(new QueryResult()); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingState.getLastCheckTime()).thenReturn(-1L); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> currentTimeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState, times(2)).setLastCheckTime(currentTimeCaptor.capture()); verify(alertingState, times(2)).getAlertingDefinition(); assertThat(currentTimeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(alertingDefinition, times(2)).getTimeRange(TimeUnit.MILLISECONDS); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).noData(alertingState); verify(alertingDefinition).getThresholdType(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition, times(2)).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
@Test public void noData() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(new QueryResult()); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState).setLastCheckTime(timeCaptor.capture()); verify(alertingState).getAlertingDefinition(); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).noData(alertingState); verify(alertingDefinition).getThresholdType(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
@Test public void noViolationLowerThreshold() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(queryResult); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.LOWER_THRESHOLD); when(alertingDefinition.getThreshold()).thenReturn(5D); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState).setLastCheckTime(timeCaptor.capture()); verify(alertingState, times(2)).getAlertingDefinition(); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).valid(alertingState); verify(alertingDefinition, times(2)).getThresholdType(); verify(alertingDefinition).getThreshold(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
@Test public void violationLowerThreshold() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(queryResult); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.LOWER_THRESHOLD); when(alertingDefinition.getThreshold()).thenReturn(15D); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState).setLastCheckTime(timeCaptor.capture()); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState, times(2)).getAlertingDefinition(); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).violation(alertingState, 10D); verify(alertingDefinition, times(2)).getThresholdType(); verify(alertingDefinition).getThreshold(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
@Test public void noViolationUpperThreshold() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(queryResult); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.UPPER_THRESHOLD); when(alertingDefinition.getThreshold()).thenReturn(15D); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState).setLastCheckTime(timeCaptor.capture()); verify(alertingState, times(2)).getAlertingDefinition(); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).valid(alertingState); verify(alertingDefinition, times(2)).getThresholdType(); verify(alertingDefinition).getThreshold(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
@Test public void violationUpperThreshold() throws BusinessException, Exception { long time = System.currentTimeMillis(); when(influxDao.isConnected()).thenReturn(true); when(influxDao.query(any(String.class))).thenReturn(queryResult); when(alertingState.getAlertingDefinition()).thenReturn(alertingDefinition); when(alertingDefinition.getThresholdType()).thenReturn(ThresholdType.UPPER_THRESHOLD); when(alertingDefinition.getThreshold()).thenReturn(5D); thresholdChecker.checkThreshold(alertingState); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); verify(alertingState, times(2)).getLastCheckTime(); verify(alertingState).setLastCheckTime(timeCaptor.capture()); verify(alertingState, times(2)).getAlertingDefinition(); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(time)); verify(influxDao).query(any(String.class)); verify(influxDao).isConnected(); verify(stateManager).violation(alertingState, 10D); verify(alertingDefinition, times(2)).getThresholdType(); verify(alertingDefinition).getThreshold(); verify(alertingDefinition).getField(); verify(alertingDefinition).getTags(); verify(alertingDefinition).getMeasurement(); verify(alertingDefinition).getTimeRange(TimeUnit.MILLISECONDS); verifyNoMoreInteractions(influxDao, alertingState, stateManager, alertingDefinition); }
long lastCheckTime = alertingState.getLastCheckTime(); if (lastCheckTime < 0) { lastCheckTime = currentTime - alertingState.getAlertingDefinition().getTimeRange(TimeUnit.MILLISECONDS);