All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.dropwizard.util.metrics.ServerLoadFetcher Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
package org.kiwiproject.dropwizard.util.metrics;

import static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.kiwiproject.base.process.ProcessHelper;
import org.kiwiproject.io.KiwiIO;

import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * Attempts to get the server load average as reported by the {@code uptime} command.
 *
 * @implNote Only works on *nix-like systems, or maybe in Windows if there is an uptime command installed and on the PATH.
 */
@Slf4j
public class ServerLoadFetcher {

    /**
     * Can be used if you need to report some value for load average in the case when {@link #get()} returns an
     * empty {@link Optional}
     */
    public static final String NO_VALUE = "0.00, 0.00, 0.00";

    private static final Pattern LOAD_AVERAGE_PATTERN =
            Pattern.compile("load averages?: (.*)", Pattern.CASE_INSENSITIVE);

    private final ProcessHelper processes;

    public ServerLoadFetcher() {
        this(new ProcessHelper());
    }

    @VisibleForTesting
    ServerLoadFetcher(ProcessHelper processes) {
        this.processes = processes;
    }

    /**
     * Example format on Linux-based systems:
     * 

* {@code 18:29:28 up 34 days, 18:25, 1 user, load average: 0.88, 0.98, 1.03} *

* Example format on macOS systems: *

* {@code 18:29:28 up 34 days, 18:25, 1 user, load averages: 0.88 0.98 1.03} * * @return an {@link Optional} with the load average string; otherwise an {@link Optional#empty()} if * the load average was not found or if any error occurred * @implNote the pattern match is case-insensitive against the output of the uptime command */ public Optional get() { var process = processes.launch("uptime"); try { var output = KiwiIO.readInputStreamOf(process); var matcher = LOAD_AVERAGE_PATTERN.matcher(output); checkState(matcher.find(), "Did not find load average substring"); var exitedBeforeTimeout = process.waitFor(500, TimeUnit.MILLISECONDS); if (!exitedBeforeTimeout) { LOG.debug("Process did not exit before timeout, so assume something is not right"); return Optional.empty(); } return Optional.of(matcher.group(1)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); LOG.warn("Interrupted while getting server load average", e); return Optional.empty(); } catch (Exception e) { LOG.debug("Error getting server load average", e); return Optional.empty(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy