Sibidharan Sibidharan - 2 months ago 21
Java Question

Run apachetop from Java

Since I have too many apache log files, I decided to create a java program build the command for me to run the

apachetop
. So I decided to create a index file, where all the apache_log files will be placed.

apache_logs_index

/opt/lampp/logs/access_log
/opt/lampp/logs/error_log
/opt/lampp/logs/php_error_log
/opt/lampp/logs/ssl_request_log
/opt/lampp/logs/mb.domain.com-access_log
/opt/lampp/logs/mb.domain.com-error_log
/opt/lampp/logs/my.domain.com-access_log
/opt/lampp/logs/my.domain.com-error_log
/opt/lampp/logs/op.domain.com-access_log
/opt/lampp/logs/op.domain.com-error_log


And I created a java program to build the command for me.

ApacheTopCall.java

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ApacheTopCall{

public static void main(String args[]) {

String fileName = "apache_logs_index";
String command = "apachetop";
command = command + " -d 1";
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {

String line;
while ((line = br.readLine()) != null) {
command = command + " -f " + line.trim();
}
//System.out.println(command);
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
Process p = pb.start();
p.waitFor();
} catch (IOException|InterruptedException e) {
e.printStackTrace();
}

}

}


Now all I want is to run
apachetop
by itself. I tried to call it using
ProcessBuilder
but
apachetop
is not displaying, instead, it is simply waiting for the process to be quit. When I run my java code, I want the command to be executed and the
apachetop
should be run.

When I am executing the command built by the java code, it is working good. But not with
ProcessBuilder

Answer

If all you want to achieve is this, then here is the simple and effective solution:

You also need to make some small changes to your java code as follows:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ApacheTopCall{

        public static void main(String args[]) {

                String fileName = "apache_logs_index";
                String command = "apachetop";
                command = command + " -d 1 -q -l -r -p"; //extra params
                try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {

                        String line;
                        while ((line = br.readLine()) != null) {
                                command = command + " -f " + line.trim();
                        }
                        System.out.println(command); //we are just creating the command for run. The C program actually run the generated command.
                        //ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
                        //Process p = pb.start();
                        //p.waitFor();
                } catch (IOException e) {
                        e.printStackTrace();
                }

        }

}

I created a simple C program apachetopall.c

#include <stdio.h>

int main(){
        FILE *fp = popen("cd /root/scripts/; java ApacheTopCall", "r"); //make sure you cd to the location of your java class.
        char cmd[32768];
        fgets(cmd, 32768, fp);
        system(cmd);
        return 0;
}

Compile it and save it as apachetopall with the following command

gcc -o apachetopall apachetopall.c

Now all you need to do is, execute the binary apachetopall. And your goal is achieved.

How it works

Instead of asking the java to run the command, we are asking the java to create the command which is needed to be fired. Now the C program runs the java code and gets the command as output and it fires the same command, which goes to the front of the screen.