-
-
Notifications
You must be signed in to change notification settings - Fork 171
/
rolling.clj
80 lines (70 loc) · 2.58 KB
/
rolling.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(ns taoensso.timbre.appenders.community.rolling
"Rolling file appender."
(:require
[clojure.java.io :as io]
[taoensso.encore :as enc]
[taoensso.timbre :as timbre])
(:import
[java.text SimpleDateFormat]
[java.util Calendar]))
;; TODO Test port to Timbre v4
(defn- rename-old-create-new-log [log old-log]
(.renameTo log old-log)
(.createNewFile log))
(defn- shift-log-period [log path prev-cal]
(let [postfix (-> "yyyyMMdd" SimpleDateFormat. (.format (.getTime prev-cal)))
old-path (format "%s.%s" path postfix)
old-log (io/file old-path)]
(if (.exists old-log)
(loop [index 0]
(let [index-path (format "%s.%d" old-path index)
index-log (io/file index-path)]
(if (.exists index-log)
(recur (+ index 1))
(rename-old-create-new-log log index-log))))
(rename-old-create-new-log log old-log))))
(defn- log-cal [date] (let [now (Calendar/getInstance)] (.setTime now date) now))
(defn- prev-period-end-cal [date pattern]
(let [cal (log-cal date)
offset (case pattern
:daily 1
:weekly (.get cal Calendar/DAY_OF_WEEK)
:monthly (.get cal Calendar/DAY_OF_MONTH)
0)]
(.add cal Calendar/DAY_OF_MONTH (* -1 offset))
(.set cal Calendar/HOUR_OF_DAY 23)
(.set cal Calendar/MINUTE 59)
(.set cal Calendar/SECOND 59)
(.set cal Calendar/MILLISECOND 999)
cal))
(defn rolling-appender
"Returns a Rolling file appender. Opts:
:path - logfile path.
:pattern - frequency of rotation, e/o {:daily :weekly :monthly}."
[& [{:keys [path pattern]
:or {path "./timbre-rolling.log"
pattern :daily}}]]
{:enabled? true
:fn
(let [lock (Object.)]
(fn [data]
(let [{:keys [instant output_]} data
output-str (force output_)
prev-cal (prev-period-end-cal instant pattern)]
(when-let [log (io/file path)]
(try
(locking lock
(when-not (.exists log)
(io/make-parents log))
(if (.exists log)
(if (<= (.lastModified log) (.getTimeInMillis prev-cal))
(shift-log-period log path prev-cal))
(.createNewFile log)))
(spit path (with-out-str (println output-str)) :append true)
(catch java.io.IOException _))))))})
;;;; Deprecated
(enc/deprecated
(defn ^:no-doc ^:deprecated make-rolling-appender
"Prefer `rolling-appender`."
[& [appender-merge opts]]
(merge (rolling-appender opts) appender-merge)))