Search code examples
clojureclosuresriemann

Adding A Custom Date Field To Riemann Events


I am using the default config setup for Riemann :

; -*- mode: clojure; -*-
; vim: filetype=clojure

(logging/init {:file "riemann.log"})

; Listen on the local interface over TCP (5555), UDP (5555), and websockets
; (5556)
(let [host "127.0.0.1"]
  (tcp-server {:host host})
  (udp-server {:host host})
  (ws-server  {:host host}))

; Expire old events from the index every 5 seconds.
(periodically-expire 5)

(let [index (index)]
  ; Inbound events will be passed to these streams:
  (streams
    (default :ttl 60
      ; Index all events immediately.
      index

      ; Log expired events.
      (expired
        (fn [event] (info "expired" event))))))

(streams
        prn)

it is outputting events as such (host name removed) :

#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server tcp 127.0.0.1:5555 in latency 0.99", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server tcp 127.0.0.1:5555 in latency 0.999", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in rate", :state "ok", :description nil, :metric 0.0, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in latency 0.0", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in latency 0.5", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in latency 0.95", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in latency 0.99", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}
#riemann.codec.Event{:host "xxxxxxxx", :service "riemann server udp 127.0.0.1:5555 in latency 0.999", :state "ok", :description nil, :metric nil, :tags nil, :time 722617016251/500, :ttl 20}

The time field is coming out as a UTC timestamp, using the above config how can I how can I add an extra field to these events called date that displays the date in a dd-mm-yyyy hh:mm:ss format? For example :

19-10-2015 05:00:00

I have a few functions which appear to do time conversions but I'm not sure how to implement them in the config :

(defn logstash-v1-format
  "Convert an event to a Logstash V1 format compatible document"
  [event]
  (merge (dissoc event :time :attributes)
         (:attributes event)
         {"@timestamp" (unix-to-iso8601 (:time event))
          "@version" "1"
          }))

(defn time-at
  "Returns the Date of a unix epoch time."
  [unix-time]
  (java.util.Date. (long (* 1000 unix-time))))

(defn unix-to-iso8601
  "Transforms unix time to iso8601 string"
  [unix]
  (clj-time.format/unparse (clj-time.format/formatters :date-time)
                           (clj-time.coerce/from-long (long (* 1000 unix)))))

Solution

  • The answer is to enclose index in :

    (adjust #(assoc % :timestamp (.format (java.text.SimpleDateFormat. "yyyy-MM-dd'T'hh:mm:ss'Z'") (java.util.Date.)) ) prn index)
    

    It ends up being :

    ; -*- mode: clojure; -*-
    ; vim: filetype=clojure
    
    (logging/init {:file "riemann.log"})
    
    ; Listen on the local interface over TCP (5555), UDP (5555), and websockets
    ; (5556)
    (let [host "127.0.0.1"]
      (tcp-server {:host host})
      (udp-server {:host host})
      (ws-server  {:host host}))
    
    ; Expire old events from the index every 5 seconds.
    (periodically-expire 5)
    
    (let [index (index)]
      ; Inbound events will be passed to these streams:
      (streams
        (default :ttl 60
          ; Index all events immediately.
          (adjust #(assoc % :timestamp (.format (java.text.SimpleDateFormat. "yyyy-MM-dd'T'hh:mm:ss'Z'") (java.util.Date.)) ) prn index)
    
          ; Log expired events.
          (expired
            (fn [event] (info "expired" event))))))