【发布时间】:2015-02-07 10:21:30
【问题描述】:
我正在与 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)))))
为了稍微解释一下代码,我收到了这样的事件:
- :service "cpu-0 idle" :metric 58.23
- :service "cpu-1 idle" :metric 98.11
- :service "cpu-2 idle" :metric 12.23
我的目标是计算平均值并在 riemann 中重新注入此事件:
- :service "cpu-average" :metric 56.19
它工作正常,这不是问题。 但是正如您在第 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))))))
【问题讨论】: