-
-
Notifications
You must be signed in to change notification settings - Fork 648
Description
Expected behavior
When logging with clojure.tools.logging
with log4j2
backend set via relevant clojure.tools.logging.imlp
factory I expect log messages both in NREPL and in REPL buffer. Note that we have cider-redirect-server-output-to-repl
set to true and cider-nrepl loadded.
Actual behavior
Log messages turn up in the NREPL only buffer, but not in REPL
Potentially related tickets:
#524
#2138
but note that server output redirection to repl is set and works perfectly fine with e.g. logback backend.
Steps to reproduce the problem
With the following settings in your project.clj
or similar in deps.edn
:
Dependencies
[org.clojure/tools.logging "1.2.4"]
[org.apache.logging.log4j/log4j-api "2.18.0"]
[org.apache.logging.log4j/log4j-core "2.18.0"]
[org.apache.logging.log4j/log4j-1.2-api "2.18.0"]
[org.apache.logging.log4j/log4j-jcl "2.18.0"]
[org.apache.logging.log4j/log4j-jul "2.18.0"]
[org.apache.logging.log4j/log4j-slf4j-impl "2.18.0"]
JVM options that set the backend
:jvm-opts ["-Dlog4j2.configurationFile=log4j2.xml"
"-Dclojure.tools.logging.factory=clojure.tools.logging.impl/log4j2-factory"]
Some simple config log4j2.xml
in your classpath
Use below or e.g. this .properties example provided by clojure.tools.logging.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="5">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%date %level %logger %message%n%throwable"/>
<!-- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> -->
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Jack in as usual and try this code:
(ns user (:require [clojure.tools.logging :as log]))
;; these will register in NREPL buffer but not your repl
(log/error "foo")
(log/info "foo")
;; confirm your setup was pulled in
(System/getProperty "log4j2.configurationFile")
(System/getProperty "clojure.tools.logging.factory")
(.name (clojure.tools.logging.impl/log4j2-factory))
(.name log/*logger-factory*)
(.toString
(.getConfiguration
(.getContext
(clojure.tools.logging.impl/get-logger
log/*logger-factory*
*ns*))))
(.getState
(.getConfiguration
(.getContext
(clojure.tools.logging.impl/get-logger
log/*logger-factory*
*ns*))))
Fun observation and experiments that may help
Our log4j2 setup above rescans itself for changes every 5 seconds. If you do in fact change that xml config you'll notice that those log messages will now appear in REPL as you'd expect. Because in prod when deployed logs will end up in STDOUT and we're only having trouble with our dev setup, I thought I'd be clever and trigger reloading our logger from e.g. user.clj
with this:
(.stop
(.getConfiguration
(.getContext
(clojure.tools.logging.impl/get-logger
log/*logger-factory*
*ns*))))
(.reconfigure
(.getContext
(clojure.tools.logging.impl/get-logger
log/*logger-factory*
*ns*)))
It does in fact fixes the problem and message start logging in the REPL buffer. It has fun consequences however: killing the REPL will kill Emacs. What fun :)
Environment & Version information
CIDER version information
;; Connected to nREPL server - nrepl://localhost:52598
;; CIDER 1.4.0 (Kyiv), nREPL 0.9.0
;; Clojure 1.11.1, Java 18.0.1
Lein / Clojure CLI version
Leiningen 2.9.8 on Java 18.0.1 OpenJDK 64-Bit Server VM
Emacs version
GNU Emacs 28.1 (build 2, x86_64-apple-darwin21.4.0, NS appkit-2113.40 Version 12.3.1 (Build 21E258)) of 2022-05-09
Operating system
Mac OS Monterey 12.3.1