liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

incz.fnl (1717B)


      1 (local { : base64 } (require :anoia))
      2 (local ll (require :lualinux))
      3 
      4 (fn index [str indexname]
      5   (string.format "{\"index\":{\"_index\":%q}}\n%s" indexname str))
      6 
      7 (local crlf "\r\n")
      8 
      9 (fn chunk [str]
     10   (let [len (# str)]
     11     (string.format "%x%s%s%s" len crlf str crlf)))
     12 
     13 (fn http-header [host path auth]
     14   (string.format
     15    "POST %s HTTP/1.1\r
     16 Host: %s\
     17 Authorization: basic %s
     18 Transfer-Encoding: chunked\r
     19 \r
     20 "
     21    path host
     22    (let [b64 (base64 :url)] (b64:encode auth))))
     23 
     24 (fn format-timestamp [timestamp]
     25   ;; I can't make zincsearch understand any epoch-based timestamp
     26   ;; formats, so we are formatting dates as iso-8601 and damn the leap
     27   ;; seconds :-(
     28   (let [secs (- (tonumber (string.sub timestamp 1 16) 16)
     29                 (lshift 1 62))
     30         nano (tonumber (string.sub timestamp 16 24) 16)
     31         ts (+ (* secs 1000) (math.floor (/ nano 1000000)))]
     32     (.. (os.date "!%FT%T" secs) "." nano "Z")))
     33 
     34 (fn process-line [indexname hostname line]
     35   (let [(timestamp service msg) (string.match line "@(%x+) (%g+) (.+)$")]
     36     (->
     37      (string.format
     38       "{%q:%q,%q:%q,%q:%q,%q:%q}\n"
     39       "@timestamp" (format-timestamp timestamp)
     40       :service service
     41       :message msg
     42       :host hostname)
     43      (index indexname)
     44      chunk)))
     45 
     46 (fn run []
     47   (let [myhostname (with-open [h (io.popen "hostname" :r)] (h:read "l"))
     48         (filename loghost credentials indexname) (table.unpack arg)]
     49 
     50     (with-open [infile (assert (io.open filename :r))]
     51       (ll.write 1 (http-header loghost "/api/_bulk" credentials))
     52       (while (case (infile:read "l")
     53                line (ll.write 1 (process-line indexname myhostname line))))
     54       (ll.write 1 (chunk "")))
     55     (io.stderr:write (ll.read 0))))
     56 
     57 
     58 { : run }