如何重构这个clojure / riemann代码

时间:2015-02-06 21:11:33

标签: clojure riemann

我正在使用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

我的目标是计算平均值并在黎曼重新注入此事件:

  • :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))))))

1 个答案:

答案 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以明确接受您想要的那些。我没有在这里设置测试,所以如果代码被破坏请编辑: - )