/** * Copyright 2017 Netflix, Inc. * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.raigad.monitoring; import com.google.inject.Inject; import com.google.inject.Singleton; import com.netflix.raigad.configuration.IConfiguration; import com.netflix.raigad.scheduler.SimpleTimer; import com.netflix.raigad.scheduler.Task; import com.netflix.raigad.scheduler.TaskTimer; import com.netflix.raigad.utils.ElasticsearchProcessMonitor; import com.netflix.raigad.utils.ElasticsearchTransportClient; import com.netflix.servo.annotations.DataSourceType; import com.netflix.servo.annotations.Monitor; import com.netflix.servo.monitor.Monitors; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; import org.elasticsearch.transport.TransportStats; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @Singleton public class TransportStatsMonitor extends Task { private static final Logger logger = LoggerFactory.getLogger(TransportStatsMonitor.class); public static final String METRIC_NAME = "Elasticsearch_TransportMonitor"; private final Elasticsearch_TransportStatsReporter transportStatsReporter; @Inject public TransportStatsMonitor(IConfiguration config) { super(config); transportStatsReporter = new Elasticsearch_TransportStatsReporter(); Monitors.registerObject(transportStatsReporter); } @Override public void execute() throws Exception { // If Elasticsearch is started then only start the monitoring if (!ElasticsearchProcessMonitor.isElasticsearchRunning()) { String exceptionMsg = "Elasticsearch is not yet started, check back again later"; logger.info(exceptionMsg); return; } TransportStatsBean transportStatsBean = new TransportStatsBean(); try { NodesStatsResponse nodesStatsResponse = ElasticsearchTransportClient.getNodesStatsResponse(config); NodeStats nodeStats = null; List<NodeStats> nodeStatsList = nodesStatsResponse.getNodes(); if (nodeStatsList.size() > 0) { nodeStats = nodeStatsList.get(0); } if (nodeStats == null) { logger.info("Transport stats are not available (node stats is not available)"); return; } TransportStats transportStats = nodeStats.getTransport(); if (transportStats == null) { logger.info("Transport stats are not available"); return; } transportStatsBean.serverOpen = transportStats.getServerOpen(); transportStatsBean.rxCount = transportStats.getRxCount(); transportStatsBean.rxSize = transportStats.getRxSize().getBytes(); transportStatsBean.rxSizeDelta = transportStats.getRxSize().getBytes() - transportStatsBean.rxSize; transportStatsBean.txCount = transportStats.getTxCount(); transportStatsBean.txSize = transportStats.getTxSize().getBytes(); transportStatsBean.txSizeDelta = transportStats.getTxSize().getBytes() - transportStatsBean.txSize; } catch (Exception e) { logger.warn("Failed to load transport stats data", e); } transportStatsReporter.transportStatsBean.set(transportStatsBean); } public class Elasticsearch_TransportStatsReporter { private final AtomicReference<TransportStatsBean> transportStatsBean; public Elasticsearch_TransportStatsReporter() { transportStatsBean = new AtomicReference<TransportStatsBean>(new TransportStatsBean()); } @Monitor(name = "server_open", type = DataSourceType.GAUGE) public long getServerOpen() { return transportStatsBean.get().serverOpen; } @Monitor(name = "rx_count", type = DataSourceType.GAUGE) public long getRxCount() { return transportStatsBean.get().rxCount; } @Monitor(name = "rx_size", type = DataSourceType.GAUGE) public long getRxSize() { return transportStatsBean.get().rxSize; } @Monitor(name = "rx_size_delta", type = DataSourceType.GAUGE) public long getRxSizeDelta() { return transportStatsBean.get().rxSizeDelta; } @Monitor(name = "tx_count", type = DataSourceType.GAUGE) public long getTxCount() { return transportStatsBean.get().txCount; } @Monitor(name = "tx_size", type = DataSourceType.GAUGE) public long getTxSize() { return transportStatsBean.get().txSize; } @Monitor(name = "tx_size_delta", type = DataSourceType.GAUGE) public long getTxSizeDelta() { return transportStatsBean.get().txSizeDelta; } } private static class TransportStatsBean { private long serverOpen; private long rxCount; private long rxSize; private long rxSizeDelta; private long txCount; private long txSize; private long txSizeDelta; } public static TaskTimer getTimer(String name) { return new SimpleTimer(name, 60 * 1000); } @Override public String getName() { return METRIC_NAME; } }