在黎曼的某个时间间隔内的事件计数

时间:2015-07-07 12:57:39

标签: clojure riemann

我必须每隔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 个答案:

答案 0 :(得分:0)

这里有几个问题。我将尝试解决其中一些问题,然后发布一个最小的工作示例:

  1. 传递给smap的第一个fn应该返回一个事件。该事件可以使用eventassoc创建一个已接收的事件。在您的示例中,创建了一个普通地图(这不起作用,它不是一个正确的事件),但是甚至丢失了因为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. 我会使用streamslet作为封闭范围,从顶级def调用中初始化邮件程序。但它应该可以正常工作。

  4. 您应该将最后一个where作为子流传递给smap,因此它必须是smap的第二个参数。让我们回忆一下smap docs

    (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的{​​{1}} fn应作为第二张地图的一部分传递,如mailer documentation

  7. 中所述
  8. mailer上有一个open issue,这使得它有点不可靠:一旦时间窗口到期,它就不会触发但等到新的事件被触发,因此您可能希望使用不同的窗口策略,直到该问题得到解决。

  9. 以下是基于您的完整最小工作示例:

    fixed-time-window