-
Notifications
You must be signed in to change notification settings - Fork 47
/
slack.clj
102 lines (79 loc) · 3.13 KB
/
slack.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(ns com.brunobonacci.mulog.publishers.slack
(:require [com.brunobonacci.mulog.publisher :as p]
[com.brunobonacci.mulog.buffer :as rb]
[com.brunobonacci.mulog.utils :as ut]
[com.brunobonacci.mulog.common.json :as json]
[clj-http.client :as http]
[clj-time.format :as tf]
[clj-time.coerce :as tc]
[clojure.string :as str]))
(defn- unix-ms-to-iso8601
[unix-ms]
(let [iso-8601-fmt (tf/formatters :date-time)]
(->> unix-ms
(tc/from-long)
(tf/unparse iso-8601-fmt))))
(defn- default-render-message
"Timestamp and event name with the log content in a code block"
[event]
(let [timestamp (unix-ms-to-iso8601 (:mulog/timestamp event))
event-name (:mulog/event-name event)]
(str timestamp " - " event-name
\newline
"```"
\newline
(ut/pprint-event-str event)
"```")))
(defn- send-slack-message
[webhook-url message publish-delay]
(http/post
webhook-url
{:content-type "application/json"
:accept :json
:socket-timeout publish-delay
:connection-timeout publish-delay
:body (json/to-json {:text message})}))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; ----==| S L A C K |==---- ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(deftype SlackPublisher [config buffer]
com.brunobonacci.mulog.publisher.PPublisher
(agent-buffer [_]
buffer)
(publish-delay [_]
(:publish-delay config))
(publish [_ buffer]
(let [items (take (:max-items config) (rb/items buffer))
last-offset (-> items last first)
transform (:transform config)
;; items are pairs [offset <item>]
transformed-events (transform (map second items))
render-message (:render-message config)
rendered-messages (map render-message transformed-events)]
;; if the are rendered events, then send them
(when (seq rendered-messages)
(send-slack-message (:webhook-url config)
(str/join "\n" rendered-messages)
(:publish-delay config)))
;; discard the events we processed
(if (seq items)
(rb/dequeue buffer last-offset)
buffer))))
(def ^:const default-config
{;; Should look something like "https://hooks.slack.com/services/..."
;; See https://api.slack.com/messaging/webhooks
;; :webhook-url (REQUIRED)
;; Function applied to the list of records retrieved from the queue
;; :transform (REQUIRED)
:max-items 20 ;; By default, only send 20 events per slack message
:publish-delay 3000 ;; 3s
;; Function applied to each event for rendering the slack message to be sent
:render-message default-render-message})
(defn slack-publisher
[{:keys [webhook-url transform] :as config}]
{:pre [webhook-url transform]}
(SlackPublisher.
(merge default-config config)
(rb/agent-buffer 100)))