Количество событий в определенный промежуток времени в Римане

Я должен проверить количество отсчетов, появляющихся в событии на каждом интервале каждые 30 секунд. Если число больше 5 означает, мне нужно вызвать электронное письмо.

Я использую приведенный ниже код, но электронная почта не сработала.

(let [userindex1 (default :ttl 300 (update-index (index)))]
  (streams
    prn
    userindex1))

(streams
  (where (and (service "system_log")
              (not (expired? event)))

    ; fixed-time-window sends a vector of events out every 30 seconds
    (fixed-time-window
      30
      ; smap passes those events into a function
      (smap
        (fn [events]
          ;Calculate the no of count of events for failure
          (let [numberofFailure (count (filter #(="IE" (:description %)) events))]

            {:status "login failures"
             :metric  numberofFailure 
             :totalFail (boolean(numberofFailure > 5))}

            (streams
              prn
              numberofFailure))))


      ;check if the variable status is true if condition satisfied then trigger an email
      (let [email (mailer {:host "smtp.gmail.com"
                           :port 25
                           :user "aaaaa"
                           :pass "bbbbb"
                           :auth "true"
                           :subject (fn [events]
                                      (clojure.string/join ", "
                                                           (map :service events)))
                           :from "abc@gmail.com"})]
        (streams
          (where (and (:status "login failures")
                      (:totalFail true))
            (email "123@gmail.com")))))))

Куда я иду не так?

1 ответ

Здесь есть пара вопросов. Я постараюсь обратиться к некоторым из них, а затем выложу минимальный рабочий пример:

  1. Первый fn, переданный в smap, должен вернуть событие. Это событие может быть создано с event или assocв одно из полученных событий. В вашем примере создается простая карта (которая не будет работать, это не правильное событие), но это даже потеряно, потому что тогда streams называется (который AFAIK следует вызывать только на верхнем уровне). Так что вместо:

    (smap
      (fn [events]
        (let [numberofFailure ...]
          {:status "login failures"
           :metric  numberofFailure 
           :totalFail (boolean ...)}
          (streams
            prn
            numberofFailure)))
      ...)
    

    Вы должны сделать что-то вроде:

    (smap
      (fn [events]
        (let [numberofFailure ...]
          (event {:status "login failures"
                  :metric  numberofFailure 
                  :totalFail (boolean ...)}))
      ...)
    
  2. Вычислять totalFail помните, что вам нужно использовать префиксную нотацию для вызова >так должно быть (> totalFail 5), А также boolean не нужен, так как > уже вернет логическое значение.

  3. Я бы инициализировал почтовик из верхнего уровня streams вызов, как охватывающая область видимости, используя let или с def, Но это должно работать как есть.

  4. Вы должны пройти последний where как дочерний поток для smap, поэтому он должен быть вторым аргументом для smap. Давайте вспомним документы Smap:

    (smap f & children)
    Streaming map. Calls children with (f event), whenever (f event) is non-nil.
    Prefer this to (adjust f) and (combine f). Example:
    
    (smap :metric prn) ; prints the metric of each event.
    (smap #(assoc % :state "ok") index) ; Indexes each event with state "ok"
    
  5. Последний where не должен быть закрыт streamsи and Приговор должен работать на eventтак и должно быть:

    (where (and (= (:status event) "login failures")
                (:total-fail event))
      (email "123@gmail.com"))
    
  6. :subject FN для mailer должны быть переданы как часть второй карты, как описано в mailer документация

  7. Есть открытый вопрос по fixed-time-window что делает его немного ненадежным: он не срабатывает, как только истекает временное окно, а ждет, пока не сработает новое событие, так что вы можете использовать другую стратегию управления окнами, пока это не будет исправлено.

Вот полный минимальный рабочий пример, основанный на вашем:

(let [email (mailer {:host "localhost"
                     :port 1025
                     :from "abc@gmail.com"})]
  (streams
    (where (and (service "system_log")
                (not (expired? event)))
      (fixed-time-window
        5
        (smap
          (fn [events]
            (let [count-of-failures (count (filter #(= "IE" (:description %)) events))]
              (event
                {:status "login failures"
                 :metric  count-of-failures 
                 :total-fail (>= count-of-failures 2)})))
          (where (and (= (:status event) "login failures")
                      (:total-fail event))
            (email "hello123@gmail.com")))))))
Другие вопросы по тегам