如何重构这个 clojure / riemann 代码
How to refactor this clojure / riemann code
我是 discovering/learning Clojure with Riemann,我编写了以下代码来汇总每个主机的 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)))))
为了稍微解释一下代码,我收到了这样的事件:
- :服务 "cpu-0 idle":指标 58.23
- :服务 "cpu-1 idle":公制 98.11
- :服务 "cpu-2 idle":指标 12.23
我的目标是计算平均值并将此事件重新注入黎曼:
- :服务 "cpu-average":指标 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))))))
我可能会通过首先提取名称并创建新的服务名称,然后使用服务名称和主机来拆分事件流,从而将函数稍微翻个底朝天。
像这样:
(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
来明确接受你想要的。我这里没有设置来测试这个所以如果代码损坏请编辑:-)
我是 discovering/learning Clojure with Riemann,我编写了以下代码来汇总每个主机的 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)))))
为了稍微解释一下代码,我收到了这样的事件:
- :服务 "cpu-0 idle":指标 58.23
- :服务 "cpu-1 idle":公制 98.11
- :服务 "cpu-2 idle":指标 12.23
我的目标是计算平均值并将此事件重新注入黎曼:
- :服务 "cpu-average":指标 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))))))
我可能会通过首先提取名称并创建新的服务名称,然后使用服务名称和主机来拆分事件流,从而将函数稍微翻个底朝天。
像这样:
(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
来明确接受你想要的。我这里没有设置来测试这个所以如果代码损坏请编辑:-)