-
Notifications
You must be signed in to change notification settings - Fork 2
/
json.clj
87 lines (68 loc) · 1.64 KB
/
json.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
(ns dialog.format.json
"Log format which presents events as JSON objects for structured logging."
(:require
[clojure.data.json :as json]
[io.aviso.exception :as ex]))
(defn- key-fn
"Coerce a map key into a string for use as a JSON object property."
[k]
(cond
(nil? k)
"nil"
(keyword? k)
(subs (str k) 1)
:else
(str k)))
(defn- sanitize-stack-frame
"Sanitize a map of stack frame data for JSON serialization."
[frame]
(into {}
(comp
(map (juxt identity frame))
(filter second))
[:class :file :line :method :name]))
(defn- sanitize-exception
"Sanitize a map of exception data for JSON serialization."
[data]
(assoc data
:stack-trace
(mapv sanitize-stack-frame (:stack-trace data))))
(defn- render-exception
"Convert an exception into a data structure suitable for serializing to JSON."
[ex]
(into []
(map sanitize-exception)
(ex/analyze-exception ex {})))
(defn- value-fn
"Coerce a value into a valid JSON type."
([_k v]
(value-fn v))
([v]
(cond
(or (nil? v)
(boolean? v)
(number? v)
(string? v)
(inst? v)
(uuid? v))
v
(keyword? v)
(key-fn v)
(instance? java.util.Map v)
v
(instance? java.util.Collection v)
(mapv value-fn v)
(instance? java.lang.Exception v)
(render-exception v)
:else
(str v))))
(defn formatter
"Construct a JSON event formatting function."
[_output]
(fn format-event
[event]
(json/write-str
event
:key-fn key-fn
:value-fn value-fn
:escape-slash false)))