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