private registerAlarms()

in src/package-sources/npmjs.ts [347:431]


  private registerAlarms(scope: Construct, follower: NpmJsFollower, stager: StageAndNotify, monitoring: IMonitoring, schedule: Rule) {
    const failureAlarm = follower.metricErrors().createAlarm(scope, 'NpmJs/Follower/Failures', {
      alarmName: `${scope.node.path}/NpmJs/Follower/Failures`,
      alarmDescription: [
        'The NpmJs follower function failed!',
        '',
        `RunBook: ${RUNBOOK_URL}`,
        '',
        `Direct link to Lambda function: ${lambdaFunctionUrl(follower)}`,
      ].join('\n'),
      comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
      evaluationPeriods: 3,
      threshold: 1,
      treatMissingData: TreatMissingData.MISSING,
    });
    monitoring.addHighSeverityAlarm('NpmJs/Follower Failures', failureAlarm);

    const notRunningAlarm = follower.metricInvocations({ period: FOLLOWER_RUN_RATE })
      .createAlarm(scope, 'NpmJs/Follower/NotRunning', {
        alarmName: `${scope.node.path}/NpmJs/Follower/NotRunning`,
        alarmDescription: [
          'The NpmJs follower function is not running!',
          '',
          `RunBook: ${RUNBOOK_URL}`,
          '',
          `Direct link to Lambda function: ${lambdaFunctionUrl(follower)}`,
        ].join('\n'),
        comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD,
        evaluationPeriods: 2,
        threshold: 1,
        treatMissingData: TreatMissingData.BREACHING,
      });
    monitoring.addHighSeverityAlarm('NpmJs/Follower Not Running', notRunningAlarm);

    // The period for this alarm needs to match the scheduling interval of the
    // follower, otherwise the metric will be too sparse to properly detect
    // problems.
    const noChangeAlarm = this.metricChangeCount({ period: FOLLOWER_RUN_RATE })
      .createAlarm(scope, 'NpmJs/Follower/NoChanges', {
        alarmName: `${scope.node.path}/NpmJs/Follower/NoChanges`,
        alarmDescription: [
          'The NpmJs follower function is no discovering any changes from CouchDB!',
          '',
          `RunBook: ${RUNBOOK_URL}`,
          '',
          `Direct link to Lambda function: ${lambdaFunctionUrl(follower)}`,
        ].join('\n'),
        comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD,
        evaluationPeriods: 2,
        threshold: 1,
        // If the metric is not emitted, it can be assumed to be zero.
        treatMissingData: TreatMissingData.BREACHING,
      });
    monitoring.addLowSeverityAlarm('Np npmjs.com changes discovered', noChangeAlarm);

    const dlqNotEmptyAlarm = new MathExpression({
      expression: 'mVisible + mHidden',
      usingMetrics: {
        mVisible: stager.deadLetterQueue!.metricApproximateNumberOfMessagesVisible({ period: Duration.minutes(1) }),
        mHidden: stager.deadLetterQueue!.metricApproximateNumberOfMessagesNotVisible({ period: Duration.minutes(1) }),
      },
    }).createAlarm(scope, `${scope.node.path}/NpmJs/Stager/DLQNotEmpty`, {
      alarmName: `${scope.node.path}/NpmJs/Stager/DLQNotEmpty`,
      alarmDescription: [
        'The NpmJS package stager is failing - its dead letter queue is not empty',
        '',
        `Link to the lambda function: ${lambdaFunctionUrl(stager)}`,
        `Link to the dead letter queue: ${sqsQueueUrl(stager.deadLetterQueue!)}`,
        '',
        `Runbook: ${RUNBOOK_URL}`,
      ].join('/n'),
      comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
      evaluationPeriods: 1,
      threshold: 1,
      treatMissingData: TreatMissingData.NOT_BREACHING,
    });
    monitoring.addLowSeverityAlarm('NpmJs/Stager DLQ Not Empty', dlqNotEmptyAlarm);

    // Finally - the "not running" alarm depends on the schedule (it won't run until the schedule
    // exists!), and the schedule depends on the failure alarm existing (we don't want it to run
    // before we can know it is failing). This means the returned `IDependable` effectively ensures
    // all alarms have been provisionned already! Isn't it nice!
    notRunningAlarm.node.addDependency(schedule);
    schedule.node.addDependency(failureAlarm);
  }