/
logging.cljs
85 lines (77 loc) · 3.04 KB
/
logging.cljs
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
(ns district.ui.logging
(:require [cljsjs.sentry-browser]
[devtools.preload]
[mount.core :as mount :refer [defstate]]
[taoensso.timbre :as timbre])
(:require-macros [district.shared.error-handling :refer [error?]]))
(declare start)
(defstate logging :start (start (:logging (mount/args))))
(def ^:private devtools-level->fn
{:fatal js/console.error,
:error js/console.error,
:warn js/console.warn,
:info js/console.info,
:debug js/console.info,
:trace js/console.trace})
(def ^:private timbre->sentry-levels
{:fatal "fatal"
:error "error"
:warn "warning"
:info "info"
:debug "debug"
:trace "debug"
:report "info"})
(defn- decode-vargs [vargs]
(reduce (fn [m arg]
(assoc m (cond
(qualified-keyword? arg) :log-ns
(string? arg) :message
(map? arg) :meta)
arg))
{}
vargs))
(def devtools-appender
"Simple js/console appender which avoids pr-str and uses cljs-devtools
to format output"
{:enabled? true
:async? false
:min-level nil
:rate-limit nil
:output-fn nil
:fn
(fn [data]
(let [{:keys [level ?ns-str ?line vargs_]} data
vargs (list* (str ?ns-str ":" ?line) (force vargs_))
f (devtools-level->fn level js/console.log)]
(.apply f js/console (to-array vargs))))})
(defn sentry-appender [{:keys [:min-level]}]
{:enabled? true
:async? true
:min-level (or min-level :warn)
:rate-limit nil
:output-fn :inherit
:fn (fn [{:keys [:level :?ns-str :?line :message :meta :log-ns] :as data}]
(let [{:keys [:error :user :ns :line]} meta]
(when meta
(js-invoke js/Sentry "configureScope" (fn [scope]
(doseq [[k v] meta]
(-> scope (.setExtra (name k) (clj->js v))))
(when user
(-> scope (.setUser (clj->js user)))))))
(if (error? error)
(js-invoke js/Sentry "captureException" error)
(js-invoke js/Sentry "captureEvent" (clj->js {:level (timbre->sentry-levels level)
:message (or message error)
:logger (str (or log-ns ns ?ns-str) ":" (or line ?line))})))))})
(defn wrap-decode-vargs [data]
"Middleware for vargs"
(merge data (decode-vargs (:vargs data))))
(defn start [{:keys [:level :console? :sentry]}]
(when sentry
(js-invoke js/Sentry "init" (clj->js sentry)))
(timbre/merge-config! {:level (keyword level)
:middleware [wrap-decode-vargs]
:appenders {:console (when console?
devtools-appender)
:sentry (when sentry
(sentry-appender sentry))}}))