/** * Handle the {@link AbstractAlertingDefinitionEvent}. * * @param event * the received {@link AbstractAlertingDefinitionEvent} */ private void createdAlertingDefinition(AbstractAlertingDefinitionEvent event) { alertingStates.add(new AlertingState(event.getFirst())); }
/** * This method is called when an active alert is ending. * * @param alertingState * the ending alert */ public void alertEnding(AlertingState alertingState) { if (alertingState == null) { throw new IllegalArgumentException("The given alerting state may not be null."); } if (log.isDebugEnabled()) { log.debug("Alert definition '{}' is ending.", alertingState.getAlertingDefinition().getName()); } alertingState.getAlert().close(System.currentTimeMillis(), AlertClosingReason.ALERT_RESOLVED); for (IAlertAction alertAction : alertActions) { alertAction.onEnding(alertingState); } alertingState.setAlert(null); } }
/** * This method is called when an active alert is still violating its threshold. * * @param alertingState * the ongoing alert * @param violationValue * the value has violated the threshold */ public void alertOngoing(AlertingState alertingState, double violationValue) { if (alertingState == null) { throw new IllegalArgumentException("The given alerting state may not be null."); } if (log.isDebugEnabled()) { log.debug("Alert definition '{}' is ongoing.", alertingState.getAlertingDefinition().getName()); } if (alertingState.getAlertingDefinition().getThresholdType() == ThresholdType.UPPER_THRESHOLD) { alertingState.setExtremeValue(Math.max(violationValue, alertingState.getExtremeValue())); } else { alertingState.setExtremeValue(Math.min(violationValue, alertingState.getExtremeValue())); } for (IAlertAction alertAction : alertActions) { alertAction.onOngoing(alertingState); } }
/** * 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); } }
/** * This method is called when the given threshold has not been violated in the latest period. * * @param alertingState * the threshold which has not been violated */ public void valid(AlertingState alertingState) { if (alertingState == null) { return; } if (log.isDebugEnabled()) { log.debug("||-Threshold '{}' has not been violated in the last interval.", alertingState.getAlertingDefinition().getName()); } if (!alertingState.isAlertActive()) { // threshold is not in a violation series return; } int validCount = alertingState.getValidCount(); if (validCount >= thresholdResetCount) { // alert ended if (log.isDebugEnabled()) { log.debug("||-Ended threshold violation series of '{}'.", alertingState.getAlertingDefinition().getName()); } alertingActionService.alertEnding(alertingState); } else { // alert is waiting for reset alertingState.setValidCount(validCount + 1); } }
@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); }
log.debug("||-Check threshold defined by alerting definition '{}'.", alertingState.getAlertingDefinition().toString()); long lastCheckTime = alertingState.getLastCheckTime(); if (lastCheckTime < 0) { lastCheckTime = currentTime - alertingState.getAlertingDefinition().getTimeRange(TimeUnit.MILLISECONDS); alertingState.setLastCheckTime(lastCheckTime); double extremeValue = resultWrapper.getDouble(0, 1); if (isViolating(alertingState.getAlertingDefinition(), extremeValue)) { stateManager.violation(alertingState, extremeValue); } else { alertingState.setLastCheckTime(currentTime);
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); Alert alert = alertingState.getAlert(); AlertingDefinition definition = alertingState.getAlertingDefinition(); properties.put(Placeholders.THRESHOLD_TYPE, definition.getThresholdType().getName()); properties.put(Placeholders.START_TIME, String.valueOf(dateFormat.format(new Date(alert.getStartTimestamp())))); properties.put(Placeholders.VIOLATION_VALUE, numberFormat.format(alertingState.getExtremeValue())); properties.put(Placeholders.CURRENT_TIME, String.valueOf(new Date(System.currentTimeMillis()))); properties.put(Placeholders.ALERT_ID, alert.getId()); properties.put(Placeholders.EXTREME_VALUE, numberFormat.format(alertingState.getExtremeValue()));
@Test public void alertActiveDataWasValid() { AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.isAlertActive()).thenReturn(true); when(alertingState.getValidCount()).thenReturn(1); lifecycleManager.thresholdResetCount = 2; lifecycleManager.noData(alertingState); verify(alertingState, times(2)).isAlertActive(); verify(alertingState, times(2)).getValidCount(); verify(alertingState).setValidCount(2); verifyNoMoreInteractions(alertingState); verifyZeroInteractions(alertingActionService); }
/** * This method is called when no data is existing for the given threshold in the latest period. * * @param alertingState * the threshold which has been checked */ public void noData(AlertingState alertingState) { if (alertingState == null) { return; } if (log.isDebugEnabled()) { log.debug("||-No data available for alerting definition '{}'. Expecting the same behavior as before.", alertingState.getAlertingDefinition().getName()); } if (!alertingState.isAlertActive() || (alertingState.getValidCount() > 0)) { valid(alertingState); } else { violation(alertingState, Double.NaN); } } }
/** * Returns the name of the given {@link AlertingState}. If the name is empty or null a default * name is returned. * * @param alertingState * the {@link AlertingState} * @return the name of the given {@link AlertingState} */ private String getAlertingName(AlertingState alertingState) { String alertingDefinitionName = alertingState.getAlertingDefinition().getName(); if (StringUtils.isEmpty(alertingDefinitionName)) { return DEFAULT_ALERTING_NAME; } else { return alertingDefinitionName; } }
/** * This method is called if the given threshold (specified by the {@link AlertingDefinition} * contained in the {@link AlertingState}) has been violated in the latest interval. The given * value showed the largest deviation to the threshold. * * @param alertingState * the threshold which has been violated * @param violationValue * the value which violated the threshold */ public void violation(AlertingState alertingState, double violationValue) { if (alertingState == null) { return; } if (alertingState.isAlertActive()) { // alert is ongoing if (log.isDebugEnabled()) { log.debug("||-Violation of threshold '{}' is ongoing.", alertingState.getAlertingDefinition().getName()); } alertingState.setValidCount(0); alertingActionService.alertOngoing(alertingState, violationValue); } else { // alert is new if (log.isDebugEnabled()) { log.debug("||-Threshold violation. Value '{}' violated threshold '{}' and started a new alert.", violationValue, alertingState.getAlertingDefinition().toString()); } alertingActionService.alertStarting(alertingState, violationValue); } }
@Test public void noAlertActiveCountPositive() { AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.isAlertActive()).thenReturn(false); when(alertingState.getValidCount()).thenReturn(10); lifecycleManager.noData(alertingState); verifyZeroInteractions(alertingActionService); verify(alertingState, times(2)).isAlertActive(); verifyNoMoreInteractions(alertingState); }
/** * Handle the {@link AbstractAlertingDefinitionEvent}. * * @param event * the received {@link AbstractAlertingDefinitionEvent} */ private void updatedAlertingDefinition(AbstractAlertingDefinitionEvent event) { Iterator<AlertingState> iterator = alertingStates.iterator(); while (iterator.hasNext()) { AlertingState state = iterator.next(); if (Objects.equals(state.getAlertingDefinition().getId(), event.getFirst().getId())) { state.setAlertingDefinition(event.getFirst()); if (null != state.getAlert()) { state.getAlert().setAlertingDefinition(event.getFirst()); } break; } } } }
/** * {@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); } } } }
/** * Handle the {@link AbstractAlertingDefinitionEvent}. * * @param event * the received {@link AbstractAlertingDefinitionEvent} */ private void deletedAlertingDefinition(AbstractAlertingDefinitionEvent event) { for (AlertingState state : alertingStates) { if (Objects.equals(state.getAlertingDefinition().getId(), event.getFirst().getId())) { if (null != state.getAlert()) { state.getAlert().close(System.currentTimeMillis(), AlertClosingReason.ALERTING_DEFINITION_DELETED); } alertingStates.remove(state); break; } } }
@Test public void alertOngoing() { double violationValue = 100D; AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.isAlertActive()).thenReturn(true); lifecycleManager.violation(alertingState, violationValue); verify(alertingState).isAlertActive(); verify(alertingState).setValidCount(0); verifyNoMoreInteractions(alertingState); verify(alertingActionService).alertOngoing(alertingState, violationValue); verifyNoMoreInteractions(alertingActionService); }
@Test @SuppressWarnings("unchecked") public void alertEnded() { 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); Alert alert = Mockito.mock(Alert.class); AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.getAlert()).thenReturn(alert); long leftBorder = System.currentTimeMillis(); alertingService.alertEnding(alertingState); long rightBorder = System.currentTimeMillis(); ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class); ArgumentCaptor<AlertClosingReason> closingReasonCaptor = ArgumentCaptor.forClass(AlertClosingReason.class); verify(alert).close(timeCaptor.capture(), closingReasonCaptor.capture()); assertThat(timeCaptor.getValue(), greaterThanOrEqualTo(leftBorder)); assertThat(timeCaptor.getValue(), lessThanOrEqualTo(rightBorder)); assertThat(closingReasonCaptor.getValue(), is(AlertClosingReason.ALERT_RESOLVED)); verifyNoMoreInteractions(alert); verify(alertingState).getAlert(); verify(alertingState).setAlert(null); verifyNoMoreInteractions(alertingState); verify(alertAction).onEnding(alertingState); verifyNoMoreInteractions(alertAction); verify(alertActions).iterator(); verifyNoMoreInteractions(alertActions); verifyZeroInteractions(alertRegistry); }
@BeforeMethod public void initAlertingState() throws BusinessException { alertingDefinition = new AlertingDefinition(); alertingDefinition.setMeasurement(MEASUREMENT); alertingDefinition.setField(FIELD); alertingDefinition.putTag(TAG_KEY, TAG_VALUE); alertingDefinition.setTimeRange(TIMERANGE, TimeUnit.MINUTES); alertingState = new AlertingState(alertingDefinition); alertingState.setLastCheckTime(LAST_CHECK_TIME); }
@Test public void noAlertActive() { AlertingState alertingState = Mockito.mock(AlertingState.class); when(alertingState.isAlertActive()).thenReturn(false); lifecycleManager.noData(alertingState); verifyZeroInteractions(alertingActionService); verify(alertingState, times(2)).isAlertActive(); verifyNoMoreInteractions(alertingState); }