-
-
Notifications
You must be signed in to change notification settings - Fork 171
/
sentry.clj
80 lines (65 loc) · 2.53 KB
/
sentry.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
(ns taoensso.timbre.appenders.community.sentry
"Sentry appender.
Requires <https://github.com/sethtrain/raven-clj>."
{:author "Samuel Otter (@samuelotter)"}
(:require
[taoensso.encore :as enc]
[taoensso.timbre :as timbre]
[raven-clj.core :as raven]
[raven-clj.interfaces :as interfaces]))
(def ^:private timbre->sentry-levels
{:trace "debug"
:debug "debug"
:info "info"
:warn "warning"
:error "error"
:fatal "fatal"
:report "info"})
(defn sentry-appender
"Returns a raven-clj Sentry appender.
Requires the DSN (e.g. \"https://<key>:<secret>@sentry.io/<project>\")
to be passed in, see Sentry documentation for details.
Timbre's `*context*` will be passed to Sentry as `:extra` data. When logging
an exception with ex-data attached, it will be stringified and added under
`:ex-data` key (unless that key already exists in context).
Common options:
* :tags, :environment, :release, and :modules will be passed to Sentry
as attributes, Ref. https://docs.sentry.io/clientdev/attributes/.
* :event-fn can be used to modify the raw event before sending it
to Sentry."
[dsn & [opts]]
(let [{:keys [event-fn] :or {event-fn identity}} opts
base-event
(->> (select-keys opts [:tags :environment :release :modules])
(filter (comp not nil? second))
(into {}))]
{:enabled? true
:async? true
:min-level :warn ; Reasonable default given how Sentry works
:fn
(fn [data]
(let [{:keys [instant level output_ ?err msg_ ?ns-str context]} data
?ex-data (ex-data ?err)
extra
(cond-> context
(and ?ex-data (not (contains? context :ex-data)))
(assoc :ex-data
(enc/get-substr-by-idx (str ?ex-data) 0 4096)))
event
(as-> base-event event
(merge event
{:message (force msg_)
:logger ?ns-str
:level (get timbre->sentry-levels level)}
(when extra {:extra extra}))
(if ?err
(interfaces/stacktrace event ?err)
event)
(event-fn event))]
(raven/capture dsn event)))}))
(comment
;; Create an example appender with default opts:
(sentry-appender "https://<key>:<secret>@sentry.io/<project>")
;; Create an example appender with default opts, but override `:min-level`:
(merge (sentry-appender "https://<key>:<secret>@sentry.io/<project>")
{:min-level :debug}))