Skip to main content
2 of 3
added 68 characters in body

is this thread safe?

I am using this code for receiving log messages from my clients I receive more than 1000 connections per minute. I want to increase my log handling. I did with java threading. I have a doubt if it receive multiple client connection what happens. Is this thread safe? Can you give your suggestions. It will help to improve this code.

public class CentralizedLogging implements Runnable {

    /**
    * Field logDir - Where the plugin logs can be stored .
    */
    public static String logDir;
    /**
    * Field server - Server Socket .
    */
    ServerSocket server = null;
    /**
    * Field LOGGER.
    */
    public static final Logger LOGGER = Logger.getLogger(CentralizedLogging.class.getName());

    /**
    * @param port - Port which the server is binds .
    * @param logDir String
    */
    public CentralizedLogging(String logDir, int port) {
        try {
            this.logDir = logDir;
            server = new ServerSocket(port);
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "It may be due to given port already binds with another process , reason {0}", new Object[]{e});
        }
    }

    /**
    * Extension point for central log server . To start receiving connections from remote end .
    */
    public void run() {
        while (true) {
            try {
                new Thread(new LogWriter(server.accept())).start();
            } catch (Exception e) {
                LogWriter.log("Interrupted exception " + e.getMessage());
            }
        }
    }

    /**
    * args[0] - logging location . args[1] - which port the server can start. It must be a integer.
    *
    * @param args
    */
    public static void main(String[] args) {
        try {
            CentralizedLogging logServer = new CentralizedLogging(args[0], Integer.parseInt(args[1]));
            new Thread(logServer).start();
        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "Unable to start log server from this location : {0} , port : {1} , This may be due to given port is not a number or this port is not free  exception trace {2}", new Object[]{args[0], args[1], e});
        }
    }
}

/**
* Used for writing client packets into logs Dir .
*/
class LogWriter implements Runnable {

    /**
    * Field client - Socket Client .
    */
    Socket client;

    /**
    * Constructor for LogWriter.
    *
    * @param client Socket
    * @throws IOException
    */
    public LogWriter(Socket client) {
        this.client = client;
    }

    public void run() {
        write();
        try {
            this.client.close();
        } catch (IOException io) {
            System.out.println("Error while closing connection , reason " + io);
        }
    }

    /**
    * Method write.
    */
    public void write() {
        try {
            String date = new SimpleDateFormat("yyyy_MM_dd").format(new Date());
            File file = new File(CentralizedLogging.logDir + client.getInetAddress().getHostName() + "_"
                    + date + ".log");
            write(client.getInputStream(), file);
        } catch (Exception e) {
            log("Error in writing logs :: Host Name " + client.getInetAddress().getHostName()
                    + " , Occured Time " + System.currentTimeMillis() + ", Reason " + e.getMessage() + "\n\n");
        }
    }

    /**
    * Method write.
    *
    * @param in InputStream
    * @param file File
    * @throws Exception
    */
    public synchronized static void write(InputStream in, File file) throws Exception {
        RandomAccessFile writer = new RandomAccessFile(file, "rw");
        writer.seek(file.length()); //append the file content to the existing file or creates a new one .
        writer.write(read(in));
        writer.close();
    }

    /**
    * This method is used for monitoring errors that will be occured on writing plugin logs .
    *
    * @param msg
    */
    public static void log(String msg) {
        File file = new File(CentralizedLogging.logDir + "plugin_error_" + new SimpleDateFormat("yyyy_MM_dd").
                format(new Date()) + ".log");
        try {
            write(new ByteArrayInputStream(msg.getBytes()), file);
        } catch (Exception e) {
        }
    }

    /**
    * Method read.
    *
    * @param in InputStream
    * @return byte[]
    * @throws IOException
    */
    public static byte[] read(InputStream in) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int read = -1;
        byte[] buffer = new byte[1024];
        while ((read = in.read(buffer)) > -1) {
            out.write(buffer, 0, read);
        }
        return out.toByteArray();
    }

    /**
    * Method close.
    *
    * @param stream Object
    */
    public static void close(Object stream) {
        try {
            if (stream instanceof Writer) {
                ((Writer) stream).close();
            } else if (stream instanceof Reader) {
                ((Reader) stream).close();
            }
        } catch (Exception e) {
        }
    }
}