Java: Obtener y Formatear el Uptime del Sistema Linux

Uso del Comando uptime en Linux

El comando uptime proporciona datos sobre el tiempo de actividad del sistema, incluyendo la duración desde el último arranque. Ejecutar uptime en la terminal genera una salida similar a:

04:03:58 up 10 days, 13:19, 1 user, load average: 0.54, 0.40, 0.20

Para integrar esta información en aplicaciones Java, es necesario extraer y converrtir el tiempo de actividad a un formato manejable, como segundos.

Clase Utilitaria en Java para Parsear Uptime

Se implementa una clase que ejecuta comandos del sistema y parsea la salida de uptime mediante expresiones regulares para una extracción robusta.

package com.example.utility;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UptimeExtractor {

    public static String runSystemCommand(String cmd) {
        StringBuilder output = new StringBuilder();
        try {
            Process proc = Runtime.getRuntime().exec(cmd);
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return output.toString().trim();
    }

    public static long convertUptimeToSeconds(String uptimeStr) {
        Pattern withDaysPattern = Pattern.compile("up\\s+(\\d+)\\s+days?,\\s+(\\d+):(\\d+)");
        Matcher withDaysMatcher = withDaysPattern.matcher(uptimeStr);
        if (withDaysMatcher.find()) {
            int d = Integer.parseInt(withDaysMatcher.group(1));
            int h = Integer.parseInt(withDaysMatcher.group(2));
            int m = Integer.parseInt(withDaysMatcher.group(3));
            return (d * 86400L) + (h * 3600L) + (m * 60L);
        }

        Pattern noDaysPattern = Pattern.compile("up\\s+(\\d+):(\\d+)");
        Matcher noDaysMatcher = noDaysPattern.matcher(uptimeStr);
        if (noDaysMatcher.find()) {
            int h = Integer.parseInt(noDaysMatcher.group(1));
            int m = Integer.parseInt(noDaysMatcher.group(2));
            return (h * 3600L) + (m * 60L);
        }

        if (uptimeStr.contains("min")) {
            Pattern minPattern = Pattern.compile("up\\s+(\\d+)\\s+min");
            Matcher minMatcher = minPattern.matcher(uptimeStr);
            if (minMatcher.find()) {
                int minutes = Integer.parseInt(minMatcher.group(1));
                return minutes * 60L;
            }
        }
        return 0L;
    }

    public static long fetchUptime() {
        String output = runSystemCommand("uptime");
        return convertUptimeToSeconds(output);
    }

    public static long fetchUptimeFromProc() {
        String data = runSystemCommand("cat /proc/uptime");
        if (data != null && !data.isEmpty()) {
            String[] tokens = data.split("\\s+");
            if (tokens.length > 0) {
                String secPart = tokens[0];
                int dotPos = secPart.indexOf('.');
                if (dotPos != -1) {
                    return Long.parseLong(secPart.substring(0, dotPos));
                } else {
                    return Long.parseLong(secPart);
                }
            }
        }
        return 0L;
    }

    public static void main(String[] args) {
        String testStr = "18:09:13 up 1 day,  1:43,  4 users,  load average: 0.51, 0.48, 0.31";
        System.out.println("Uptime en segundos: " + convertUptimeToSeconds(testStr));
        System.out.println("Uptime real del sistema: " + fetchUptime());
    }
}

Alternativa con /proc/uptime

Para una mayor precisión, se puede acceder directamente al archivo /proc/uptime, donde el primer valor indica el tiempo de actividad en segundos, incluyendo decimales.

public static long getProcUptime() {
    String content = runSystemCommand("cat /proc/uptime");
    if (content != null && content.contains(" ")) {
        String[] fields = content.split(" ");
        if (fields.length > 0) {
            String value = fields[0];
            if (value.contains(".")) {
                return Long.parseLong(value.substring(0, value.indexOf(".")));
            }
            return Long.parseLong(value);
        }
    }
    return 0L;
}

Este método evita el parsing complejo de la salida estándar de uptime.

Etiquetas: java linux uptime proc-filesystem

Publicado el 6-1 14:03