我有一个clojure代码(riemann),如果满足某些条件,就会发送电子邮件。在将事件传递给riemann服务器时,我遇到了一些问题。
黎曼代码
Ivan
123456
Student added
Georgi
,▒( 654321
Student added
Teacher added
Teacher added
Teacher added
Teacher added
E 0▒( 2673448E 0▒( 2673448
riemann服务器的O / P
(let [email (mailer {"......"})]
(streams
(where (service "system_log")
(by :RefNo
(smap
(fn [events]
(let [count-of-failures (count (filter #(= "Failed" (:Status %)) events))]
(assoc (first events)
:status "Failure"
:metric count-of-failures
:total-fail (>= count-of-failures 2))))
(where (and (= (:status event) "Failure")
(:total-fail event))
(email "XXXXX@gmail.com"))prn)))))
更新2:
我只是将smap改为sreduce。我应该如何更新,因为我是新手,我对根据你的建议更改代码感到困惑
WARN [2015-11-18 05:24:49,596] defaultEventExecutorGroup-2-2 - riemann.streams - riemann.streams$smap$stream__3695@7addde9e threw
java.lang.IllegalArgumentException: Key must be integer
at clojure.lang.APersistentVector.assoc(APersistentVector.java:335)
at clojure.lang.APersistentVector.assoc(APersistentVector.java:18)
更新3:
我已使用(let [email (mailer {"......"})]
(streams
(where (service "system_log")
(by :RefNo
(sreduce
(fn [events]
(let [count-of-failures (count (filter #(= "Failed" (:Status %)) events))]
(assoc (first events)
:status "Failure"
:metric count-of-failures
:total-fail (>= count-of-failures 2))))
(where (and (= (:status event) "Failure")
(:total-fail event))
(email "XXXXX@gmail.com"))prn)))))
更新了我的代码,而coalesce
有其子代。现在它没有显示任何错误,但电子邮件没有被触发。我的smap
为count-of-failures
。我猜0
无效。
count function
答案 0 :(得分:1)
在我的帽子顶部,by
接受一个不是符号的向量:
(by [:Refno] ...
作为旁注,我建议使用REPL(例如https://github.com/aphyr/riemann/wiki/playing-with-the-REPL),这样您就可以在REPL中测试函数的同时逐步构建流处理。它对我很有用。
更新:我也不确定你是否应该在smap
内嵌套,因为你指的是“失败”,但where
并行运行到smap
所以除非我遗漏了什么,否则我认为它不会看到它。
更新2:我通过与Riemann相连的REPL运行它:
(require '[riemann.streams :refer :all])
(def f (stream
(where (service "system_log")
(by :RefNo
(smap
(fn [events]
(let [count-of-failures (count (filter #(= "Failed" (:Status %)) events))]
(prn events)
(assoc (first events)
:status "Failure"
:metric count-of-failures
:total-fail (>= count-of-failures 2))))
#_(where (and (= (:status event) "Failure")
(:total-fail event)))
prn)))))
(f {:RefNo 4444 :service "system_log" :status "Failed"})
它会产生与您相同的错误。之所以出现错误,是因为您假设传递给smap
的函数收到了一系列事件。它不会,它会收到一个事件(参见那里的prn
)。在哈希映射上调用first
会生成一个向量,然后尝试使用符号作为键的assoc
会给出错误,因为向量仅支持整数。
你无法以这种方式计算失败,就像你不会在Clojure中使用常规map
那样,因为你需要过去的事件。
以下是我认为可能与您的示例兼容的内容。
或者:
使用coalesce http://riemann.io/api/riemann.streams.html#var-coalesce和smap作为其孩子;我认为smap会收到一份你最初想要的活动清单。我没有尝试过,但没有理由不这样做。
您可以通过发送1小时TTL的事件并查询流中的索引来控制所需的时间窗口(假设每小时最多2次失败)。以下是一个完整的示例:http://riemann.io/howto.html#query-the-index-from-within-a-stream
除此之外,我认为:Status
应该是小写的。我希望它有所帮助。