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

org.graylog2.restclient.models.ClusterService Maven / Gradle / Ivy

/**
 * This file is part of Graylog.
 *
 * Graylog is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Graylog is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Graylog.  If not, see .
 */
package org.graylog2.restclient.models;

import com.google.common.collect.Lists;
import org.graylog2.rest.models.system.SystemJobSummary;
import org.graylog2.restclient.lib.APIException;
import org.graylog2.restclient.lib.ApiClient;
import org.graylog2.restclient.lib.ServerNodes;
import org.graylog2.restclient.lib.metrics.Gauge;
import org.graylog2.restclient.lib.metrics.Metric;
import org.graylog2.restclient.models.api.requests.MultiMetricRequest;
import org.graylog2.restclient.models.api.requests.SystemJobTriggerRequest;
import org.graylog2.restclient.models.api.responses.metrics.MetricsListResponse;
import org.graylog2.restclient.models.api.responses.system.ClusterEntityJVMStatsResponse;
import org.graylog2.restclient.models.api.responses.system.ESClusterHealthResponse;
import org.graylog2.restclient.models.api.responses.system.GetNotificationsResponse;
import org.graylog2.restclient.models.api.responses.system.GetSystemJobsResponse;
import org.graylog2.restclient.models.api.responses.system.GetSystemMessagesResponse;
import org.graylog2.restclient.models.api.responses.system.NodeThroughputResponse;
import org.graylog2.restclient.models.api.responses.system.NotificationSummaryResponse;
import org.graylog2.restclient.models.api.responses.system.SystemMessageSummaryResponse;
import org.graylog2.restclient.models.api.responses.system.indices.IndexerFailureCountResponse;
import org.graylog2.restclient.models.api.responses.system.indices.IndexerFailuresResponse;
import org.graylog2.restroutes.generated.routes;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.libs.F;
import play.mvc.Http;

