1

I am using the Socket Appender of Log4j2 to write logs to a remote server. It was working fine when I was writing from a spring boot application. After I containerized this app with docker and run as a docker container, it gives the following errors. What is the proper was to write to a remote server from a docker container?

Errors

kabilesh@kabilesh-Latitude-E6540:~/IdeaProjects/SpringResearch$ docker run -p 8080:8080 springappnew
2019-06-21 10:39:50,796 main ERROR TcpSocketManager (TCP:127.0.0.1:8000) java.net.ConnectException: Connection refused (Connection refused) java.net.ConnectException: Connection refused (Connection refused)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createSocket(TcpSocketManager.java:423)
        at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createManager(TcpSocketManager.java:404)
        at org.apache.logging.log4j.core.net.TcpSocketManager$TcpSocketManagerFactory.createManager(TcpSocketManager.java:387)
        at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
        at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
        at org.apache.logging.log4j.core.net.TcpSocketManager.getSocketManager(TcpSocketManager.java:201)
        at org.apache.logging.log4j.core.appender.SocketAppender.createSocketManager(SocketAppender.java:430)
        at org.apache.logging.log4j.core.appender.SocketAppender$Builder.build(SocketAppender.java:215)
        at org.apache.logging.log4j.core.appender.SocketAppender$Builder.build(SocketAppender.java:190)
        at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:952)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:892)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:884)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:508)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:232)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:244)
        at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
        at org.apache.commons.logging.LogFactory$Log4jLog.<clinit>(LogFactory.java:199)
        at org.apache.commons.logging.LogFactory$Log4jDelegate.createLog(LogFactory.java:166)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:109)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:99)
        at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:189)
        at com.springResearch.SpringRoot.main(SpringRoot.java:9)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

2019-06-21 10:39:51,396 Log4j2-TF-1-AsyncLoggerConfig-1 ERROR Unable to write to stream TCP:127.0.0.1:8000 for appender socket: org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:8000 socket not available
2019-06-21 10:39:51,398 Log4j2-TF-1-AsyncLoggerConfig-1 ERROR An exception occurred processing Appender socket org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:8000 socket not available
        at org.apache.logging.log4j.core.net.TcpSocketManager.write(TcpSocketManager.java:213)
        at org.apache.logging.log4j.core.appender.OutputStreamManager.write(OutputStreamManager.java:201)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.writeByteArrayToManager(AbstractOutputStreamAppender.java:186)
        at org.apache.logging.log4j.core.appender.SocketAppender.directEncodeEvent(SocketAppender.java:446)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161)
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:448)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfig.asyncCallAppenders(AsyncLoggerConfig.java:115)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:112)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:98)
        at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:129)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)

2019-06-21 10:39:51,616 Log4j2-TF-1-AsyncLoggerConfig-1 ERROR Unable to write to stream TCP:127.0.0.1:8000 for appender socket: org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:8000 socket not available
2019-06-21 10:39:51,617 Log4j2-TF-1-AsyncLoggerConfig-1 ERROR An exception occurred processing Appender socket org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:127.0.0.1:8000 socket not available
        at org.apache.logging.log4j.core.net.TcpSocketManager.write(TcpSocketManager.java:213)
        at org.apache.logging.log4j.core.appender.OutputStreamManager.write(OutputStreamManager.java:201)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.writeByteArrayToManager(AbstractOutputStreamAppender.java:186)
        at org.apache.logging.log4j.core.appender.SocketAppender.directEncodeEvent(SocketAppender.java:446)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161)
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:448)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfig.asyncCallAppenders(AsyncLoggerConfig.java:115)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:112)
        at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor.java:98)
        at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:129)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

2019-06-21 10:39:53.884  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-06-21 10:39:53.886  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.34
2019-06-21 10:39:53.905  INFO 1 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib]
2019-06-21 10:39:54.013  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext

In Client app

log4j2.xml (log4j2 configurations)

<Configuration status="warn" name="SpringResearch" packages="com.springResearch">
    <Appenders>
        <Socket name="socket" host="127.0.0.1" port="8000">
            <SerializedLayout />
        </Socket>
    </Appenders>

    <Loggers>
        <AsyncRoot level="info">
            <AppenderRef ref="socket"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

Dockerfile

FROM java:8
EXPOSE 8080
ADD /target/SpringResearch-1.0-SNAPSHOT.jar SpringResearch-1.0-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "SpringResearch-1.0-SNAPSHOT.jar"]

I run the docker container as

docker run -p 8080:8080 springappnew

I use this - https://github.com/piruin/log4j2-socket-server as the app that listens to the socket appender. This is listening on localhost : port 8000

In log server app

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="SocketServerLog" monitorInterval="30">
  <Appenders>
    <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/info.log"
                 filePattern="logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
        <SizeBasedTriggeringPolicy size="25 MB"/>
      </Policies>
    </RollingRandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="RollingRandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>
Bharti Rawat
  • 1,949
  • 21
  • 32
Kabilesh
  • 1,000
  • 6
  • 22
  • 47
  • 1
    I would suggest you read a basic introduction to containers, what they are and how they work. The fact that you have used the loopback address and expect the container to be able to access your local machine shows a fundamental misunderstanding of what is going on. It is not productive to proceed until you have a better understanding of the basics. – Boris the Spider Jun 21 '19 at 05:52
  • Sure, I will look into those. – Kabilesh Jun 21 '19 at 05:58

2 Answers2

2

Normally, you don't run the server in the same docker container as the application. Therefore I assume that 127.0.0.1 is not correct, since this is the local docker container. You have to put the correct name or ip, probably the name of the docker host.

jokster
  • 577
  • 5
  • 14
  • 2
    The name of the docker host doesn't help you here. To access the host machine you need to use the special name `host.docker.internal`. – Boris the Spider Jun 21 '19 at 05:54
2

As @jokster mentioned localhost (127.0.0.1) should be replaced with the IP of the host known inside the container. You could use the following on the host to get it:

 ip r s 0/0 | awk '{print $3}

Then pass the IP as an environment variable to the container and use it in the log4j.xml configuration file. Refer to Environment Lookup in log4j docs

As of Docker v18.03+ it seems that one can use host.docker.internal hostname

More info:

Get Your Docker Host's IP Address from in a Container

How to get the IP address of the docker host from inside a docker container

Connect to a Database Running on Your Docker Host

Hope that helps.

b0gusb
  • 4,283
  • 2
  • 14
  • 33