         clojure.tools.logging)
   (:require
     [clojure.set :as set]
-    [clojure.tools.logging.impl :as impl]))
-
-(defn test-factory [enabled-set entries-atom agent-used-atom]
-  (let [main-thread (Thread/currentThread)]
-    (reify impl/LoggerFactory
-      (name [_] "test factory")
-      (get-logger [_ log-ns]
-        (reify impl/Logger
-          (enabled? [_ level] (contains? enabled-set level))
-          (write! [_ lvl ex msg]
-            (reset! entries-atom [(str log-ns) lvl ex msg])
-            (reset! agent-used-atom (not (identical? main-thread (Thread/currentThread))))))))))
-
-(defmacro with-test-logging
-  [[enabled-level-set log-entry-sym agent-used?-sym] & body]
-  (let [enabled-level-set (or enabled-level-set #{:trace :debug :info :warn :error :fatal})
-        log-entry-sym (or log-entry-sym 'log-entry-sym)
-        agent-used?-sym (or agent-used?-sym 'agent-used?-sym)]
-    `(let [~log-entry-sym (atom nil)
-           ~agent-used?-sym (atom nil)]
-       (binding [*logger-factory* (test-factory
-                                    ~enabled-level-set
-                                    ~log-entry-sym
-                                    ~agent-used?-sym)]
-         ~@body))))
+    [clojure.tools.logging.impl :as impl]
+    [clojure.tools.logging.test :as log-test :refer [logged?
+                                                     matches]]))
+
+; TODO: Improve tools.logging.test so that the ability to check the thread is
+;       not so hacky/out-of-band from the normal flow.
+
+
+(defn log-entry-with-thread [logger-ns level throwable message]
+  (assoc (log-test/->LogEntry logger-ns level throwable message)
+         ::thread (Thread/currentThread)))
+
+(defn same-thread? [log-entry]
+  (identical? (::thread log-entry)
+              (Thread/currentThread)))
+
+(defn direct-logged? [logger-ns level throwable message]
+  (->> (log-test/matches logger-ns level throwable message)
+    (filter same-thread?)
+    seq
+    boolean))
+
+(defn agent-logged? [logger-ns level throwable message]
+  (->> (log-test/matches logger-ns level throwable message)
+    (remove same-thread?)
+    seq
+    boolean))
+
+(defmacro with-log [& body]
+  `(let [stateful-log# (log-test/atomic-log log-entry-with-thread)
+         logger-factory# (log-test/logger-factory stateful-log# (constantly true))]
+     (binding [log-test/*stateful-log*   stateful-log#
+               *logger-factory* logger-factory#]
+       ~@body)))
+
+(defmacro with-log-level [level & body]
+  `(let [stateful-log# (log-test/atomic-log log-entry-with-thread)
+         logger-factory# (log-test/logger-factory stateful-log# #(= ~level %2))]
+     (binding [log-test/*stateful-log*   stateful-log#
+               *logger-factory* logger-factory#]
+       ~@body)))
 
 (deftest log-yields-nil
   (let [enabled-logger  (reify impl/Logger

      (is (== 6 @cnt)))))

(deftest logf-single-eval
  (with-test-logging []
    (let [cnt (atom 0)]
      (logf :debug (str (swap! cnt inc)))
      (logf :debug (str (swap! cnt inc)) :foo)


(deftest println-style-ex
  (let [e (Exception.)]
    (are [f kw] (with-log
                  (f e "hello" "world")
                  (logged? "clojure.tools.test-logging" kw e "hello world"))
      trace :trace
      debug :debug
      info :info
