|
17 | 17 | [java.net MalformedURLException URISyntaxException URL] |
18 | 18 | [java.nio ByteBuffer CharBuffer] |
19 | 19 | [java.nio.charset Charset CoderResult StandardCharsets] |
20 | | - (java.util.concurrent ScheduledThreadPoolExecutor TimeUnit))) |
| 20 | + (java.util.concurrent ScheduledThreadPoolExecutor TimeUnit) |
| 21 | + (org.apache.log4j MDC))) |
21 | 22 |
|
22 | 23 | (defmacro with-captured-throw [& body] |
23 | 24 | `(try [(do ~@body)] (catch Throwable ex# ex#))) |
|
34 | 35 | (apply print args) |
35 | 36 | (flush))) |
36 | 37 |
|
| 38 | +(defmacro with-log-mdc |
| 39 | + "Establishes the MDC contexts given by the alternating-kvs key value |
| 40 | + pairs during the execution of the body, and ensures that the |
| 41 | + original values (if any) are always restored before returning." |
| 42 | + [alternating-kvs & body] |
| 43 | + ;; For now, assume this isn't used in performance-critical code, |
| 44 | + ;; i.e. within tight loops. |
| 45 | + (when-not (even? (count alternating-kvs)) |
| 46 | + (throw (RuntimeException. "Odd number of MDC key value pairs"))) |
| 47 | + (when-not (every? string? (take-nth 2 alternating-kvs)) |
| 48 | + (throw (RuntimeException. "MDC keys are not all strings"))) |
| 49 | + (loop [[k v & alternating-kvs] alternating-kvs |
| 50 | + expansion `(do ~@body)] |
| 51 | + (if-not k |
| 52 | + expansion |
| 53 | + (recur alternating-kvs |
| 54 | + ;; We know k is a string, so it's fine to repeat ~k |
| 55 | + `(let [v# ~v] |
| 56 | + (if (nil? v#) |
| 57 | + ~expansion |
| 58 | + (let [orig# (MDC/get ~k)] |
| 59 | + (try |
| 60 | + (MDC/put ~k v#) |
| 61 | + ~expansion |
| 62 | + (finally |
| 63 | + ;; After you put a nil value MDC/getContext crashes |
| 64 | + (if (nil? orig#) |
| 65 | + (MDC/remove ~k) |
| 66 | + (MDC/put ~k orig#))))))))))) |
| 67 | + |
37 | 68 | (defn flush-and-exit |
38 | 69 | "Attempts to flush *out* and *err*, reporting any failures to *err*, |
39 | 70 | if possible, and then invokes (System/exit status)." |
|
0 commit comments