Skip to content

Commit

Permalink
Add support for log4j2.
Browse files Browse the repository at this point in the history
Fixes TLOG-19.
  • Loading branch information
ataggart committed Jun 2, 2017
1 parent 9d752e2 commit 39b670b
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
@@ -1,6 +1,6 @@
# Logging

Logging macros which delegate to a specific logging implementation. At runtime a specific implementation is selected from, in order, slf4j, Apache commons-logging, log4j, and finally java.util.logging.
Logging macros which delegate to a specific logging implementation. At runtime a specific implementation is selected from, in order, slf4j, Apache commons-logging, log4j2, log4j, and finally java.util.logging.

Logging levels are specified by clojure keywords, in increasingly severe order:

Expand Down
12 changes: 12 additions & 0 deletions pom.xml
Expand Up @@ -42,6 +42,18 @@
<version>1.2.16</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
Expand Down
2 changes: 2 additions & 0 deletions project.clj
Expand Up @@ -9,4 +9,6 @@
:profiles {:test {:dependencies [[org.slf4j/slf4j-api "1.6.2"]
[org.slf4j/slf4j-log4j12 "1.6.2"]
[log4j "1.2.16"]
[org.apache.logging.log4j/log4j-api "2.8.2"]
[org.apache.logging.log4j/log4j-core "2.8.2"]
[commons-logging "1.1.1"]]}})
6 changes: 3 additions & 3 deletions src/main/clojure/clojure/tools/logging.clj
Expand Up @@ -12,10 +12,10 @@
;; remove this notice, or any other, from this software.
(ns ^{:author "Alex Taggart"
:doc "Logging macros which delegate to a specific logging implementation. At
runtime a specific implementation is selected from, in order, slf4j,
Apache commons-logging, log4j, and finally java.util.logging.
runtime a specific implementation is selected by invoking
clojure.tools.logging.impl/find-factory.
The logging implementation can be explicitly determined by using
The logging implementation can be explicitly provided by using
binding or alter-var-root to change the value of *logger-factory* to
another implementation of clojure.tools.logging.impl/LoggerFactory
(see also the *-factory functions in the impl namespace)."}
Expand Down
34 changes: 33 additions & 1 deletion src/main/clojure/clojure/tools/logging/impl.clj
Expand Up @@ -168,6 +168,37 @@
(org.apache.log4j.Logger/getLogger ^String (str logger-ns#))))))
(catch Exception e nil)))

(defn log4j2-factory
"Returns a Log4j2-based implementation of the LoggerFactory protocol, or nil if
not available."
[]
(try
(Class/forName "org.apache.logging.log4j.Logger")
(eval
`(let [levels# {:trace org.apache.logging.log4j.Level/TRACE
:debug org.apache.logging.log4j.Level/DEBUG
:info org.apache.logging.log4j.Level/INFO
:warn org.apache.logging.log4j.Level/WARN
:error org.apache.logging.log4j.Level/ERROR
:fatal org.apache.logging.log4j.Level/FATAL}]
(extend org.apache.logging.log4j.Logger
Logger
{:enabled?
(fn [^org.apache.logging.log4j.Logger logger# level#]
(.isEnabled logger# (get levels# level# level#)))
:write!
(fn [^org.apache.logging.log4j.Logger logger# level# e# msg#]
(let [level# (get levels# level# level#)]
(if e#
(.log logger# level# msg# e#)
(.log logger# level# msg#))))})
(reify LoggerFactory
(name [_#]
"org.apache.logging.log4j")
(get-logger [_# logger-ns#]
(org.apache.logging.log4j.LogManager/getLogger ^String (str logger-ns#))))))
(catch Exception e nil)))

(defn jul-factory
"Returns a java.util.logging-based implementation of the LoggerFactory protocol,
or nil if not available."
Expand Down Expand Up @@ -202,10 +233,11 @@

(defn find-factory
"Returns the first non-nil value from slf4j-factory, cl-factory,
log4j-factory, and jul-factory."
log4j2-factory, log4j-factory, and jul-factory."
[]
(or (slf4j-factory)
(cl-factory)
(log4j2-factory)
(log4j-factory)
(jul-factory)
(throw ; this should never happen in 1.5+
Expand Down
22 changes: 19 additions & 3 deletions src/test/clojure/clojure/tools/logging/test_impl.clj
Expand Up @@ -2,8 +2,20 @@
(:use clojure.test)
(:require [clojure.tools.logging.impl :as impl]))

(def logger-factories [(impl/slf4j-factory)
(let [[factory level] (try
[(impl/log4j2-factory) (eval 'org.apache.logging.log4j.Level/FATAL)]
(catch UnsupportedClassVersionError _
; This will happen when not using a 1.7+ jvm, e.g.,
; during matrix testing. Use the no-op factory
; to get past testing log4j2.
[impl/disabled-logger-factory nil]))]
(def maybe-log4j2-factory factory)
(def maybe-log4j2-level level))

(def logger-factories [impl/disabled-logger-factory
(impl/slf4j-factory)
(impl/cl-factory)
maybe-log4j2-factory
(impl/log4j-factory)
(impl/jul-factory)])

Expand All @@ -18,13 +30,17 @@
(deftest test-enabled-non-kw-levels
; Just checking that the call doesn't blow up.
(are [lf level] (let [logger (impl/get-logger lf "logger-ns")]
(impl/enabled? logger level))
(impl/enabled? logger level)
true)
maybe-log4j2-factory maybe-log4j2-level
(impl/log4j-factory) org.apache.log4j.Level/FATAL
(impl/jul-factory) java.util.logging.Level/SEVERE))

(deftest test-write-non-kw-levels
; Just checking that the call doesn't blow up.
(are [lf level] (let [logger (impl/get-logger lf "logger-ns")]
(nil? (impl/write! logger level nil "message")))
(impl/write! logger level nil "message")
true)
maybe-log4j2-factory maybe-log4j2-level
(impl/log4j-factory) org.apache.log4j.Level/FATAL
(impl/jul-factory) java.util.logging.Level/SEVERE))
13 changes: 13 additions & 0 deletions src/test/clojure/log4j2.xml
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p %c: %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="fatal">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>

0 comments on commit 39b670b

Please sign in to comment.