javaserver-monitoringoshi

How can I remotely monitor the performance status of a Linux server with oshi?


I want to use OSHI to monitor the performance status of my remote Linux server, but the official api seems to only monitor the performance status of the machine.

Do I have to put the java code on the server to get the performance status of the server? Can I use my own machine to monitor the performance status of the remote server?


Solution

  • As you indicated, OSHI is only designed to read information from the local computer. You would have to run a program on the remote computer using OSHI to fetch statistics.

    Issue 249 on the OSHI project outlines a few of the options, including the Dropwizard Metrics library, with which you can enable a JMX port with the data. However, capturing a larger number of metrics that way probably adds a lot more overhead than needed.

    Alternately Jackson's ObjectMapper is capable of handling any of OSHI's objects. You can easily set up a Webserver to vend JSON (or XML or CSV, etc.). Here's a quick sample dumping the entire SystemInfo object:

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    import java.security.NoSuchAlgorithmException;
    import java.util.Scanner;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import oshi.SystemInfo;
    
    public class WebSocket {
        public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
            ServerSocket server = new ServerSocket(80);
            try {
                System.out.println("Server has started on 127.0.0.1:80.\r\nWaiting for a connection...");
                Socket client = server.accept();
                System.out.println("A client connected.");
                InputStream in = client.getInputStream();
                OutputStream out = client.getOutputStream();
                Scanner s = new Scanner(in, "UTF-8");
                try {
                    String data = s.useDelimiter("\\r\\n\\r\\n").next();
                    Matcher get = Pattern.compile("^GET").matcher(data);
                    if (get.find()) {
                        SystemInfo si = new SystemInfo();
                        ObjectMapper mapper = new ObjectMapper();
                        byte[] response = ("HTTP/1.1 200 OK\r\n" + "Content-Type: application/json\r\n"
                                + "Accept: application/json\r\n"
                                // end header
                                + "\r\n"
                                // write JSON
                                + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(si))
                                        .getBytes(StandardCharsets.UTF_8);
                        out.write(response, 0, response.length);
                    }
                } finally {
                    s.close();
                }
            } finally {
                server.close();
            }
        }
    }
    

    Execute the above class on your Linux server and then connect to it via a web browser at http://yourserver and you'll get all OSHI's stats in pretty JSON.

    {
      "hardware" : {
        "computerSystem" : {
          "firmware" : {
            "manufacturer" : "Apple Inc.",
            "version" : "1037.40.124.0.0 (iBridge: 17.16.11081.0.0,0)",
            "description" : "EFI64",
            "name" : "boot.efi",
            "releaseDate" : "10/17/2019"
          },
    
          <snip>
    
        "processor" : {
          "maxFreq" : 2300000000,
          "currentFreq" : [ 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000, 2300000000 ],
          "contextSwitches" : 156099,
          "interrupts" : 1836212,
          "systemCpuLoadTicks" : [ 37060587, 0, 22431664, -1856553863, 0, 0, 0, 0 ],
          "processorCpuLoadTicks" : [ [ 8458566, 0, 7386132, 140274450, 0, 0, 0, 0 ], [ 120919, 0, 109162, 155889021, 0, 0, 0, 0 ], [ 7848726, 0, 4826688, 143443690, 0, 0, 0, 0 ], [ 117655, 0, 116672, 155884776, 0, 0, 0, 0 ], [ 5675383, 0, 3300677, 147143043, 0, 0, 0, 0 ], [ 116186, 0, 111427, 155891490, 0, 0, 0, 0 ], [ 4235682, 0, 2440832, 149442588, 0, 0, 0, 0 ], [ 114003, 0, 111121, 155893978, 0, 0, 0, 0 ], [ 3471025, 0, 1700387, 150947690, 0, 0, 0, 0 ], [ 111883, 0, 101912, 155905307, 0, 0, 0, 0 ], [ 2713535, 0, 962449, 152443118, 0, 0, 0, 0 ], [ 109036, 0, 73592, 155936474, 0, 0, 0, 0 ], [ 2023118, 0, 626887, 153469097, 0, 0, 0, 0 ], [ 104912, 0, 50922, 155963268, 0, 0, 0, 0 ], [ 1738287, 0, 472098, 153908718, 0, 0, 0, 0 ], [ 101671, 0, 40706, 155976725, 0, 0, 0, 0 ] ],
          "physicalPackageCount" : 1,
          "physicalProcessorCount" : 8,
          "logicalProcessorCount" : 16,
    
          <snip>
    
          "identifier" : "Intel64 Family 6 Model 158 Stepping 13",
          "model" : "158",
          "processorIdentifier" : {
            "processorID" : "BFEBFBFF000906ED",
            "cpu64bit" : true,
            "identifier" : "Intel64 Family 6 Model 158 Stepping 13",
            "model" : "158",
            "vendor" : "GenuineIntel",
            "stepping" : "13",
            "vendorFreq" : 2300000000,
            "family" : "6",
            "name" : "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz"
          },
          "vendor" : "GenuineIntel",
          "stepping" : "13",
          "processorID" : "BFEBFBFF000906ED",
          "cpu64bit" : true,
          "vendorFreq" : 2300000000,
          "family" : "6",
          "name" : "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz"
        },
        "memory" : {
          "available" : 13347446784,
          "total" : 34359738368,
          "pageSize" : 4096,
          "virtualMemory" : {
            "swapTotal" : 7516192768,
            "swapUsed" : 5921832960,
            "swapPagesIn" : 71667220,
            "swapPagesOut" : 809694
          },
          "physicalMemory" : [ {
            "bankLabel" : "BANK 0/ChannelA-DIMM",
            "capacity" : 17179869184,
            "clockSpeed" : 2400000000,
            "manufacturer" : "Micron",
            "memoryType" : "DDR4"
          }, {
            "bankLabel" : "BANK 2/ChannelB-DIMM",
            "capacity" : 17179869184,
            "clockSpeed" : 2400000000,
            "manufacturer" : "Micron",
            "memoryType" : "DDR4"
          } ]
        },
    

    Obviously you'd want to set up a better mechanism than web-browser JSON, and perhaps narrow down your response to only objects you care about. But hopefully this shows how easy it is to include OSHI into any existing Java-based network response.