diff --git a/integration_tests/emitter-slf4j17-java/project.clj b/integration_tests/emitter-slf4j17-java/project.clj new file mode 100644 index 0000000..761d813 --- /dev/null +++ b/integration_tests/emitter-slf4j17-java/project.clj @@ -0,0 +1,4 @@ +(defproject emitter-slf4j17-java "0.1.0-SNAPSHOT" + :dependencies [[org.slf4j/slf4j-api "1.7.36"]] + :java-source-paths ["src/java"] + :source-paths []) diff --git a/integration_tests/emitter-slf4j17-java/src/java/com/example/Slf4j17JavaEmitter.java b/integration_tests/emitter-slf4j17-java/src/java/com/example/Slf4j17JavaEmitter.java new file mode 100644 index 0000000..bc74d10 --- /dev/null +++ b/integration_tests/emitter-slf4j17-java/src/java/com/example/Slf4j17JavaEmitter.java @@ -0,0 +1,16 @@ +package com.example; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.lang.invoke.MethodHandles; + +public class Slf4j17JavaEmitter { + final static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static void emit() { + logger.error("Hello from SLF4J 1.7 (Java)"); + logger.warn("Hello from SLF4J 1.7 (Java)"); + logger.info("Hello from SLF4J 1.7 (Java)"); + logger.debug("Hello from SLF4J 1.7 (Java)"); + logger.trace("Hello from SLF4J 1.7 (Java)"); + } +} diff --git a/integration_tests/emitter-slf4j17/project.clj b/integration_tests/emitter-slf4j17/project.clj new file mode 100644 index 0000000..a1d027b --- /dev/null +++ b/integration_tests/emitter-slf4j17/project.clj @@ -0,0 +1,4 @@ +(defproject emitter-slf4j17 "0.1.0-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.11.1"] + [org.slf4j/slf4j-api "1.7.36"]] + :aot [emitter-slf4j17.core]) diff --git a/integration_tests/emitter-slf4j17/src/emitter_slf4j17/core.clj b/integration_tests/emitter-slf4j17/src/emitter_slf4j17/core.clj new file mode 100644 index 0000000..e5e5ac5 --- /dev/null +++ b/integration_tests/emitter-slf4j17/src/emitter_slf4j17/core.clj @@ -0,0 +1,13 @@ +(ns emitter-slf4j17.core + (:import org.slf4j.LoggerFactory) + (:gen-class + :name com.example.Slf4j17Emitter + :methods [^:static [emit [] void]])) + +(defn -emit [] + (let [logger (LoggerFactory/getLogger (str *ns*))] + (.error logger "Hello from SLF4J 1.7") + (.warn logger "Hello from SLF4J 1.7") + (.info logger "Hello from SLF4J 1.7") + (.debug logger "Hello from SLF4J 1.7") + (.trace logger "Hello from SLF4J 1.7"))) diff --git a/integration_tests/emitter-slf4j20-java/project.clj b/integration_tests/emitter-slf4j20-java/project.clj new file mode 100644 index 0000000..8da72fd --- /dev/null +++ b/integration_tests/emitter-slf4j20-java/project.clj @@ -0,0 +1,4 @@ +(defproject emitter-slf4j20-java "0.1.0-SNAPSHOT" + :dependencies [[org.slf4j/slf4j-api "2.0.7"]] + :java-source-paths ["src/java"] + :source-paths []) diff --git a/integration_tests/emitter-slf4j20-java/src/java/com/example/Slf4j20JavaEmitter.java b/integration_tests/emitter-slf4j20-java/src/java/com/example/Slf4j20JavaEmitter.java new file mode 100644 index 0000000..3b8930f --- /dev/null +++ b/integration_tests/emitter-slf4j20-java/src/java/com/example/Slf4j20JavaEmitter.java @@ -0,0 +1,16 @@ +package com.example; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.lang.invoke.MethodHandles; + +public class Slf4j20JavaEmitter { + final static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static void emit() { + logger.error("Hello from SLF4J 2.0 (Java)"); + logger.warn("Hello from SLF4J 2.0 (Java)"); + logger.info("Hello from SLF4J 2.0 (Java)"); + logger.debug("Hello from SLF4J 2.0 (Java)"); + logger.trace("Hello from SLF4J 2.0 (Java)"); + } +} diff --git a/integration_tests/emitter-slf4j20/project.clj b/integration_tests/emitter-slf4j20/project.clj new file mode 100644 index 0000000..1602983 --- /dev/null +++ b/integration_tests/emitter-slf4j20/project.clj @@ -0,0 +1,4 @@ +(defproject emitter-slf4j20 "0.1.0-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.11.1"] + [org.slf4j/slf4j-api "2.0.7"]] + :aot [emitter-slf4j20.core]) diff --git a/integration_tests/emitter-slf4j20/src/emitter_slf4j20/core.clj b/integration_tests/emitter-slf4j20/src/emitter_slf4j20/core.clj new file mode 100644 index 0000000..f9f640e --- /dev/null +++ b/integration_tests/emitter-slf4j20/src/emitter_slf4j20/core.clj @@ -0,0 +1,13 @@ +(ns emitter-slf4j20.core + (:import org.slf4j.LoggerFactory) + (:gen-class + :name com.example.Slf4j20Emitter + :methods [^:static [emit [] void]])) + +(defn -emit [] + (let [logger (LoggerFactory/getLogger (str *ns*))] + (.error logger "Hello from SLF4J 2.0") + (.warn logger "Hello from SLF4J 2.0") + (.info logger "Hello from SLF4J 2.0") + (.debug logger "Hello from SLF4J 2.0") + (.trace logger "Hello from SLF4J 2.0"))) diff --git a/integration_tests/timbre5/project.clj b/integration_tests/timbre5/project.clj deleted file mode 100644 index e90c115..0000000 --- a/integration_tests/timbre5/project.clj +++ /dev/null @@ -1,8 +0,0 @@ -(defproject example "1.0.0" - :dependencies [[org.clojure/clojure "1.11.1"] - [com.taoensso/timbre "5.2.1"] - [org.slf4j/slf4j-api "1.7.36"] - ; slf4j-timbre will be added here by lein update-in - ] - :main example.core - :aot [example.core]) \ No newline at end of file diff --git a/integration_tests/timbre5/src/example/core.clj b/integration_tests/timbre5/src/example/core.clj deleted file mode 100644 index bccb643..0000000 --- a/integration_tests/timbre5/src/example/core.clj +++ /dev/null @@ -1,18 +0,0 @@ -(ns example.core - (:require [taoensso.timbre :as timbre]) - (:import org.slf4j.LoggerFactory) - (:gen-class)) - -(defn -main - [& _] - (timbre/error "Hello from Timbre") - (timbre/warn "Hello from Timbre") - (timbre/info "Hello from Timbre") - (timbre/debug "Hello from Timbre") - (timbre/trace "Hello from Timbre") - (let [logger (LoggerFactory/getLogger (str *ns*))] - (.error logger "Hello from SLF4J") - (.warn logger "Hello from SLF4J") - (.info logger "Hello from SLF4J") - (.debug logger "Hello from SLF4J") - (.trace logger "Hello from SLF4J"))) \ No newline at end of file diff --git a/integration_tests/timbre6/project.clj b/integration_tests/timbre6/project.clj new file mode 100644 index 0000000..d095ac8 --- /dev/null +++ b/integration_tests/timbre6/project.clj @@ -0,0 +1,11 @@ +(defproject timbre6 "0.1.0-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.11.1"] + [com.taoensso/timbre "6.1.0"] + [emitter-slf4j17 "0.1.0-SNAPSHOT"] + [emitter-slf4j17-java "0.1.0-SNAPSHOT"] + [emitter-slf4j20 "0.1.0-SNAPSHOT"] + [emitter-slf4j20-java "0.1.0-SNAPSHOT"] + ; slf4j-timbre will be added here by lein update-in + ] + :main timbre6.core + :aot [timbre6.core]) diff --git a/integration_tests/timbre6/src/timbre6/core.clj b/integration_tests/timbre6/src/timbre6/core.clj new file mode 100644 index 0000000..fcf4db1 --- /dev/null +++ b/integration_tests/timbre6/src/timbre6/core.clj @@ -0,0 +1,18 @@ +(ns timbre6.core + (:require [taoensso.timbre :as timbre]) + (:import [com.example Slf4j17Emitter Slf4j17JavaEmitter Slf4j20Emitter Slf4j20JavaEmitter])) + +(defn ^:private emit [] + (timbre/error "Hello from Timbre") + (timbre/warn "Hello from Timbre") + (timbre/info "Hello from Timbre") + (timbre/debug "Hello from Timbre") + (timbre/trace "Hello from Timbre")) + +(defn -main + [& _] + (emit) + (Slf4j17Emitter/emit) + (Slf4j17JavaEmitter/emit) + (Slf4j20Emitter/emit) + (Slf4j20JavaEmitter/emit)) diff --git a/project.clj b/project.clj index 86679b1..e7ddfb6 100644 --- a/project.clj +++ b/project.clj @@ -4,23 +4,27 @@ :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.11.1"] - [com.taoensso/timbre "5.2.1"] - [org.slf4j/slf4j-api "1.7.36"]] + [com.taoensso/timbre "6.1.0"] + [org.slf4j/slf4j-api "2.0.7"]] :profiles {:dev - {:dependencies [[midje "1.10.5"]] + {:dependencies [[midje "1.10.9"]] :plugins [[lein-midje "3.2.2"] [lein-sub "0.3.0"] [day8/lein-git-inject "0.0.15"]] - :sub ["integration_tests/timbre5"] - :aliases {"run-integration-tests" ["sub" "do" "clean," "deps," - "update-in" ":dependencies" "conj" "[com.fzakaria/slf4j-timbre \"lein-git-inject/version\"]" "--" "run"]}}} + :sub ["integration_tests/emitter-slf4j17" + "integration_tests/emitter-slf4j17-java" + "integration_tests/emitter-slf4j20" + "integration_tests/emitter-slf4j20-java"] + :aliases {"run-integration-tests" ["do" "sub" "install," + "sub" "-s" "integration_tests/timbre6" "update-in" ":dependencies" "conj" "[com.fzakaria/slf4j-timbre \"lein-git-inject/version\"]" "--" "run"]}}} :middleware [leiningen.git-inject/middleware] :git-inject {:version-pattern #"^(\d+\.\d+\.\d+)$"} :aot [slf4j-timbre.adapter slf4j-timbre.factory slf4j-timbre.static-logger-binder slf4j-timbre.static-marker-binder - slf4j-timbre.static-mdc-binder] + slf4j-timbre.static-mdc-binder + slf4j-timbre.service-provider] :jar-exclusions [#"\.class$"] :jar-inclusions [#"slf4j.*\.class$"] :release-tasks [["vcs" "assert-committed"] diff --git a/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000..113d4e3 --- /dev/null +++ b/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +com.github.fzakaria.slf4j.timbre.TimbreServiceProvider \ No newline at end of file diff --git a/src/slf4j_timbre/service_provider.clj b/src/slf4j_timbre/service_provider.clj new file mode 100644 index 0000000..5f12711 --- /dev/null +++ b/src/slf4j_timbre/service_provider.clj @@ -0,0 +1,32 @@ +(ns slf4j-timbre.service-provider + (:gen-class :name com.github.fzakaria.slf4j.timbre.TimbreServiceProvider + :implements [org.slf4j.spi.SLF4JServiceProvider] + :state state + :init init) + (:import (com.github.fzakaria.slf4j.timbre TimbreLoggerFactory TimbreServiceProvider) + (org.slf4j.helpers NOPMDCAdapter BasicMarkerFactory))) + +(defn -init [] + [[] (atom {})]) + +(defn -initialize + [^TimbreServiceProvider this] + (reset! (.state this) + {:logger-factory (TimbreLoggerFactory.) + :marker-factory (BasicMarkerFactory.) + :mdc-adapter (NOPMDCAdapter.)})) + +(defn -getLoggerFactory + [^TimbreServiceProvider this] + (:logger-factory @(.state this))) + +(defn -getMarkerFactory + [^TimbreServiceProvider this] + (:marker-factory @(.state this))) + +(defn -getMDCAdapter + [^TimbreServiceProvider this] + (:mdc-adapter @(.state this))) + +(defn -getRequestedApiVersion [_] + "2.0.99") \ No newline at end of file diff --git a/test/slf4j_timbre/t_adapter.clj b/test/slf4j_timbre/t_adapter.clj index 058e61f..af0ad25 100644 --- a/test/slf4j_timbre/t_adapter.clj +++ b/test/slf4j_timbre/t_adapter.clj @@ -15,7 +15,7 @@ `(~m ~@args ~@args-rest))))) (defn invoke-each-lal - [logger marker fqcn message arg-array t] + [^LocationAwareLogger logger marker fqcn message arg-array t] (dorun (for [level [LocationAwareLogger/ERROR_INT LocationAwareLogger/WARN_INT LocationAwareLogger/INFO_INT LocationAwareLogger/DEBUG_INT LocationAwareLogger/TRACE_INT]] (.log logger marker fqcn level message arg-array t)))) diff --git a/test/slf4j_timbre/t_service_provider.clj b/test/slf4j_timbre/t_service_provider.clj new file mode 100644 index 0000000..fd70a27 --- /dev/null +++ b/test/slf4j_timbre/t_service_provider.clj @@ -0,0 +1,30 @@ +(ns slf4j-timbre.t-service-provider + (:use midje.sweet) + (:import (com.github.fzakaria.slf4j.timbre TimbreServiceProvider))) + +(let + [provider (doto (TimbreServiceProvider.) .initialize) + logger-factory-a (.getLoggerFactory provider) + logger-factory-b (.getLoggerFactory provider) + marker-factory-a (.getMarkerFactory provider) + marker-factory-b (.getMarkerFactory provider) + mdc-adapter-a (.getMDCAdapter provider) + mdc-adapter-b (.getMDCAdapter provider)] + + (fact "provider returns a logger factory" + (nil? logger-factory-a) => false) + + (fact "provider returns same logger factory each time" + (= logger-factory-a logger-factory-b) => true) + + (fact "provider returns a marker factory" + (nil? marker-factory-a) => false) + + (fact "provider returns same marker factory each time" + (= marker-factory-a marker-factory-b) => true) + + (fact "provider returns an MDC adapter" + (nil? mdc-adapter-a) => false) + + (fact "provider returns same MDC adapter each time" + (= mdc-adapter-a mdc-adapter-b) => true)) \ No newline at end of file