Clojure:riemann.streams$smap$stream IllegalArgumentException:键必须是整数
我有一个clojure代码(riemann),如果满足某些条件,可以发送电子邮件。在将事件传递给riemann服务器时,我遇到了一些问题 黎曼编码Clojure:riemann.streams$smap$stream IllegalArgumentException:键必须是整数,clojure,riemann,Clojure,Riemann,我有一个clojure代码(riemann),如果满足某些条件,可以发送电子邮件。在将事件传递给riemann服务器时,我遇到了一些问题 黎曼编码 (let [email (mailer {"......"})] (streams (where (service "system_log") (by :RefNo (smap (fn [events] (let [count-of-failures (cou
(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)))))
riemann服务器中的O/p
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)
更新2:
我只是简单地将smap更改为sreduce。我应该如何更新,因为我是这方面的新手,我对按照你的建议修改代码有点困惑
(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)))))
更新3:
我使用coalesce
更新了我的代码,smap
有它的子项。现在它没有显示任何错误,但电子邮件没有被触发。我的失败计数为0
。我猜计数功能不起作用
(let [email (mailer {"......"})]
(streams
(where (service "system_log")
(by :RefNo
(coalesce
(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))))
在我的帽子顶上,by
接受向量而不是符号:
(by [:Refno] ...
作为补充说明,我建议使用REPL(例如),这样您可以在测试REPL中的函数时逐步构建流处理。这对我很有效
更新:我也不确定你是否应该在smap
中嵌套where,因为你分配了“Failure”,但是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
)。首先在hashmap上调用,
会生成一个向量,然后尝试使用符号作为键进行关联,会出现错误,因为向量只支持整数
您不能像在Clojure中不使用常规的map
那样以这种方式计算失败,因为您需要过去的事件
以下是我认为可能与您的smap示例兼容的内容
要么:
使用coalesce和smap作为其子级;我认为smap将收到一份活动列表,就像您最初想要的一样。我没有试过,但没有理由不起作用
您可以通过发送带有1小时TTL的事件并查询流中的索引来控制所需的时间窗口(假设每小时最多2次失败)。下面是一个完整的示例:
除此之外,我认为:Status
应该是小写的。我希望它能有所帮助。我已经更新了我的代码(通过[:Refno]
),但是我仍然得到了同样的错误。我需要替换smap
。通过将smap
替换为sreduce
我需要保持(通过[:Refno]
原样还是需要删除[]
从它开始。它似乎与单个符号一起工作,因此可能函数会处理这种情况。我使用了向量,因为这是我理解引用的方式。但是如果它工作,它就工作。我已经替换了sreduce
,而不是smap
。我尝试删除了`[[,并且尝试了不删除
[]`对于这两种情况,我都会遇到这个错误。“传递的参数(2)的数目错误”
。如果不查看代码,我就无法找到确切的解决方案。我猜您传递给sreduce
的函数的签名不正确。它应该包含两个参数,就像reduce
一样。