mirror of https://github.com/status-im/timbre.git
Update 3rd-party appenders (rough)
This commit is contained in:
parent
014faa7bab
commit
3c824d31da
|
@ -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)))))})))
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
|
@ -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)})))
|
||||
|
|
Loading…
Reference in New Issue