diff --git a/project.clj b/project.clj index a834070..66b78b3 100644 --- a/project.clj +++ b/project.clj @@ -8,16 +8,16 @@ :url "https://www.eclipse.org/legal/epl-v10.html"} :dependencies - [[com.taoensso/encore "3.104.1"]] + [[com.taoensso/encore "3.105.1"]] :test-paths ["test" #_"src"] :profiles {;; :default [:base :system :user :provided :dev] :provided {:dependencies [[org.clojure/clojurescript "1.11.132"] - [org.clojure/clojure "1.11.2"]]} - :c1.12 {:dependencies [[org.clojure/clojure "1.12.0-alpha9"]]} - :c1.11 {:dependencies [[org.clojure/clojure "1.11.2"]]} + [org.clojure/clojure "1.11.3"]]} + :c1.12 {:dependencies [[org.clojure/clojure "1.12.0-alpha10"]]} + :c1.11 {:dependencies [[org.clojure/clojure "1.11.3"]]} :c1.10 {:dependencies [[org.clojure/clojure "1.10.1"]]} :graal-tests diff --git a/resources/signal-docstrings/filter-system-vals.txt b/resources/signal-docstrings/filter-system-vals.txt new file mode 100644 index 0000000..1f53380 --- /dev/null +++ b/resources/signal-docstrings/filter-system-vals.txt @@ -0,0 +1,15 @@ +These include: + + Compile-time: + + ns-filter: (get-env {:as :edn} :taoensso.telemere/ct-ns-filter<.platform><.edn>) + id-filter: (get-env {:as :edn} :taoensso.telemere/ct-id-filter<.platform><.edn>) + min-level: (get-env {:as :edn} :taoensso.telemere/ct-min-level<.platform><.edn>) + + Runtime: + + ns-filter: (get-env {:as :edn} :taoensso.telemere/rt-ns-filter<.platform><.edn>) + id-filter: (get-env {:as :edn} :taoensso.telemere/rt-id-filter<.platform><.edn>) + min-level: (get-env {:as :edn, :default :info} :taoensso.telemere/rt-min-level<.platform><.edn>) + + See `get-env` for details. diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 0ab74ab..b647912 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -1,7 +1,7 @@ {;;:lein true :source-paths ["src" "test"] :dependencies - [[com.taoensso/encore "3.104.1"] + [[com.taoensso/encore "3.105.1"] [cider/cider-nrepl "0.47.0"] [binaryage/devtools "1.0.7"]] diff --git a/slf4j/project.clj b/slf4j/project.clj index ad5ac1a..4f565b5 100644 --- a/slf4j/project.clj +++ b/slf4j/project.clj @@ -14,7 +14,7 @@ :profiles {:provided {:dependencies - [[org.clojure/clojure "1.11.2"] + [[org.clojure/clojure "1.11.3"] [org.slf4j/slf4j-api "2.0.13"] [com.taoensso/telemere "1.0.0-beta3"]]} diff --git a/src/taoensso/telemere.cljc b/src/taoensso/telemere.cljc index 21f7d0e..5d60229 100644 --- a/src/taoensso/telemere.cljc +++ b/src/taoensso/telemere.cljc @@ -11,9 +11,9 @@ [taoensso.encore.signals :as sigs] [taoensso.telemere.impl :as impl] [taoensso.telemere.utils :as utils] - #?(:clj [taoensso.telemere.streams :as streams]) - #?(:default [taoensso.telemere.console-handlers :as ch]) - #?(:clj [taoensso.telemere.file-handler :as fh])) + #?(:default [taoensso.telemere.consoles :as consoles]) + #?(:clj [taoensso.telemere.streams :as streams]) + #?(:clj [taoensso.telemere.files :as files])) #?(:cljs (:require-macros @@ -32,7 +32,7 @@ (remove-ns 'taoensso.telemere) (:api (enc/interns-overview))) -(enc/assert-min-encore-version [3 104 1]) +(enc/assert-min-encore-version [3 105 1]) ;;;; TODO ;; - Add email handler @@ -49,21 +49,7 @@ :*rt-sig-filter* impl/*rt-sig-filter* :*sig-handlers* impl/*sig-handlers* :sig-filter-system-vals-info - "These include: - - Compile-time: - - ns-filter: (get-env {:as :edn} :taoensso.telemere/ct-ns-filter<.platform><.edn>) - id-filter: (get-env {:as :edn} :taoensso.telemere/ct-id-filter<.platform><.edn>) - min-level: (get-env {:as :edn} :taoensso.telemere/ct-min-level<.platform><.edn>) - - Runtime: - - ns-filter: (get-env {:as :edn} :taoensso.telemere/rt-ns-filter<.platform><.edn>) - id-filter: (get-env {:as :edn} :taoensso.telemere/rt-id-filter<.platform><.edn>) - min-level: (get-env {:as :edn, :default :info} :taoensso.telemere/rt-min-level<.platform><.edn>) - - See `get-env` for details."}) + (impl/signal-docstring :filter-system-vals)}) (comment help:filters) @@ -181,30 +167,6 @@ See `*middleware*` for details." [init-val form] `(binding [*middleware* ~init-val] ~form))) -;;;; Encore integration - -(do - (enc/set-var-root! sigs/*default-handler-error-fn* - (fn [{:keys [error] :as m}] - (impl/signal! - {:kind :error - :level :error - :error error - :location {:ns "taoensso.encore.signals"} - :id :taoensso.encore.signals/handler-error - :msg "Error executing wrapped handler fn" - :data (dissoc m :error)}))) - - (enc/set-var-root! sigs/*default-handler-backp-fn* - (fn [data] - (impl/signal! - {:kind :event - :level :warn - :location {:ns "taoensso.encore.signals"} - :id :taoensso.encore.signals/handler-back-pressure - :msg "Back pressure on wrapped handler fn" - :data data})))) - ;;;; Signal creators ;; - signal! [ opts] ; => allowed? / run result (value or throw) ;; - event! [id ] [id level-or-opts] ; id + ?level => allowed? ; Sole signal with descending main arg! @@ -376,9 +338,39 @@ ;;;; Handlers (enc/defaliases - #?(:default ch/handler:console) - #?(:cljs ch/handler:console-raw) - #?(:clj fh/handler:file)) + #?(:default consoles/handler:console) + #?(:cljs consoles/handler:console-raw) + #?(:clj files/handler:file)) + +;;;; Init + +(impl/on-init + + (enc/set-var-root! sigs/*default-handler-error-fn* + (fn [{:keys [error] :as m}] + (impl/signal! + {:kind :error + :level :error + :error error + :location {:ns "taoensso.encore.signals"} + :id :taoensso.encore.signals/handler-error + :msg "Error executing wrapped handler fn" + :data (dissoc m :error)}))) + + (enc/set-var-root! sigs/*default-handler-backp-fn* + (fn [data] + (impl/signal! + {:kind :event + :level :warn + :location {:ns "taoensso.encore.signals"} + :id :taoensso.encore.signals/handler-back-pressure + :msg "Back pressure on wrapped handler fn" + :data data}))) + + (add-handler! :default/console (handler:console)) + + #?(:clj (enc/catching (require '[taoensso.telemere.tools-logging]))) + #?(:clj (enc/catching (require '[taoensso.telemere.slf4j])))) ;;;; Flow benchmarks @@ -413,14 +405,6 @@ ;;;; -(impl/on-init - (add-handler! :default/console (handler:console)) - - #?(:clj (enc/catching (require '[taoensso.telemere.tools-logging]))) - #?(:clj (enc/catching (require '[taoensso.telemere.slf4j])))) - -;;;; - (comment (with-handler :hid1 (handler:console) {} (log! "Message")) diff --git a/src/taoensso/telemere/console_handlers.cljc b/src/taoensso/telemere/consoles.cljc similarity index 79% rename from src/taoensso/telemere/console_handlers.cljc rename to src/taoensso/telemere/consoles.cljc index e2053dc..86983a3 100644 --- a/src/taoensso/telemere/console_handlers.cljc +++ b/src/taoensso/telemere/consoles.cljc @@ -1,22 +1,28 @@ -(ns ^:no-doc taoensso.telemere.console-handlers +(ns ^:no-doc taoensso.telemere.consoles "Private ns, implementation detail. - Core console handlers." + Core console handlers, aliased in main Telemere ns." (:require [taoensso.encore :as enc :refer [have have?]] [taoensso.telemere.utils :as utils])) (comment - (remove-ns 'taoensso.telemere.console-handlers) + (require '[taoensso.telemere :as tel]) + (remove-ns 'taoensso.telemere.consoles) (:api (enc/interns-overview))) +;;;; Handlers + #?(:clj (defn ^:public handler:console - "Experimental, subject to change. + "Experimental, subject to change. Feedback welcome! Returns a (fn handler [signal]) that: - Takes a Telemere signal. - Writes a formatted signal string to stream. + A general-purpose `println`-style handler that's well suited for outputting + signals formatted as edn, JSON, or human-readable strings. + Options: `:format-signal-fn` - (fn [signal]) => output, see `help:signal-formatters` @@ -42,12 +48,15 @@ :cljs (defn ^:public handler:console - "Experimental, subject to change. + "Experimental, subject to change. Feedback welcome! If `js/console` exists, returns a (fn handler [signal]) that: - Takes a Telemere signal. - Writes a formatted signal string to JavaScript console. + A general-purpose `println`-style handler that's well suited for outputting + signals formatted as edn, JSON, or human-readable strings. + Options: `:format-signal-fn` - (fn [signal]) => output, see `help:signal-formatters`" @@ -77,7 +86,7 @@ #?(:cljs (defn ^:public handler:console-raw - "Experimental, subject to change. + "Experimental, subject to change. Feedback welcome! If `js/console` exists, returns a (fn handler [signal]) that: - Takes a Telemere signal. @@ -87,10 +96,10 @@ Ref. ." ([] (handler:console-raw nil)) - ([{:keys [format-signal-prelude-fn format-nsecs-fn] :as opts + ([{:keys [format-signal->prelude-fn format-nsecs-fn] :as opts :or - {format-signal-prelude-fn (utils/format-signal-prelude-fn) ; (fn [signal]) - format-nsecs-fn (utils/format-nsecs-fn) ; (fn [nanosecs]) + {format-signal->prelude-fn (utils/format-signal->prelude-fn) ; (fn [signal]) + format-nsecs-fn (utils/format-nsecs-fn) ; (fn [nanosecs]) }}] (when (and (exists? js/console) (exists? js/console.group)) @@ -108,7 +117,7 @@ logger (js-console-logger level)] ;; Unfortunately groups have no level - (.group js/console (format-signal-prelude-fn signal)) + (.group js/console (format-signal->prelude-fn signal)) (signal-content-handler signal (logger-fn logger) identity) (when-let [stack (and error (.-stack (enc/ex-root error)))] diff --git a/src/taoensso/telemere/file_handler.clj b/src/taoensso/telemere/files.clj similarity index 98% rename from src/taoensso/telemere/file_handler.clj rename to src/taoensso/telemere/files.clj index ad8dd23..50f9b10 100644 --- a/src/taoensso/telemere/file_handler.clj +++ b/src/taoensso/telemere/files.clj @@ -1,12 +1,13 @@ -(ns ^:no-doc taoensso.telemere.file-handler +(ns ^:no-doc taoensso.telemere.files "Private ns, implementation detail. - Core archiving file handler." + Core file handler, aliased in main Telemere ns." (:require [taoensso.encore :as enc :refer [have have?]] [taoensso.telemere.utils :as utils])) (comment - (remove-ns 'taoensso.telemere.file-handler) + (require '[taoensso.telemere :as tel]) + (remove-ns 'taoensso.telemere.files) (:api (enc/interns-overview))) ;;;; Implementation @@ -265,7 +266,7 @@ ;;;; Handler (defn ^:public handler:file - "Experimental, subject to change. + "Experimental, subject to change. Feedback welcome! Returns a (fn handler [signal]) that: - Takes a Telemere signal. diff --git a/src/taoensso/telemere/impl.cljc b/src/taoensso/telemere/impl.cljc index e479089..0dd223b 100644 --- a/src/taoensso/telemere/impl.cljc +++ b/src/taoensso/telemere/impl.cljc @@ -396,8 +396,8 @@ ;;;; Signal API helpers -#?(:clj (defmacro signal-docstring [rname] (enc/slurp-resource (str "signal-docstrings/" (name rname) ".txt")))) -#?(:clj (defmacro defhelp [sym rname] `(enc/def* ~sym {:doc ~(eval `(signal-docstring ~rname))} "See docstring"))) +#?(:clj (defmacro signal-docstring [ rname] (enc/slurp-resource (str "signal-docstrings/" (name rname) ".txt")))) +#?(:clj (defmacro defhelp [sym rname] `(enc/def* ~sym {:doc ~(eval `(signal-docstring ~rname))} "See docstring"))) #?(:clj (defn signal-arglists [macro-id] @@ -693,7 +693,7 @@ (and (not elide?) allow?)))) -;;;; Intake +;;;; Intakes #?(:clj (do @@ -722,6 +722,3 @@ (with-signal :raw :trap (test-fn msg)))] (= (force (get signal :msg_)) msg))))) - - - diff --git a/src/taoensso/telemere/open_telemetry.clj b/src/taoensso/telemere/open_telemetry.clj index c290891..b614307 100644 --- a/src/taoensso/telemere/open_telemetry.clj +++ b/src/taoensso/telemere/open_telemetry.clj @@ -1,9 +1,6 @@ (ns taoensso.telemere.open-telemetry - "Core OpenTelemetry handler and utils. - - Needs `OpenTelemetry Java`, + "OpenTelemetry handler using `opentelemetry-java`, Ref. ." - (:require [clojure.string :as str] [taoensso.encore :as enc :refer [have have?]] @@ -165,40 +162,53 @@ attrs-map)) -(defn get-default-logger-provider - "Experimental, subject to change!! Feedback very welcome! +(defn default-logger-provider + "Experimental, subject to change. Feedback welcome! + Returns `io.opentelemetry.api.logs.LoggerProvider` via: `AutoConfiguredOpenTelemetrySdk` when possible, or - `GlobalOpenTelemetry` otherwise." + `GlobalOpenTelemetry` otherwise. + + See the relevant `opentelemetry-java` docs for details." ^LoggerProvider [] (or + ;; Without Java agent (enc/compile-when io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk (enc/catching :common (let [builder (io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk/builder)] (.getSdkLoggerProvider (.getOpenTelemetrySdk (.build builder)))))) + ;; With Java agent (.getLogsBridge (GlobalOpenTelemetry/get)))) ;;;; Handler (defn handler:open-telemetry-logger - "Experimental, subject to change!! Feedback very welcome! + "Experimental, subject to change. Feedback welcome! + + Needs `opentelemetry-java`, + Ref. . Returns a (fn handler [signal]) that: - Takes a Telemere signal. - Emits signal content to the `io.opentelemetry.api.logs.Logger` - returned by given `io.opentelemetry.api.logs.LoggerProvider`." + returned by given `io.opentelemetry.api.logs.LoggerProvider`. + + Options: + `:logger-provider` - `io.opentelemetry.api.logs.LoggerProvider` + Defaults to the LoggerProvider returned by (default-logger-provider), + see that docstring for details." ([] (handler:open-telemetry-logger nil)) ([{:keys [^LoggerProvider logger-provider - attrs-key ; Advanced, undocumented + attrs-signal-key ; Advanced, undocumented ] :or - {logger-provider (get-default-logger-provider) - attrs-key :open-telemetry-attrs}}] + {logger-provider (default-logger-provider) + attrs-signal-key :open-telemetry/attrs}}] (let [] (fn a-handler:open-telemetry-logger @@ -208,7 +218,7 @@ logger (.get logger-provider (or ns "default")) severity (level->severity level) msg (force msg_) - attrs-map (signal->attrs-map attrs-key signal) + attrs-map (signal->attrs-map attrs-signal-key signal) attrs (as-attrs attrs-map)] (.emit @@ -217,5 +227,3 @@ (.setSeverity severity) (.setBody msg) (.setAllAttributes attrs))))))))) - - diff --git a/src/taoensso/telemere/streams.clj b/src/taoensso/telemere/streams.clj index c654ff9..eaeb0dc 100644 --- a/src/taoensso/telemere/streams.clj +++ b/src/taoensso/telemere/streams.clj @@ -85,7 +85,7 @@ (let [monitor (Object.)] (defn ^:public streams->reset! - "Experimental, subject to change without notice! + "Experimental, subject to change. Resets `System/out` and `System/err` to their original value (prior to any `streams->telemere!` call)." [] @@ -107,7 +107,7 @@ (boolean (or orig-out orig-err)))) (defn ^:public streams->telemere! - "Experimental, subject to change without notice! + "Experimental, subject to change. When given `out`, sets JVM's `System/out` to flush to Telemere signals with those opts. When given `err`, sets JVM's `System/err` to flush to Telemere signals with those opts. diff --git a/src/taoensso/telemere/utils.cljc b/src/taoensso/telemere/utils.cljc index ac3cc7e..e7309f0 100644 --- a/src/taoensso/telemere/utils.cljc +++ b/src/taoensso/telemere/utils.cljc @@ -46,7 +46,9 @@ (str x)) (str x))))) -(comment (format-id (str *ns*) ::id1)) +(comment + (format-id (str *ns*) ::id1) + (format-id nil ::id1)) ;;;; Public misc @@ -174,16 +176,20 @@ #?(:clj (defn file-writer - "Experimental, subject to change!! + "Experimental, subject to change. Feedback welcome! Opens the specified file and returns a stateful fn of 2 arities: [content] => Writes given content to file, or no-ops if closed. [] => Closes the writer. - Thread safe. Automatically creates file and parent dirs as necessary. - Writers MUST ALWAYS be manually closed after use! + Useful for basic handlers that write to a file, etc. + + Notes: + - Automatically creates file and parent dirs as necessary. + - Writer should be manually closed after use (with zero-arity call). + - Flushes after every write. + - Thread safe, locks on single file stream." - Useful for handlers that write to files, etc." [file append?] (let [file (writeable-file! file) stream_ (volatile! (file-stream file append?)) @@ -205,7 +211,7 @@ true) write-ba! - (fn [^bytes ba-content retrying?] + (fn [^bytes ba-content] (when-let [^java.io.FileOutputStream stream (.deref stream_)] (.write stream ba-content) (.flush stream) @@ -219,24 +225,23 @@ lock (Object.)] - (fn file-writer + (fn a-file-writer ([] (when (open?_) (locking lock (close!)))) ([content-or-action] - (case content-or-action ; Undocumented + (case content-or-action ; Undocumented, for dev/testing :writer/open? (open?_) - :writer/file file - :writer/stream (.deref stream_) :writer/reset! (locking lock (reset!)) + :writer/state {:file file, :stream (.deref stream_)} (when (open?_) (let [content content-or-action ba (.getBytes (str content) java.nio.charset.StandardCharsets/UTF_8)] (locking lock (try (file-exists!) - (write-ba! ba false) - (catch java.io.IOException _ + (write-ba! ba) + (catch java.io.IOException _ ; Retry once (reset!) - (write-ba! ba true)))))))))))) + (write-ba! ba)))))))))))) (comment (def fw1 (file-writer "test.txt" true)) (fw1 "x") (fw1)) @@ -304,17 +309,17 @@ (do (enc/ex-map (ex-info "Ex2" {:k2 "v2"} (ex-info "Ex1" {:k1 "v1"})))) (println (str "--\n" ((format-error-fn) (ex-info "Ex2" {:k2 "v2"} (ex-info "Ex1" {:k1 "v1"})))))) -(defn format-signal-prelude-fn +(defn format-signal->prelude-fn "Experimental, subject to change. Returns a (fn format [signal]) that: - Takes a Telemere signal. - Returns a formatted prelude string like: \"2024-03-26T11:14:51.806Z INFO EVENT Hostname taoensso.telemere(2,21) ::ev-id - msg\"" - ([] (format-signal-prelude-fn nil)) + ([] (format-signal->prelude-fn nil)) ([{:keys [format-inst-fn] :or {format-inst-fn (format-inst-fn)}}] - (fn format-signal-prelude [signal] + (fn format-signal->prelude [signal] (let [{:keys [inst level kind ns id msg_]} signal sb (enc/str-builder) s+spc (enc/sb-appender sb " ")] @@ -338,12 +343,12 @@ (when-let [msg (force msg_)] (s+spc "- " msg)) (str sb))))) -(comment ((format-signal-prelude-fn) (tel/with-signal (tel/event! ::ev-id)))) +(comment ((format-signal->prelude-fn) (tel/with-signal (tel/event! ::ev-id)))) (defn ^:no-doc signal-content-handler "Private, don't use. Returns a (fn handle [signal handle-fn value-fn]) for internal use. - Content equivalent to `format-signal-prelude-fn`." + Content equivalent to `format-signal->prelude-fn`." ([] (signal-content-handler nil)) ([{:keys [format-nsecs-fn format-error-fn raw-error?] :or @@ -435,12 +440,12 @@ - Takes a Telemere signal. - Returns a formatted string intended for text consoles, etc." ([] (format-signal->str-fn nil)) - ([{:keys [format-signal-prelude-fn + ([{:keys [format-signal->prelude-fn format-nsecs-fn format-error-fn] :or - {format-signal-prelude-fn (format-signal-prelude-fn) ; (fn [signal]) - format-nsecs-fn (format-nsecs-fn) ; (fn [nanosecs]) - format-error-fn (format-error-fn) ; (fn [error]) + {format-signal->prelude-fn (format-signal->prelude-fn) ; (fn [signal]) + format-nsecs-fn (format-nsecs-fn) ; (fn [nanosecs]) + format-error-fn (format-error-fn) ; (fn [error]) }}] (let [signal-content-handler ; (fn [signal hf vf] @@ -453,7 +458,7 @@ s+ (partial enc/sb-append sb) s++ (partial enc/sb-append sb (str newline " "))] - (when-let [ff format-signal-prelude-fn] (s+ (ff signal))) ; Prelude + (when-let [ff format-signal->prelude-fn] (s+ (ff signal))) ; Prelude (signal-content-handler signal s++ enc/pr-edn*) ; Content (str sb)))))) diff --git a/test/taoensso/telemere_tests.cljc b/test/taoensso/telemere_tests.cljc index 31a1a76..9140eee 100644 --- a/test/taoensso/telemere_tests.cljc +++ b/test/taoensso/telemere_tests.cljc @@ -14,7 +14,7 @@ #_[taoensso.telemere.streams :as streams] #?(:clj [taoensso.telemere.slf4j :as slf4j]) #?(:clj [taoensso.telemere.open-telemetry :as otel]) - #?(:clj [taoensso.telemere.file-handler :as fh]) + #?(:clj [taoensso.telemere.files :as files]) #?(:clj [clojure.tools.logging :as ctl]))) (comment @@ -626,7 +626,8 @@ (is (= (utils/format-level 8) "LEVEL:8")) (is (= (utils/format-id "foo.bar" :foo.bar/qux) "::qux")) - (is (= (utils/format-id "foo.baz" :foo.bar/qux) ":foo.bar/qux"))]) + (is (= (utils/format-id "foo.baz" :foo.bar/qux) ":foo.bar/qux")) + (is (= (utils/format-id nil :foo.bar/qux) ":foo.bar/qux"))]) (testing "error-signal?" [(is (= (utils/error-signal? {:error nil}) false)) @@ -670,7 +671,7 @@ :cljs " Root: cljs.core/ExceptionInfo - Ex1\n data: {:k1 \"v1\"}\n\nCaused: cljs.core/ExceptionInfo - Ex2\n data: {:k2 \"v2\"}\n\nRoot stack trace:\n"))) (let [sig (with-sig (tel/event! ::ev-id {:inst t0})) - prelude ((utils/format-signal-prelude-fn) sig)] ; "2024-06-09T21:15:20.170Z INFO EVENT taoensso.telemere-tests(592,35) ::ev-id" + prelude ((utils/format-signal->prelude-fn) sig)] ; "2024-06-09T21:15:20.170Z INFO EVENT taoensso.telemere-tests(592,35) ::ev-id" [(is (enc/str-starts-with? prelude "2024-06-09T21:15:20.170Z INFO EVENT")) (is (enc/str-ends-with? prelude "::ev-id")) (is (string? (re-find #"taoensso.telemere-tests\(\d+,\d+\)" prelude)))]) @@ -707,44 +708,44 @@ #?(:clj (deftest _file-names - [(is (= (fh/get-file-name "/logs/app.log" nil nil false) "/logs/app.log")) - (is (= (fh/get-file-name "/logs/app.log" nil nil true) "/logs/app.log")) - (is (= (fh/get-file-name "/logs/app.log" "ts" nil true) "/logs/app.log-ts")) - (is (= (fh/get-file-name "/logs/app.log" "ts" 1 false) "/logs/app.log-ts.1")) - (is (= (fh/get-file-name "/logs/app.log" "ts" 1 true) "/logs/app.log-ts.1.gz")) - (is (= (fh/get-file-name "/logs/app.log" nil 1 false) "/logs/app.log.1")) - (is (= (fh/get-file-name "/logs/app.log" nil 1 true) "/logs/app.log.1.gz"))])) + [(is (= (files/get-file-name "/logs/app.log" nil nil false) "/logs/app.log")) + (is (= (files/get-file-name "/logs/app.log" nil nil true) "/logs/app.log")) + (is (= (files/get-file-name "/logs/app.log" "ts" nil true) "/logs/app.log-ts")) + (is (= (files/get-file-name "/logs/app.log" "ts" 1 false) "/logs/app.log-ts.1")) + (is (= (files/get-file-name "/logs/app.log" "ts" 1 true) "/logs/app.log-ts.1.gz")) + (is (= (files/get-file-name "/logs/app.log" nil 1 false) "/logs/app.log.1")) + (is (= (files/get-file-name "/logs/app.log" nil 1 true) "/logs/app.log.1.gz"))])) #?(:clj (deftest _file-timestamps - [(is (= (fh/format-file-timestamp :daily (fh/udt->edy udt0)) "2024-06-09d")) - (is (= (fh/format-file-timestamp :weekly (fh/udt->edy udt0)) "2024-06-03w")) - (is (= (fh/format-file-timestamp :monthly (fh/udt->edy udt0)) "2024-06-01m"))])) + [(is (= (files/format-file-timestamp :daily (files/udt->edy udt0)) "2024-06-09d")) + (is (= (files/format-file-timestamp :weekly (files/udt->edy udt0)) "2024-06-03w")) + (is (= (files/format-file-timestamp :monthly (files/udt->edy udt0)) "2024-06-01m"))])) -(comment (fh/manage-test-files! :create)) +(comment (files/manage-test-files! :create)) #?(:clj (deftest _file-handling - [(is (boolean (fh/manage-test-files! :create))) + [(is (boolean (files/manage-test-files! :create))) (testing "`scan-files`" ;; Just checking basic counts here, should be sufficient - [(is (= (count (fh/scan-files "test/logs/app1.log" nil nil :sort)) 1) "1 main, 0 parts") - (is (= (count (fh/scan-files "test/logs/app1.log" :daily nil :sort)) 0) "0 stamped") - (is (= (count (fh/scan-files "test/logs/app2.log" nil nil :sort)) 6) "1 main, 5 parts (+gz)") - (is (= (count (fh/scan-files "test/logs/app3.log" nil nil :sort)) 6) "1 main, 5 parts (-gz") - (is (= (count (fh/scan-files "test/logs/app4.log" nil nil :sort)) 11) "1 main, 5 parts (+gz) + 5 parts (-gz)") - (is (= (count (fh/scan-files "test/logs/app5.log" nil nil :sort)) 1) "1 main, 0 unstamped") - (is (= (count (fh/scan-files "test/logs/app5.log" :daily nil :sort)) 5) "5 stamped") - (is (= (count (fh/scan-files "test/logs/app6.log" nil nil :sort)) 1) "1 main, 0 unstamped") - (is (= (count (fh/scan-files "test/logs/app6.log" :daily nil :sort)) 25) "5 stamped * 5 parts") - (is (= (count (fh/scan-files "test/logs/app6.log" :weekly nil :sort)) 5) "5 stamped")]) + [(is (= (count (files/scan-files "test/logs/app1.log" nil nil :sort)) 1) "1 main, 0 parts") + (is (= (count (files/scan-files "test/logs/app1.log" :daily nil :sort)) 0) "0 stamped") + (is (= (count (files/scan-files "test/logs/app2.log" nil nil :sort)) 6) "1 main, 5 parts (+gz)") + (is (= (count (files/scan-files "test/logs/app3.log" nil nil :sort)) 6) "1 main, 5 parts (-gz") + (is (= (count (files/scan-files "test/logs/app4.log" nil nil :sort)) 11) "1 main, 5 parts (+gz) + 5 parts (-gz)") + (is (= (count (files/scan-files "test/logs/app5.log" nil nil :sort)) 1) "1 main, 0 unstamped") + (is (= (count (files/scan-files "test/logs/app5.log" :daily nil :sort)) 5) "5 stamped") + (is (= (count (files/scan-files "test/logs/app6.log" nil nil :sort)) 1) "1 main, 0 unstamped") + (is (= (count (files/scan-files "test/logs/app6.log" :daily nil :sort)) 25) "5 stamped * 5 parts") + (is (= (count (files/scan-files "test/logs/app6.log" :weekly nil :sort)) 5) "5 stamped")]) (testing "`archive-main-file!`" - [(is (= (let [df (fh/debugger)] (fh/archive-main-file! "test/logs/app1.log" nil nil 2 :gz df) (df)) + [(is (= (let [df (files/debugger)] (files/archive-main-file! "test/logs/app1.log" nil nil 2 :gz df) (df)) [[:rename "test/logs/app1.log" "test/logs/app1.log.1.gz"]])) - (is (= (let [df (fh/debugger)] (fh/archive-main-file! "test/logs/app2.log" nil nil 2 :gz df) (df)) + (is (= (let [df (files/debugger)] (files/archive-main-file! "test/logs/app2.log" nil nil 2 :gz df) (df)) [[:delete "test/logs/app2.log.5.gz"] [:delete "test/logs/app2.log.4.gz"] [:delete "test/logs/app2.log.3.gz"] @@ -752,7 +753,7 @@ [:rename "test/logs/app2.log.1.gz" "test/logs/app2.log.2.gz"] [:rename "test/logs/app2.log" "test/logs/app2.log.1.gz"]])) - (is (= (let [df (fh/debugger)] (fh/archive-main-file! "test/logs/app3.log" nil nil 2 :gz df) (df)) + (is (= (let [df (files/debugger)] (files/archive-main-file! "test/logs/app3.log" nil nil 2 :gz df) (df)) [[:delete "test/logs/app3.log.5"] [:delete "test/logs/app3.log.4"] [:delete "test/logs/app3.log.3"] @@ -760,7 +761,7 @@ [:rename "test/logs/app3.log.1" "test/logs/app3.log.2"] [:rename "test/logs/app3.log" "test/logs/app3.log.1.gz"]])) - (is (= (let [df (fh/debugger)] (fh/archive-main-file! "test/logs/app6.log" :daily "2021-01-01d" 2 :gz df) (df)) + (is (= (let [df (files/debugger)] (files/archive-main-file! "test/logs/app6.log" :daily "2021-01-01d" 2 :gz df) (df)) [[:delete "test/logs/app6.log-2021-01-01d.5.gz"] [:delete "test/logs/app6.log-2021-01-01d.4.gz"] [:delete "test/logs/app6.log-2021-01-01d.3.gz"] @@ -769,15 +770,15 @@ [:rename "test/logs/app6.log" "test/logs/app6.log-2021-01-01d.1.gz"]]))]) (testing "`prune-archive-files!`" - [(is (= (let [df (fh/debugger)] (fh/prune-archive-files! "test/logs/app1.log" nil 2 df) (df)) [])) - (is (= (let [df (fh/debugger)] (fh/prune-archive-files! "test/logs/app2.log" nil 2 df) (df)) [])) - (is (= (let [df (fh/debugger)] (fh/prune-archive-files! "test/logs/app5.log" nil 2 df) (df)) [])) - (is (= (let [df (fh/debugger)] (fh/prune-archive-files! "test/logs/app5.log" :daily 2 df) (df)) + [(is (= (let [df (files/debugger)] (files/prune-archive-files! "test/logs/app1.log" nil 2 df) (df)) [])) + (is (= (let [df (files/debugger)] (files/prune-archive-files! "test/logs/app2.log" nil 2 df) (df)) [])) + (is (= (let [df (files/debugger)] (files/prune-archive-files! "test/logs/app5.log" nil 2 df) (df)) [])) + (is (= (let [df (files/debugger)] (files/prune-archive-files! "test/logs/app5.log" :daily 2 df) (df)) [[:delete "test/logs/app5.log-2020-01-01d"] [:delete "test/logs/app5.log-2020-01-02d"] [:delete "test/logs/app5.log-2020-02-01d"]])) - (is (= (let [df (fh/debugger)] (fh/prune-archive-files! "test/logs/app6.log" :daily 2 df) (df)) + (is (= (let [df (files/debugger)] (files/prune-archive-files! "test/logs/app6.log" :daily 2 df) (df)) [[:delete "test/logs/app6.log-2020-01-01d.5.gz"] [:delete "test/logs/app6.log-2020-01-01d.4.gz"] [:delete "test/logs/app6.log-2020-01-01d.3.gz"] @@ -798,7 +799,7 @@ "Prune oldest 3 intervals, with 5 parts each")]) - (is (boolean (fh/manage-test-files! :delete)))])) + (is (boolean (files/manage-test-files! :delete)))])) ;;;; Other handlers