|
5 | 5 | [clojure.string :as str])
|
6 | 6 | (:import (ch.qos.logback.classic.spi ILoggingEvent IThrowableProxy ThrowableProxy ThrowableProxyUtil)
|
7 | 7 | (ch.qos.logback.core CoreConstants)
|
| 8 | + (clojure.lang Reflector) |
8 | 9 | (java.time Instant)
|
9 | 10 | (java.util HashMap List Map Map$Entry)
|
10 | 11 | (org.slf4j Marker)
|
|
18 | 19 | :exposes-methods {start superStart, stop superStop}
|
19 | 20 | :methods [[setPrettyPrint [Boolean] void]
|
20 | 21 | [setRemoveNullKeyValuePairs [Boolean] void]
|
| 22 | + [setRemoveEmptyKeyValuePairs [Boolean] void] |
21 | 23 | [setTimestampFormat [String] void]
|
22 | 24 | [setEscapeNonAsciiCharacters [Boolean] void]
|
23 | 25 | [setSortKeysLexicographically [Boolean] void]
|
|
40 | 42 | include-markers
|
41 | 43 | include-exception
|
42 | 44 | include-ex-data
|
43 |
| - exception-as-str |
44 | 45 | modules
|
45 | 46 | object-mapper])
|
46 | 47 |
|
47 | 48 | (defn- reify-jackson-module [module]
|
48 |
| - (clojure.lang.Reflector/invokeConstructor |
49 |
| - (-> module symbol resolve) |
50 |
| - (to-array []))) |
| 49 | + (Reflector/invokeConstructor (resolve (symbol module)) (to-array []))) |
51 | 50 |
|
52 | 51 | (defn- reify-jackson-modules [modules]
|
53 | 52 | (into []
|
|
76 | 75 | [[] (volatile! (let [opts (map->JsonLayoutOpts
|
77 | 76 | {:pretty false
|
78 | 77 | :strip-nils true
|
| 78 | + :strip-empties false |
79 | 79 | :date-format "yyyy-MM-dd'T'HH:mm:ss'Z'"
|
80 | 80 | :escape-non-ascii false
|
81 | 81 | :order-by-keys false
|
|
91 | 91 | (assoc opts :object-mapper (new-object-mapper opts))))])
|
92 | 92 |
|
93 | 93 | (defn- insert-kvp!
|
94 |
| - "Inserts a key value pair into a Java map. If a key with the same name |
95 |
| - already exists, prepends \"@\"-symbols onto the key until it is unique." |
| 94 | + "Inserts an SLF4J `KeyValuePair` into a Java map. If a key with the same |
| 95 | + name already exists, prepends \"@\"-symbols onto the key until it is unique." |
96 | 96 | ^Map [^Map m ^KeyValuePair kv]
|
97 | 97 | (loop [^String k (.key kv)
|
98 | 98 | ^Object v (.value kv)]
|
|
129 | 129 | (if t
|
130 | 130 | (recur (conj! acc (ex-data t)) (.getCause t))
|
131 | 131 | (persistent! acc)))]
|
132 |
| - (if (every? nil? ex-datas) |
133 |
| - nil |
| 132 | + (when-not (every? nil? ex-datas) |
134 | 133 | ex-datas))
|
135 | 134 | (ex-data t)))
|
136 | 135 |
|
|
154 | 153 | "error.kind" (.getClass e)
|
155 | 154 | "error.stack" (ThrowableProxyUtil/asString (ThrowableProxy. e))})
|
156 | 155 | CoreConstants/LINE_SEPARATOR)
|
157 |
| - ;; Another failover for when something is very seriously wrong! |
| 156 | + ;; A second failover for when something is *very* seriously wrong! |
158 | 157 | (catch Throwable _
|
159 | 158 | (format "{\"timestamp\":\"%s\"\"message\":%s,\"exception\":%s,\"level\":\"ERROR\",\"logger.name\":\"%s\"}\n"
|
160 | 159 | (Instant/now)
|
|
186 | 185 | (when (:include-markers opts)
|
187 | 186 | (when-let [^List markers (.getMarkerList event)]
|
188 | 187 | (when-not (.isEmpty markers)
|
189 |
| - ;; TODO: markers vs. tags? |
190 | 188 | (.put m "markers" (mapv #(.getName ^Marker %) markers)))))
|
191 | 189 | (when-let [^IThrowableProxy tp (and (:include-exception opts)
|
192 | 190 | (.getThrowableProxy event))]
|
|
220 | 218 | ;;; -------------------------------------
|
221 | 219 | ;;; Expose Logback configuration options.
|
222 | 220 |
|
223 |
| -(defmacro ^:private set-opt! [this opt] |
224 |
| - `(vswap! (.state ~this) assoc ~(keyword opt) ~opt)) |
225 |
| - |
226 | 221 | (defn- update-opt+mapper
|
227 | 222 | "Update an option in the option map and builds a new Jackson ObjectMapper."
|
228 | 223 | ^JsonLayoutOpts [opts k v]
|
229 | 224 | (let [opts (assoc opts k v)]
|
230 | 225 | (assoc opts :object-mapper (new-object-mapper opts))))
|
231 | 226 |
|
232 |
| -(defn -setPrettyPrint [this pretty-print?] |
233 |
| - (vswap! (.state this) update-opt+mapper |
234 |
| - :pretty pretty-print?)) |
235 |
| - |
236 |
| -(defn -setRemoveNullKeyValuePairs [this remove-nil-kvs?] |
237 |
| - (vswap! (.state this) update-opt+mapper |
238 |
| - :strip-nils remove-nil-kvs?)) |
239 |
| - |
240 |
| -(defn -setTimestampFormat [this timestamp-format] |
241 |
| - (vswap! (.state this) update-opt+mapper |
242 |
| - :date-format timestamp-format)) |
| 227 | +(defmacro ^:private defopt-json [method-name key] |
| 228 | + `(defn ~method-name [this# value#] |
| 229 | + (vswap! (.state this#) update-opt+mapper ~key value#))) |
243 | 230 |
|
244 |
| -(defn -setEscapeNonAsciiCharacters [this escape-non-ascii?] |
245 |
| - (vswap! (.state this) update-opt+mapper |
246 |
| - :escape-non-ascii escape-non-ascii?)) |
| 231 | +(defmacro ^:private defopt [method-name key] |
| 232 | + `(defn ~method-name [this# value#] |
| 233 | + (vswap! (.state this#) assoc ~key value#))) |
247 | 234 |
|
248 |
| -(defn -setSortKeysLexicographically [this sort-keys?] |
249 |
| - (vswap! (.state this) update-opt+mapper |
250 |
| - :order-by-keys sort-keys?)) |
| 235 | +(defopt-json -setPrettyPrint :pretty) |
| 236 | +(defopt-json -setRemoveNullKeyValuePairs :strip-nils) |
| 237 | +(defopt-json -setRemoveEmptyKeyValuePairs :strip-empties) |
| 238 | +(defopt-json -setTimestampFormat :date-format) |
| 239 | +(defopt-json -setEscapeNonAsciiCharacters :escape-non-ascii) |
| 240 | +(defopt-json -setSortKeysLexicographically :order-by-keys) |
251 | 241 |
|
252 | 242 | (defn -setJacksonModules [this modules]
|
253 | 243 | (vswap! (.state this) update-opt+mapper
|
254 | 244 | :modules (reify-jackson-modules modules)))
|
255 | 245 |
|
256 |
| -(defn -setAppendLineSeparator [this append-newline] |
257 |
| - (set-opt! this append-newline)) |
258 |
| - |
259 |
| -(defn -setIncludeLoggerContext [this include-logger-ctx] |
260 |
| - (set-opt! this include-logger-ctx)) |
261 |
| - |
262 |
| -(defn -setIncludeLevelValue [this include-level-val] |
263 |
| - (set-opt! this include-level-val)) |
264 |
| - |
265 |
| -(defn -setIncludeMdc [this include-mdc] |
266 |
| - (set-opt! this include-mdc)) |
267 |
| - |
268 |
| -(defn -setFlattenMdc [this flatten-mdc] |
269 |
| - (set-opt! this flatten-mdc)) |
270 |
| - |
271 |
| -(defn -setIncludeMarkers [this include-markers] |
272 |
| - (set-opt! this include-markers)) |
273 |
| - |
274 |
| -(defn -setIncludeException [this include-exception] |
275 |
| - (set-opt! this include-exception)) |
276 |
| - |
277 |
| -(defn -setIncludeExData [this include-ex-data] |
278 |
| - (set-opt! this include-ex-data)) |
| 246 | +(defopt -setAppendLineSeparator :append-newline) |
| 247 | +(defopt -setIncludeLoggerContext :include-logger-ctx) |
| 248 | +(defopt -setIncludeLevelValue :include-level-val) |
| 249 | +(defopt -setIncludeMdc :include-mdc) |
| 250 | +(defopt -setFlattenMdc :flatten-mdc) |
| 251 | +(defopt -setIncludeMarkers :include-markers) |
| 252 | +(defopt -setIncludeException :include-exception) |
| 253 | +(defopt -setIncludeExData :include-ex-data) |
0 commit comments