Search code examples
javaunix-socket

Read data directly from /dev/log Unix Domain Socket


My project aims at reading log messages directly from /dev/log UNIX domain socket in Java. Currently I am using junixsocket. Below is a sample code of client that reads from a unix socket.

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.newsclub.net.unix.AFUNIXSocket;
import org.newsclub.net.unix.AFUNIXSocketAddress;
import org.newsclub.net.unix.AFUNIXSocketException;

public class SimpleTestClient {
    public static void main(String[] args) throws IOException {
        final File socketFile = new File("/dev/log");

        AFUNIXSocket sock = AFUNIXSocket.newInstance();
        try {
            sock.connect(new AFUNIXSocketAddress(socketFile));
        } catch (AFUNIXSocketException e) {
            System.out.println("Cannot connect to server. Have you started it?\n");
            System.out.flush();
            throw e;
        }
        System.out.println("Connected");

        InputStream is = sock.getInputStream();

        byte[] buf = new byte[8192];

        int read = is.read(buf);
        System.out.println("Server says: " + new String(buf, 0, read));
    
        is.close();

        sock.close();

        System.out.println("End of communication.");
    }
}

The above mentioned code is unable to connect to /dev/log. It throws an exception:

Cannot connect to server. Have you started it?
Exception in thread "main" org.newsclub.net.unix.AFUNIXSocketException: Protocol wrong type for socket (socket: /dev/log)
        at org.newsclub.net.unix.NativeUnixSocket.connect(Native Method)
        at org.newsclub.net.unix.AFUNIXSocketImpl.connect(AFUNIXSocketImpl.java:125)
        at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:97)
        at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:87)
        at SimpleTestClient.main(SimpleTestClient.java:40)

I am unable to figure out how to solve this problem. Any help would be appreciable.


Solution

  • Since you cannot connect to an existing server socket as mentioned in the log traces, then you haven't bound one one the mentioned file, so try creating an AF_UNIX server socket then connect to it.

    It could be done in a separate class:

    public class DevLogServer {
    
      public static void main(String[] args) throws IOException {
    
        final File socketFile = new File("/dev/log");
        AFUNIXServerSocket server = AFUNIXServerSocket.newInstance();
        try {
          server.bind(new AFUNIXSocketAddress(socketFile));
        } catch (Exception e) {
          throw e;
        }
    
      }
    
    }
    

    Edit as per @Ankit comment:

    You may also need to make sure the syslod daemon is stopped by runnig below command in a terminal window:

    sudo service syslog stop
    

    You may alternatively need to grand write permission to the /dev directory.