Reputation: 1
I'm trying to make a javafx application which displays the logs from kubernetes. I'm using Runtime.getRuntime().exec
to get the output of kubetail servicename
in the following way:
Process exec = Runtime.getRuntime().exec(new String[]{"kubetail", "serviceName"});
InputStream inputStream = exec.getInputStream();
int read;
try {
while (((read = inputStream.read()) != -1)) {
System.out.print((char) read);
}
} catch (IOException e) {
e.printStackTrace();
}
The process starts normally and I see "Will tail 2 pods...". The problem appears when I make a request on that service and a lot of logs appears. The service returns a report and this report is archived and it is also logged. The report is quite big, 40K characters. The tail somehow hangs in the middle of the logged report and I don't get any more data, but if I send another request, it continues from where it hanged and stops again on the report of the second request.
I tried using buffered reader and also wrapped the inputstream with NIO, but the problem persist. I also tried to use kubectl logs
and this works on but I don't have any identification for the line of log (I don't know which pod it belongs to). kubetail
gives a stream of logs for all the pods in an application and these are identified by color and by pod name.
Thank you
Upvotes: 0
Views: 282
Reputation: 15196
You are not consuming the stdout and stderr streams properly, they will cause process output to hang if one fills without you reading it. You could try setting stderr to go to stdout class when using ProcessBuilder
ProcessBuilder pb = new ProcessBuilder(new String[]{"kubetail", "serviceName"});
pb.redirectErrorStream(true);
Process exec = pb.start();
... Your reading code
int rc = exec.waitFor();
OR: add threads to consume both stdout and stderr streams:
Process exec = Runtime.getRuntime().exec(new String[]{"kubetail", "serviceName"});
new Thread(() -> copy(exec.getInputStream(), System.out), "STDOUT").start();
new Thread(() -> copy(exec.getErrorStream(), System.err), "STDERR").start();
int rc = exec.waitFor();
with method:
static void copy(InputStream in, OutputStream out)
{
try(var autoClose = in; var autoClose2 = out)
{
in.transferTo(out);
}
catch(IOException io)
{
throw new UncheckedIOException(io);
}
}
Upvotes: 1