How to make log messages display in remote REPL?

I have web app that uses logback + clojure.tools.logging for logging.

In development, if I run (log/warn "foo") then foo would display in the REPL as well as getting appended to the log file. However, if I connect to the production app with a remote REPL, then when I run (log/warn "foo) I see foo is appended to the log file but not displayed in the REPL.

Is there a way to make it so that log messages are displayed in my REPL window when I connect to the production app with a remote REPL?

At first I thought the problem was with my logback.xml configuration, but I’m experiencing this even when I use the exact same logback.xml for dev and prod.

Thanks in advance for any advice!

Here’s my logback.xml in case it’s relevant.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>log/web-app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/web-app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- keep 30 days of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern>
        </encoder>
    </appender>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <charset>UTF-8</charset>
            <pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern>
        </encoder>
    </appender>
    <logger name="org.apache.http" level="warn" />
    <logger name="org.xnio.nio" level="warn" />
    <logger name="io.undertow.websockets.core.request" level="warn" />
    <logger name="io.undertow.request" level="warn" />
    <logger name="io.undertow.session" level="warn" />
    <logger name="io.undertow.request" level="warn" />
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

As I understand REPL overrides *out* in order to grab output from remote application.
But logback writes to System.out which REPL does not touch.

I would try to override System.out with a buffer, capture some logs and print them to the REPL, which should be displayed locally

(let [original-out System/out
      baos (java.io.ByteArrayOutputStream.)]
  (System/setOut (java.io.PrintStream. baos true "UTF-8"))
  (try

    ;; call some code that prints logs
    (log/warn "foo")

    (finally
      (System/setOut original-out)
      (print (str baos)))))

Thank you! This is what I didn’t understand.

My ideal situation would be that I can use the same logging functions in local development and production, and that when I REPL into the production machine I can see the log messages in my REPL.

I think what I’ll do is wrap the clojure.tools.logging warn etc functions with versions that println as well as the usual log.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.