clojuretimbre

Logging to two files in Timbre


I'm trying to log to two different files from the same namespace with Timbre. Or if that's not possible, at least to different files from the two different namespaces.

Inspecting timbre/*config* I get the impression that I'd need two configuration maps to configure something like that. I can create another config map and use it with timbre/log* in place of the standard config map but I can't shake off the feeling that it's not how this is supposed to be used...?

(timbre/log* timbre/*config* :info "Test with standard config")

Solution

  • AFAIK, the easiest way is indeed to create two config maps:

    (def config1
       {:level :debug 
        :appenders {:spit1 (appenders/spit-appender {:fname "file1.log"})}})
    
    (def config2
       {:level :debug 
        :appenders {:spit2 (appenders/spit-appender {:fname "file2.log"})}})
    
    (timbre/with-config config1
        (info "This will print in file1") )
    
    (timbre/with-config config2
        (info "This will print in file2") )
    

    A second way would be to write your own appender from the spit-appender:

    https://github.com/ptaoussanis/timbre/blob/master/src/taoensso/timbre/appenders/core.cljx

    (defn my-spit-appender
      "Returns a simple `spit` file appender for Clojure."
      [& [{:keys [fname] :or {fname "./timbre-spit.log"}}]]
      {:enabled?   true
       :async?     false
       :min-level  nil
       :rate-limit nil
       :output-fn  :inherit
       :fn
       (fn self [data]
         (let [{:keys [output_]} data]
           (try
    
            ;; SOME LOGIC HERE TO CHOOSE THE FILE TO OUTPUT TO ...             
    
             (spit fname (str (force output_) "\n") :append true)
             (catch java.io.IOException e
               (if (:__spit-appender/retry? data)
                 (throw e) ; Unexpected error
                 (let [_    (have? enc/nblank-str? fname)
                       file (java.io.File. ^String fname)
                       dir  (.getParentFile (.getCanonicalFile file))]
    
                   (when-not (.exists dir) (.mkdirs dir))
                   (self (assoc data :__spit-appender/retry? true))))))))})