Riemann - dynamically build a stream from the map

I have the following function which gets a map with service name and threshold. It checks to see if the service has crossed a certain threshold, and then calls multiple downstream children in the event.

(defn tc
  [s & children]
   (where
     (and (service (:service_name s)) (not (expired? event)))
       (by [:host :service]
         (where (> metric (:threshold s)
           (with :state "critical" 
             (apply sdo children)))))))

      

I would like to construct a stream dynamically using a vector of maps:

(def services [{:service "cpu/usage" :threshold 90}
               {:service "memory/usage" :threshold 90}])

      

When I try to run it on a thread, I get the following warning:

(streams
  (doseq [s services] (tc s prn)))

WARN [2015-01-05 14:27:07,187] Thread-15 - riemann.core - instrumentation service caught
java.lang.NullPointerException
  at riemann.core$stream_BANG_$fn__11140.invoke(core.clj:19)
  at riemann.core$stream_BANG_.invoke(core.clj:18)
  at riemann.core$instrumentation_service$measure__11149.invoke(core.clj:57)
  at riemann.service.ThreadService$thread_service_runner__8782$fn__8783.invoke(service.clj:66)
  at riemann.service.ThreadService$thread_service_runner__8782.invoke(service.clj:65)
  at clojure.lang.AFn.run(AFn.java:22)
  at java.lang.Thread.run(Thread.java:701)

      

This works if I run the threads function inside the dose. This works and gives the following output:

(doseq [s services]
  (streams (tc s prn)))

#riemann.codec.Event{:host "testhost", :service "memory/usage", :state "critical", :description nil, :metric 91.0, :tags nil, :time 1420460856, :ttl 60.0}

      

+3


source to share


1 answer


Seems like it will explode if your events don't have all required fields, here's a sample from a similar project where I create an event from a sequence of events (shorthand). This is not exactly what you are doing, m generates events in the same way:

{:service (:service (first events))
 :metric (->> events count)
 :host "All-counts"
 :state "OK"
 :time (:time (last events))
 :ttl default-interval}

      



I got NPE on purpose when I was running out of time. If you can't inherit its form somewhere, just do it (use now

for example) without a reasonable value here, expiration won't work and you will run out of RAM

0


source







All Articles