我必须每隔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")))))))
我哪里错了?
答案 0 :(得分:0)
这里有几个问题。我将尝试解决其中一些问题,然后发布一个最小的工作示例:
传递给smap的第一个fn应该返回一个事件。该事件可以使用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 ...)}))
...)
要计算totalFail
,请记住您需要使用前缀表示法来呼叫>
,因此它必须是(> totalFail 5)
。并且不需要boolean
,因为>
已经返回布尔值。
我会使用streams
或let
作为封闭范围,从顶级def
调用中初始化邮件程序。但它应该可以正常工作。
您应该将最后一个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"
最后where
不应该被streams
括起来,and
句子必须适用于event
,所以必须是:
(where (and (= (:status event) "login failures")
(:total-fail event))
(email "123@gmail.com"))
:subject
的{{1}} fn应作为第二张地图的一部分传递,如mailer
documentation
mailer
上有一个open issue,这使得它有点不可靠:一旦时间窗口到期,它就不会触发但等到新的事件被触发,因此您可能希望使用不同的窗口策略,直到该问题得到解决。
以下是基于您的完整最小工作示例:
fixed-time-window