Search code examples
clojureriemann

Comparing event and adding new field in Riemann


I am facing one scenario. Let assume I have 3 events A, B and C which I am passing to Riemann.

Event A have following fields :ExamNo 3890 :ExamResult Pass :Rank 8
Event B have following fields :ExamNo 3890 :ExamResult Pass :Rank 5
Event C have following fields :ExamNo 3890 :ExamResult Fail :Rank 0

I need to compare the events based on ExamNo and whenver there is a change in ExamResult I need to add a new fields to event {:Eligible, :Grade}. I wrote the code to compare the events but the new field was not getting added to the event.

(let [examindex (default :ttl 300 (update-index (index)))]
  (streams
    prn
    examindex))

(streams
  (where (service "Result")
    (smap
          (fn [events]
        (by[:ExamNo]
        (changed :ExamResult))
        (event
            {    :Eligible :Eligible-Status
                 :Grade     :GradeValue
            }
         )))))

Since I am newbie to Riemann . I couldn't figure out the issue.


Solution

  • I never used Riemann, but since you want to modify existing events, you should probably use with, as explained here, instead of event. By the way, just to be clear, events are immutables, so you are in fact creating new values based on older ones.

    You should try to indent your code: notice that the (event ...) form is not enclosed under (changed ...), althought it probably should.

    Tests

    I use only this streams declaration, in the configuration file:

    (streams
     (where (service "Result")
        (by :ExamNo
          (changed :ExamResult
            (with {:Eligible :Eligible-Status
                   :Grade    :GradeValue  }
              prn)))))))
    

    I removed smap and added a prn statement. In order to test this, I connected to an nREPL client and fired events from there. First, let's define a TCP client.

    (def tcp-client (riemann.client/tcp-client))
    

    Then, send a first event, with no :ExamResult value:

    (riemann.client/send-event tcp-client
      (riemann.common/event {:service "Result" :ExamNo "4"}))
    

    Nothing is printed by the server. Then, I send a new event for the same ExamNo with a result:

    (riemann.client/send-event tcp-client
      (riemann.common/event {:service "Result" :ExamNo "4" :ExamResult "result"}))
    

    Since the result changed for exam number "4" since last event, we build a new event. The running Riemann server outputs the following in its standard output:

    #riemann.codec.Event{:host "localhost", :service "Result", :state nil, 
    :description nil, :metric nil, :tags nil, :time 1437035833,
    :ttl nil, :Grade :GradeValue, :Eligible :Eligible-Status, 
    :ExamNo "4", :ExamResult "x"}
    

    Reinject

    If, instead of prn, I use reinject, and if I restore the previously omitted lines:

    (let [examindex (default :ttl 300 (update-index (index)))]
      (streams
        prn
        examindex))
    

    ... then all events are shown, in particular the new events being reinjected. This behaviour might be the one you expected to have in the first place.