import javax.inject.Inject;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class ClusterService {
    private static final Logger LOG = LoggerFactory.getLogger(ClusterService.class);

    private final ApiClient api;
    private final SystemJob.Factory systemJobFactory;
    private final ServerNodes serverNodes;
    private final NodeService nodeService;

    @Inject
    private ClusterService(ApiClient api,
                           SystemJob.Factory systemJobFactory,
                           ServerNodes serverNodes,
                           NodeService nodeService) {
        this.api = api;
        this.systemJobFactory = systemJobFactory;
        this.serverNodes = serverNodes;
        this.nodeService = nodeService;
    }

    public void triggerSystemJob(SystemJob.Type type, User user) throws IOException, APIException {
        api.path(routes.SystemJobResource().trigger())
                .body(new SystemJobTriggerRequest(type, user))
                .expect(Http.Status.ACCEPTED)
                .execute();
    }

    public List allNotifications() throws IOException, APIException {
        GetNotificationsResponse r = api.path(routes.NotificationsResource().listNotifications(), GetNotificationsResponse.class).execute();

        List notifications = Lists.newArrayList();
        for (NotificationSummaryResponse notification : r.notifications) {
            try {
                notifications.add(new Notification(notification));
            } catch (IllegalArgumentException e) {
                LOG.warn("There is a notification type we can't handle: [{}]", notification.type);
            }
        }

        return notifications;
    }

    public void deleteNotification(Notification.Type type) throws APIException, IOException {
        api.path(routes.NotificationsResource().deleteNotification(type.toString().toLowerCase()))
                .expect(204)
                .execute();
    }

    public long getIndexerFailureCountLast24Hours() throws APIException, IOException {
        IndexerFailureCountResponse r = api.path(routes.FailuresResource().count(), IndexerFailureCountResponse.class)
                .queryParam("since", ISODateTimeFormat.dateTime().print(new DateTime(DateTimeZone.UTC).minusDays(1)))
                .execute();

        return r.count;
    }

    public IndexerFailuresResponse getIndexerFailures(int limit, int offset) throws APIException, IOException {
        return api.path(routes.FailuresResource().single(), IndexerFailuresResponse.class)
                .queryParam("limit", limit)
                .queryParam("offset", offset)
                .execute();
    }

    public List getSystemMessages(int page) throws IOException, APIException {
        GetSystemMessagesResponse r = api.path(routes.MessagesResource().all(), GetSystemMessagesResponse.class)
                .queryParam("page", page)
                .execute();
        List messages = Lists.newArrayList();
        for (SystemMessageSummaryResponse message : r.messages) {
            messages.add(new SystemMessage(message));
        }

        return messages;
    }

    public int getNumberOfSystemMessages() throws IOException, APIException {
        return api.path(routes.MessagesResource().all(), GetSystemMessagesResponse.class).execute().total;
    }

    public List allSystemJobs() throws IOException, APIException {
        List jobs = Lists.newArrayList();

        for (Node node : serverNodes.all()) {
            GetSystemJobsResponse r = api.path(routes.SystemJobResource().list(), GetSystemJobsResponse.class).node(node).execute();

            for (SystemJobSummary job : r.jobs) {
                jobs.add(systemJobFactory.fromSummaryResponse(job));
            }
        }

        return jobs;
    }

    public ESClusterHealth getESClusterHealth() {
        try {
            final ESClusterHealthResponse response = api.path(routes.IndexerClusterResource().clusterHealth(), ESClusterHealthResponse.class).execute();
            return new ESClusterHealth(response);
        } catch (APIException | IOException e) {
            LOG.error("Could not load es cluster health", e);
        }
        return null;
    }

    public List getClusterJvmStats() {
        List result = Lists.newArrayList();
        Map rs = null;
        try {
            rs = api.path(routes.SystemResource().jvm(), ClusterEntityJVMStatsResponse.class).fromAllNodes().executeOnAll();
        } catch (APIException e) {
            LOG.error("Unable to load JVM stats", e);
            return result;
        }

        for (Map.Entry entry : rs.entrySet()) {
            if (entry.getValue() == null) {
                LOG.warn("Skipping failed jvm stats request for node {}", entry.getKey());
                continue;
            }
            result.add(new NodeJVMStats(entry.getValue()));
        }

        return result;
    }

    public F.Tuple getClusterThroughput() {
        final Map responses;
        try {
            responses = api.path(routes.ThroughputResource().total(), NodeThroughputResponse.class)
                    .fromAllNodes()
                    .executeOnAll();
        } catch (APIException e) {
            LOG.error("Unable to load cluster throughput", e);
            return F.Tuple(0, 0);
        }
        int t = 0;
        for (Map.Entry entry : responses.entrySet()) {
            if (entry.getValue() == null) {
                LOG.warn("Skipping failed throughput request for node {}", entry.getKey());
                continue;
            }
            t += entry.getValue().throughput;
        }
        return F.Tuple(t, responses.size());
    }


    // TODO duplicated
    private long asLong(String read_bytes, Map metrics) {
        if (metrics.get(read_bytes) != null)
            return ((Number) ((Gauge) metrics.get(read_bytes)).getValue()).longValue();
        else
            return 0;
    }

    // TODO duplicated
    private String buildNetworkIOMetricName(String base, boolean total) {
        StringBuilder metricName = new StringBuilder(base).append("_");

        if (total) {
            metricName.append("total");
        } else {
            metricName.append("1sec");
        }

        return metricName.toString();
    }

    // TODO duplicated
    private String qualifiedIOMetricName(String type, String id, String base, boolean total) {
        return type + "." + id + "." + buildNetworkIOMetricName(base, total);
    }

    public Input.IoStats getGlobalInputIo(Input input) {
        final Input.IoStats ioStats = new Input.IoStats();

        final String inputId = input.getId();
        final String type = input.getType();

        try {
            MultiMetricRequest request = new MultiMetricRequest();
            final String read_bytes = qualifiedIOMetricName(type, inputId, "read_bytes", false);
            final String read_bytes_total = qualifiedIOMetricName(type, inputId, "read_bytes", true);
            final String written_bytes = qualifiedIOMetricName(type, inputId, "written_bytes", false);
            final String written_bytes_total = qualifiedIOMetricName(type, inputId, "written_bytes", true);
            request.metrics = new String[]{read_bytes, read_bytes_total, written_bytes, written_bytes_total};

            final Map results = api.path(routes.MetricsResource().multipleMetrics(), MetricsListResponse.class)
                    .body(request)
                    .expect(200, 404)
                    .executeOnAll();

            for (MetricsListResponse response : results.values()) {
                final Map metrics = response.getMetrics();

                ioStats.readBytes += asLong(read_bytes, metrics);
                ioStats.readBytesTotal += asLong(read_bytes_total, metrics);
                ioStats.writtenBytes += asLong(written_bytes, metrics);
                ioStats.writtenBytesTotal += asLong(written_bytes_total, metrics);
            }

            for (Radio radio : nodeService.radios().values()) {
                try {
                    final MetricsListResponse radioResponse = api
                            .path(routes.radio().MetricsResource().multipleMetrics(), MetricsListResponse.class)
                            .body(request)
                            .radio(radio)
                            .expect(200, 404)
                            .execute();
                    final Map metrics = radioResponse.getMetrics();

                    ioStats.readBytes += asLong(read_bytes, metrics);
                    ioStats.readBytesTotal += asLong(read_bytes_total, metrics);
                    ioStats.writtenBytes += asLong(written_bytes, metrics);
                    ioStats.writtenBytesTotal += asLong(written_bytes_total, metrics);
                } catch (APIException | IOException e) {
                    LOG.error("Unable to load metrics for radio node {}", radio.getId());
                }
            }

        } catch (APIException | IOException e) {
            LOG.error("Unable to load master node", e);
        }
        return ioStats;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy