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!
CodePudding user response:
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).
CodePudding user response:
Do you want something like centralized logs? There are tools for that like Grafana Loki, where you can use a log collector named promtail to collect logs from files and send them to your Loki instance, and with the Grafana frontend you have searchable, colored logs. This can include logs from multiple applications.
https://grafana.com/docs/loki/latest/clients/promtail/
You could send that to Grafana Cloud, which got a free tier for up to three users, or host a Grafana Stack with docker, here is an ready to use stack: