diff --git a/src/taoensso/timbre/appenders/3rd_party/android.clj b/src/taoensso/timbre/appenders/3rd_party/android.clj index 4382a42..04c90c7 100644 --- a/src/taoensso/timbre/appenders/3rd_party/android.clj +++ b/src/taoensso/timbre/appenders/3rd_party/android.clj @@ -1,41 +1,44 @@ -(ns taoensso.timbre.appenders.android - "Android LogCat appender. Depends on the android runtime. This is a - configuration for the timbre logging library" +(ns taoensso.timbre.appenders.3rd-party.android + "Android LogCat appender. Requires Android runtime." {:author "Adam Clements"} - (:require [taoensso.timbre :as timbre] - clojure.string)) + (:require [clojure.string :as str] + [taoensso.timbre :as timbre])) -(defn make-logcat-appender +(defn make-appender "Returns an appender that writes to Android LogCat. Obviously only works if running within the Android runtime (device or emulator). You may want to disable std-out to prevent printing nested timestamps, etc." - [& [appender-opts make-opts]] - (let [default-appender-opts {:enabled? true - :min-level :debug}] - (merge default-appender-opts appender-opts - {:fn (fn [{:keys [level ns throwable message]}] - (let [output (format "%s %s - %s" timestamp - (-> level name clojure.string/upper-case) - (or message ""))] - (if throwable - (case level - :trace (android.util.Log/d ns output throwable) - :debug (android.util.Log/d ns output throwable) - :info (android.util.Log/i ns output throwable) - :warn (android.util.Log/w ns output throwable) - :error (android.util.Log/e ns output throwable) - :fatal (android.util.Log/e ns output throwable) - :report (android.util.Log/i ns output throwable)) + [& [appender-config make-config]] + (let [default-appender-config + {:enabled? true + :min-level :debug}] - (case level - :trace (android.util.Log/d ns output) - :debug (android.util.Log/d ns output) - :info (android.util.Log/i ns output) - :warn (android.util.Log/w ns output) - :error (android.util.Log/e ns output) - :fatal (android.util.Log/e ns output) - :report (android.util.Log/i ns output)))))}))) + (merge default-appender-config appender-config + {:fn + (fn [data] + (let [{:keys [level ?ns-str ?err_ msg_ timestamp_]} data + msg (or (force msg_) "") + timestamp (force timestamp_) + ns (or ?ns-str "") + output (format "%s %s - %s" timestamp + (-> level name str/upper-case) + msg)] -(def logcat-appender - "DEPRECATED: Use `make-logcat-appender` instead." - (make-logcat-appender)) + (if-let [throwable (force ?err_)] + (case level + :trace (android.util.Log/d ns output throwable) + :debug (android.util.Log/d ns output throwable) + :info (android.util.Log/i ns output throwable) + :warn (android.util.Log/w ns output throwable) + :error (android.util.Log/e ns output throwable) + :fatal (android.util.Log/e ns output throwable) + :report (android.util.Log/i ns output throwable)) + + (case level + :trace (android.util.Log/d ns output) + :debug (android.util.Log/d ns output) + :info (android.util.Log/i ns output) + :warn (android.util.Log/w ns output) + :error (android.util.Log/e ns output) + :fatal (android.util.Log/e ns output) + :report (android.util.Log/i ns output)))))}))) diff --git a/src/taoensso/timbre/appenders/3rd_party/irc.clj b/src/taoensso/timbre/appenders/3rd_party/irc.clj index 4813e1a..1b8b9e2 100644 --- a/src/taoensso/timbre/appenders/3rd_party/irc.clj +++ b/src/taoensso/timbre/appenders/3rd_party/irc.clj @@ -1,18 +1,20 @@ -(ns taoensso.timbre.appenders.irc - "IRC appender. Depends on https://github.com/flatland/irclj." +(ns taoensso.timbre.appenders.3rd-party.irc + "IRC appender. Requires https://github.com/flatland/irclj." {:author "Emlyn Corrin"} (:require [clojure.string :as str] [irclj.core :as irc] [taoensso.timbre :as timbre])) (defn default-fmt-output-fn - [{:keys [level throwable message]}] + [{:keys [level ?err_ msg_]}] (format "[%s] %s%s" - (-> level name (str/upper-case)) - (or message "") - (or (timbre/stacktrace throwable "\n") ""))) + (-> level name (str/upper-case)) + (or (force msg_) "") + (if-let [err (force ?err_)] + (str "\n" (timbre/stacktrace err)) + ""))) -(def default-appender-opts +(def default-appender-config {:async? true :enabled? true :min-level :info}) @@ -38,38 +40,36 @@ (irc/message conn chan ">" line)))) (defn- make-appender-fn [irc-config conn] - (fn [{:keys [ap-config] :as args}] - (when-let [irc-config (or irc-config (:irc ap-config))] - (ensure-conn conn irc-config) - (let [fmt-fn (or (:fmt-output-fn irc-config) - default-fmt-output-fn)] - (send-message conn (:chan irc-config) (fmt-fn args)))))) + (fn [data] + (let [{:keys [appender-opts]} data] + (when-let [irc-config (or irc-config appender-opts)] + (ensure-conn conn irc-config) + (let [fmt-fn (or (:fmt-output-fn irc-config) + default-fmt-output-fn)] + (send-message conn (:chan irc-config) (fmt-fn data))))))) ;;; Public -(defn make-irc-appender +(defn make-appender "Sends IRC messages using irc. - Needs :irc config map in :shared-appender-config, e.g.: - {:host \"irc.example.org\" :port 6667 :nick \"logger\" - :name \"My Logger\" :chan \"#logs\"}" - [& [appender-opts {:keys [irc-config]}]] + Needs :opts map in appender, e.g.: + {:host \"irc.example.org\" :port 6667 :nick \"logger\" + :name \"My Logger\" :chan \"#logs\"}" + [& [appender-config {:keys [irc-config]}]] (let [conn (atom nil)] - (merge default-appender-opts - appender-opts - {:conn conn - :doc (:doc (meta #'make-irc-appender)) - :fn (make-appender-fn irc-config conn)}))) - -(def irc-appender "DEPRECATED: Use `make-irc-appender` instead." - (make-irc-appender)) + (merge default-appender-config appender-config + {:conn conn + :fn (make-appender-fn irc-config conn)}))) (comment - (timbre/set-config! - [:shared-appender-config :irc] - {:host "127.0.0.1" - :nick "lazylog" - :user "lazare" - :name "Lazylus Logus" - :chan "bob"}) - (timbre/set-config! [:appenders :irc] (make-irc-appender)) - (timbre/log :error "A multiple\nline message\nfor you")) + (timbre/merge-config! {:appenders {:irc (make-appender)}}) + (timbre/merge-config! + {:appenders + {:irc + {:opts + {:host "127.0.0.1" + :nick "lazylog" + :user "lazare" + :name "Lazylus Logus" + :chan "bob"}}}}) + (timbre/error "A multiple\nline message\nfor you")) diff --git a/src/taoensso/timbre/appenders/3rd_party/mongo.clj b/src/taoensso/timbre/appenders/3rd_party/mongo.clj index bde6431..8d6a029 100644 --- a/src/taoensso/timbre/appenders/3rd_party/mongo.clj +++ b/src/taoensso/timbre/appenders/3rd_party/mongo.clj @@ -1,7 +1,9 @@ -(ns taoensso.timbre.appenders.mongo - "MongoDB appender. Depends on https://github.com/aboekhoff/congomongo." +(ns taoensso.timbre.appenders.3rd-party.mongo + "MongoDB appender. Requires on https://github.com/aboekhoff/congomongo." {:author "Emlyn Corrin"} - (:require [somnium.congomongo :as mongo])) + (:require [somnium.congomongo :as mongo] + [taoensso.timbre :as timbre] + [taoensso.encore :as encore])) (def conn (atom nil)) @@ -21,26 +23,28 @@ :as config}] (let [selected-params (if logged-keys (select-keys params logged-keys) - (dissoc params :ap-config)) - logged-params (if-let [t (:throwable selected-params)] - (assoc selected-params :throwable (str t)) - selected-params)] + (dissoc params :config :appender :appender-opts)) + logged-params (encore/map-vals #(str (force %)) selected-params)] (mongo/with-mongo (ensure-conn config) (mongo/insert! collection logged-params)))) -(defn appender-fn [{:keys [ap-config] :as params}] - (when-let [mongo-config (:mongo ap-config)] - (log-message params mongo-config))) +(defn- make-appender-fn [make-config] + (fn [data] + (let [{:keys [appender-opts]} data] + (when-let [mongo-config appender-opts] + (log-message data mongo-config))))) -(def mongo-appender - {:doc (str "Logs to MongoDB using congomongo.\n" - "Needs :mongo config map in :shared-appender-config, e.g.: - {:db \"logs\" - :collection \"myapp\" - :logged-keys [:instant :level :message] - :write-concern :acknowledged - :server {:host \"127.0.0.1\" - :port 27017}}") - :min-level :warn :enabled? true :async? true - :rate-limit [1 1000] ; 1 entry / sec - :fn appender-fn}) +(defn make-appender + "Logs to MongoDB using congomongo. Needs :opts map in appender, e.g.: + {:db \"logs\" + :collection \"myapp\" + :logged-keys [:instant :level :msg_] + :write-concern :acknowledged + :server {:host \"127.0.0.1\" + :port 27017}}" + [& [appender-config make-config]] + (let [default-appender-config + {:min-level :warn :enabled? true :async? true + :rate-limit [[1 1000]]}] + (merge default-appender-config appender-config + {:fn (make-appender-fn make-config)}))) diff --git a/src/taoensso/timbre/appenders/3rd_party/rolling.clj b/src/taoensso/timbre/appenders/3rd_party/rolling.clj index 0f80808..6d93874 100644 --- a/src/taoensso/timbre/appenders/3rd_party/rolling.clj +++ b/src/taoensso/timbre/appenders/3rd_party/rolling.clj @@ -1,8 +1,10 @@ -(ns taoensso.timbre.appenders.rolling "Rolling file appender." +(ns taoensso.timbre.appenders.3rd-party.rolling + "Rolling file appender." + {:author "Unknown - please let me know?"} (:require [clojure.java.io :as io] [taoensso.timbre :as timbre]) - (:import [java.text SimpleDateFormat] - [java.util Calendar])) + (:import [java.text SimpleDateFormat] + [java.util Calendar])) (defn- rename-old-create-new-log [log old-log] (.renameTo log old-log) @@ -41,9 +43,11 @@ cal)) (defn- make-appender-fn [path pattern] - (fn [{:keys [ap-config output instant]}] - (let [path (or path (-> ap-config :rolling :path)) - pattern (or pattern (-> ap-config :rolling :pattern) :daily) + (fn [data] + (let [{:keys [instant appender-opts output-fn]} data + output (output-fn data) + path (or path (-> appender-opts :path)) + pattern (or pattern (-> appender-opts :pattern) :daily) prev-cal (prev-period-end-cal instant pattern) log (io/file path)] (when log @@ -52,20 +56,20 @@ (if (<= (.lastModified log) (.getTimeInMillis prev-cal)) (shift-log-period log path prev-cal)) (.createNewFile log)) - (spit path (with-out-str (timbre/str-println output)) :append true) + (spit path (with-out-str (println output)) :append true) (catch java.io.IOException _)))))) -(defn make-rolling-appender +(defn make-appender "Returns a Rolling file appender. - A rolling config map can be provided here as a second argument, or provided at - :rolling in :shared-appender-config. + A rolling config map can be provided here as a second argument, or provided in + appender's :opts map. (make-rolling-appender {:enabled? true} {:path \"log/app.log\" :pattern :daily}) path: logfile path pattern: frequency of rotation, available values: :daily (default), :weekly, :monthly" - [& [appender-opts {:keys [path pattern]}]] - (let [default-appender-opts {:enabled? true :min-level nil}] - (merge default-appender-opts appender-opts + [& [appender-config {:keys [path pattern]}]] + (let [default-appender-config {:enabled? true :min-level nil}] + (merge default-appender-config appender-config {:fn (make-appender-fn path pattern)}))) diff --git a/src/taoensso/timbre/appenders/3rd_party/rotor.clj b/src/taoensso/timbre/appenders/3rd_party/rotor.clj index 25451b3..a3c744d 100644 --- a/src/taoensso/timbre/appenders/3rd_party/rotor.clj +++ b/src/taoensso/timbre/appenders/3rd_party/rotor.clj @@ -1,10 +1,8 @@ -(ns taoensso.timbre.appenders.rotor +(ns taoensso.timbre.appenders.3rd-party.rotor {:author "Yutaka Matsubara"} - (:import - [java.io File FilenameFilter]) - (:require - [clojure.java.io :as io] - [taoensso.timbre :as t])) + (:require [clojure.java.io :as io] + [taoensso.timbre :as timbre]) + (:import [java.io File FilenameFilter])) (defn- ^FilenameFilter file-filter "Returns a Java FilenameFilter instance which only matches @@ -45,25 +43,27 @@ (reverse (map vector logs-to-rotate (iterate inc 1)))] (.renameTo log-file (io/file (format "%s.%03d" abs-path n)))))) -(defn appender-fn [{:keys [ap-config output]}] - (let [{:keys [path max-size backlog] - :or {max-size (* 1024 1024) - backlog 5}} (:rotor ap-config)] - (when path - (try - (when (> (.length (io/file path)) max-size) - (rotate-logs path backlog)) - (spit path - (str output "\n") - :append true) - (catch java.io.IOException _))))) +(defn make-appender-fn [make-config] + (fn [data] + (let [{:keys [appender-opts output-fn]} data + {:keys [path max-size backlog] + :or {max-size (* 1024 1024) + backlog 5}} appender-opts] + (when path + (try + (when (> (.length (io/file path)) max-size) + (rotate-logs path backlog)) + (spit path (str (output-fn data) "\n") :append true) + (catch java.io.IOException _)))))) -(def rotor-appender - {:doc (str "Simple Rotating File Appender.\n" - "Needs :rotor config map in :shared-appender-config, e.g.: - {:path \"logs/app.log\" - :max-size (* 512 1024) - :backlog 5}") - :min-level nil - :enabled? true - :fn appender-fn}) +(defn make-appender + "Simple Rotating File Appender. + Needs :opts map in appender, e.g.: + {:path \"logs/app.log\" + :max-size (* 512 1024) + :backlog 5}" + [& [appender-config make-config]] + (let [default-appender-config + {:min-level :warn :enabled? true}] + (merge default-appender-config appender-config + {:fn (make-appender-fn make-config)}))) diff --git a/src/taoensso/timbre/appenders/3rd_party/socket.clj b/src/taoensso/timbre/appenders/3rd_party/socket.clj index 60443af..03d5817 100644 --- a/src/taoensso/timbre/appenders/3rd_party/socket.clj +++ b/src/taoensso/timbre/appenders/3rd_party/socket.clj @@ -1,10 +1,10 @@ -(ns taoensso.timbre.appenders.socket - "TCP Socket appender. Depends on https://github.com/technomancy/server-socket." +(ns taoensso.timbre.appenders.3rd-party.socket + "TCP socket appender. Requires https://github.com/technomancy/server-socket." {:author "Emlyn Corrin"} (:require [server.socket :refer [create-server]] [taoensso.timbre :refer [stacktrace]]) - (:import [java.net Socket InetAddress] - [java.io BufferedReader InputStreamReader PrintWriter])) + (:import [java.net Socket InetAddress] + [java.io BufferedReader InputStreamReader PrintWriter])) (def conn (atom nil)) @@ -30,19 +30,23 @@ (defn ensure-conn [socket-config] (swap! conn #(or % (connect socket-config)))) -(defn appender-fn [{:keys [ap-config prefix message throwable] :as params}] - (when-let [socket-config (:socket ap-config)] - (let [c (ensure-conn socket-config)] - (doseq [sock @(:connections c)] - (let [out (PrintWriter. (.getOutputStream ^Socket sock))] - (binding [*out* out] - (println prefix message - (stacktrace throwable)))))))) +(defn make-appender-fn [make-config] + (fn [data] + (let [{:keys [appender-opts output-fn ?err_]} data] + (when-let [socket-config appender-opts] + (let [c (ensure-conn socket-config)] + (doseq [sock @(:connections c)] + (let [out (PrintWriter. (.getOutputStream ^Socket sock))] + (binding [*out* out] + (println (output-fn data)))))))))) -(def socket-appender - {:doc (str "Logs to a listening socket.\n" - "Needs :socket config map in :shared-appender-config, e.g.: - {:listen-addr :all - :port 9000}") - :min-level :trace :enabled? true - :fn appender-fn}) +(defn make-appender + "Logs to a listening socket. + Needs :opts map in appender, e.g.: + {:listen-addr :all + :port 9000}" + [& [appender-config make-config]] + (let [default-appender-config + {:min-level :trace :enabled? true}] + (merge default-appender-config appender-config + {:fn (make-appender-fn make-config)}))) diff --git a/src/taoensso/timbre/appenders/3rd_party/zmq.clj b/src/taoensso/timbre/appenders/3rd_party/zmq.clj index abfc628..e2e43a2 100644 --- a/src/taoensso/timbre/appenders/3rd_party/zmq.clj +++ b/src/taoensso/timbre/appenders/3rd_party/zmq.clj @@ -1,34 +1,37 @@ -(ns taoensso.timbre.appenders.zmq +(ns taoensso.timbre.appenders.3rd-party.zmq "ØMQ appender. Requires https://github.com/zeromq/cljzmq" {:author "Angus Fletcher"} - (:require [zeromq.zmq :as zmq] + (:require [zeromq.zmq :as zmq] [taoensso.timbre :as timbre])) (defn make-zmq-socket [context transport address port] (doto (zmq/socket context :push) (zmq/connect (format "%s://%s:%d" transport address port)))) -(defn appender-fn [socket poller {:keys [ap-config output]}] - (loop [] - (zmq/poll poller 500) - (cond - (zmq/check-poller poller 0 :pollout) (zmq/send-str socket output) - (zmq/check-poller poller 0 :pollerr) (System/exit 1) - :else (recur)))) +(defn make-appender-fn [socket poller] + (fn [data] + (let [{:keys [appender-opts output-fn]} data + output (output-fn data)] + (loop [] + (zmq/poll poller 500) + (cond + (zmq/check-poller poller 0 :pollout) (zmq/send-str socket output) + (zmq/check-poller poller 0 :pollerr) (System/exit 1) + :else (recur)))))) -(defn make-zmq-appender +(defn make-appender "Returns a ØMQ appender. Takes appender options and a map consisting of: transport: a string representing transport type: tcp, ipc, inproc, pgm/epgm address: a string containing an address to connect to. port: a number representing the port to connect to." - [& [appender-opts {:keys [transport address port]}]] - (let [default-appender-opts {:enabled? true - :min-level :error - :async? true} + [& [appender-config {:keys [transport address port]}]] + (let [default-appender-config + {:enabled? true + :min-level :error + :async? true} context (zmq/zcontext) socket (make-zmq-socket context transport address port) poller (doto (zmq/poller context) (zmq/register socket :pollout :pollerr))] - (merge default-appender-opts - appender-opts - {:fn (partial appender-fn socket poller)}))) + (merge default-appender-config appender-config + {:fn (make-appender-fn socket poller)})))