Search code examples
javaconsolelocalhostmirroringconsole-output

Can i mirror the console output to a website?


Is there any way I can mirror the console output to localhost in java and maybe even add some nice CSS to it. It would be cool if the console could also be reached by other devices in the same network. I have done much research regarding this topic but haven't found ANY websites/threads/questions about this. Help would be appreciated!


Solution

  • In order to intercept the output normally going to the console (or the standard output) you need to use the following API somewhere in your code:

    System.setOut(myStream); 
    System.setErr(myStream); //If you want to grab the error stream also. Could go do a different location
    

    Many log libraries can already do this for you. But this is basically how you need to capture the output. What 'myStream' actually does is up to you. The quickest route to get this out to a web server on http://localhost:8888 is to direct the output to a file and start the JDK's embedded web server. Here is an example you should be able to run:

    package test.example;
    
    import com.sun.net.httpserver.HttpContext;
    import com.sun.net.httpserver.HttpServer;
    
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.InetSocketAddress;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.time.Instant;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class SystemOutToWeb
    {
        public static void main(String... args ) throws Exception
        {
            final Path myOutputFile = Paths.get("./MyOutputFile.txt");
            final PrintStream myStream = new PrintStream(myOutputFile.toFile());
    
            System.out.println("Going to redirect to : " + myOutputFile.toAbsolutePath());
    
            System.setOut(myStream);
            System.setErr(myStream);
    
            System.out.println("Starting the Output");
    
            //Have something that logs every 5 seconds
            final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.scheduleAtFixedRate(() ->
            {
                System.out.println("Hello - the time is now " + Instant.now());
            }, 1, 5, TimeUnit.SECONDS);
    
            // Start the simple Java Built in Web Server.
            final HttpServer http = HttpServer.create(new InetSocketAddress(8888), 0);
            final HttpContext context = http.createContext("/");
            context.setHandler(exchange ->
            {
                byte[] data = Files.readAllBytes(myOutputFile);
                exchange.sendResponseHeaders(200, data.length);
                OutputStream os = exchange.getResponseBody();
                os.write(data);
                os.close();
            });
            http.start();
    
        }
    }
    
    

    If you give it a few seconds to run, then you should be able to see something at http://localhost:8888.

    Of course, this is only the starting point. You could for instance use a different web server all together or augment this resource with some CSS further (perhaps even use a web socket to stream the file out as it updates).