我正在使用Riemann发现/学习Clojure,我编写了以下代码来汇总每个主机的CPU指标:
(streams
(by [:host]
smap (aggregate-cpu-metrics "user" folds/mean)
smap (aggregate-cpu-metrics "nice" folds/mean)
smap (aggregate-cpu-metrics "system" folds/mean)
smap (aggregate-cpu-metrics "idle" folds/mean)
smap (aggregate-cpu-metrics "wait" folds/mean)
smap (aggregate-cpu-metrics "interrupt" folds/mean)
smap (aggregate-cpu-metrics "softirq" folds/mean)
smap (aggregate-cpu-metrics "steal" folds/mean)))
(defn aggregate-cpu-metrics
[name, aggr]
(where (service (re-pattern (str "cpu-[0-9]+ " name)))
(coalesce 10
(smap aggr
(with :service (str "cpu-average " name) reinject)))))
为了解释一下代码,我收到了类似的事件:
我的目标是计算平均值并在黎曼重新注入此事件:
它正在发挥作用,这不是问题所在。 但是正如你在第3到第10行中看到的那样,这里有很多重复的代码。我正在寻找一种重构这段代码的方法,但我被卡住了。
我想用我的指标名称定义一个向量:
(def cpu-metrics ["user", "nice", "system", "idle", "interrupt", "softirq", "steal"])
...并用它来调用 smap(aggregate-cpu-metrics ...
但我不知道该怎么做。我已经尝试过 map 或 doseq ,但没有成功。
你会怎么做?
(更新/解决方案):
在阅读了Arthur的回答后,这是我的重构版本。
(streams
(where
(service #"^cpu-[0-9]+ ")
(adjust
[:service #(clojure.string/replace % #"^cpu-[0-9]+" "cpu-average")]
(by [:host :service]
(fixed-time-window 10 (smap folds/mean reinject))))))
答案 0 :(得分:1)
我可能首先提取名称并创建新服务名称,然后使用服务名称和主机来拆分事件流,从而将功能内部化。
这样的事情:
(streams
(where (service #"cpu-[0-9]+ ")
(adjust [:service (fn [service]
(str "cpu-average "
(second (clojure.string/split service #"cpu-[0-9]+ "))))]
(by [:host :service] ... )))
这会产生副作用,即允许报告的任何cpu服务显示在统计信息中,而不会更改监控代码。如果您不想这样,可以添加另一个where
以明确接受您想要的那些。我没有在这里设置测试,所以如果代码被破坏请编辑: - )