private void sendNodeThreadPoolStats(ThreadPoolStats threadPoolStats) {
    String prefix = this.getPrefix("thread_pool");
    Iterator<ThreadPoolStats.Stats> statsIterator = threadPoolStats.iterator();
    while (statsIterator.hasNext()) {
      ThreadPoolStats.Stats stats = statsIterator.next();
      String threadPoolType = prefix + "." + stats.getName();

      this.sendGauge(threadPoolType, "threads", stats.getThreads());
      this.sendGauge(threadPoolType, "queue", stats.getQueue());
      this.sendGauge(threadPoolType, "active", stats.getActive());
      this.sendGauge(threadPoolType, "rejected", stats.getRejected());
      this.sendGauge(threadPoolType, "largest", stats.getLargest());
      this.sendGauge(threadPoolType, "completed", stats.getCompleted());
    }
  }
  @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;
    }

    ThreadPoolStatsBean tpStatsBean = new ThreadPoolStatsBean();
    try {
      NodesStatsResponse ndsStatsResponse = ESTransportClient.getNodesStatsResponse(config);
      ThreadPoolStats tpstats = null;
      NodeStats ndStat = null;
      if (ndsStatsResponse.getNodes().length > 0) {
        ndStat = ndsStatsResponse.getAt(0);
      }
      if (ndStat == null) {
        logger.info("NodeStats is null,hence returning (No ThreadPoolStats).");
        return;
      }
      tpstats = ndStat.getThreadPool();
      if (tpstats == null) {
        logger.info("ThreadPoolStats is null,hence returning (No ThreadPoolStats).");
        return;
      }
      Iterator<ThreadPoolStats.Stats> iter = tpstats.iterator();
      while (iter.hasNext()) {
        ThreadPoolStats.Stats stat = iter.next();
        if (stat.getName().equals("index")) {
          tpStatsBean.indexThreads = stat.getThreads();
          tpStatsBean.indexQueue = stat.getQueue();
          tpStatsBean.indexActive = stat.getActive();
          tpStatsBean.indexRejected = stat.getRejected();
          tpStatsBean.indexLargest = stat.getLargest();
          tpStatsBean.indexCompleted = stat.getCompleted();
        } else if (stat.getName().equals("get")) {
          tpStatsBean.getThreads = stat.getThreads();
          tpStatsBean.getQueue = stat.getQueue();
          tpStatsBean.getActive = stat.getActive();
          tpStatsBean.getRejected = stat.getRejected();
          tpStatsBean.getLargest = stat.getLargest();
          tpStatsBean.getCompleted = stat.getCompleted();
        } else if (stat.getName().equals("search")) {
          tpStatsBean.searchThreads = stat.getThreads();
          tpStatsBean.searchQueue = stat.getQueue();
          tpStatsBean.searchActive = stat.getActive();
          tpStatsBean.searchRejected = stat.getRejected();
          tpStatsBean.searchLargest = stat.getLargest();
          tpStatsBean.searchCompleted = stat.getCompleted();
        } else if (stat.getName().equals("bulk")) {
          tpStatsBean.bulkThreads = stat.getThreads();
          tpStatsBean.bulkQueue = stat.getQueue();
          tpStatsBean.bulkActive = stat.getActive();
          tpStatsBean.bulkRejected = stat.getRejected();
          tpStatsBean.bulkLargest = stat.getLargest();
          tpStatsBean.bulkCompleted = stat.getCompleted();
        }
      }
    } catch (Exception e) {
      logger.warn("failed to load Thread Pool stats data", e);
    }
    tpStatsReporter.threadPoolBean.set(tpStatsBean);
  }
  private Table buildTable(
      RestRequest req,
      ClusterStateResponse state,
      NodesInfoResponse nodesInfo,
      NodesStatsResponse nodesStats) {
    final String[] threadPools = req.paramAsStringArray("thread_pool_patterns", new String[] {"*"});
    final DiscoveryNodes nodes = state.getState().nodes();
    final Table table = getTableWithHeader(req);

    // collect all thread pool names that we see across the nodes
    final Set<String> candidates = new HashSet<>();
    for (final NodeStats nodeStats : nodesStats.getNodes()) {
      for (final ThreadPoolStats.Stats threadPoolStats : nodeStats.getThreadPool()) {
        candidates.add(threadPoolStats.getName());
      }
    }

    // collect all thread pool names that match the specified thread pool patterns
    final Set<String> included = new HashSet<>();
    for (final String candidate : candidates) {
      if (Regex.simpleMatch(threadPools, candidate)) {
        included.add(candidate);
      }
    }

    for (final DiscoveryNode node : nodes) {
      final NodeInfo info = nodesInfo.getNodesMap().get(node.getId());
      final NodeStats stats = nodesStats.getNodesMap().get(node.getId());

      final Map<String, ThreadPoolStats.Stats> poolThreadStats;
      final Map<String, ThreadPool.Info> poolThreadInfo;

      if (stats == null) {
        poolThreadStats = Collections.emptyMap();
        poolThreadInfo = Collections.emptyMap();
      } else {
        // we use a sorted map to ensure that thread pools are sorted by name
        poolThreadStats = new TreeMap<>();
        poolThreadInfo = new HashMap<>();

        ThreadPoolStats threadPoolStats = stats.getThreadPool();
        for (ThreadPoolStats.Stats threadPoolStat : threadPoolStats) {
          poolThreadStats.put(threadPoolStat.getName(), threadPoolStat);
        }
        if (info != null) {
          for (ThreadPool.Info threadPoolInfo : info.getThreadPool()) {
            poolThreadInfo.put(threadPoolInfo.getName(), threadPoolInfo);
          }
        }
      }
      for (Map.Entry<String, ThreadPoolStats.Stats> entry : poolThreadStats.entrySet()) {

        if (!included.contains(entry.getKey())) continue;

        table.startRow();

        table.addCell(node.getName());
        table.addCell(node.getId());
        table.addCell(node.getEphemeralId());
        table.addCell(info == null ? null : info.getProcess().getId());
        table.addCell(node.getHostName());
        table.addCell(node.getHostAddress());
        table.addCell(node.getAddress().address().getPort());
        final ThreadPoolStats.Stats poolStats = entry.getValue();
        final ThreadPool.Info poolInfo = poolThreadInfo.get(entry.getKey());

        Long maxQueueSize = null;
        String keepAlive = null;
        Integer minThreads = null;
        Integer maxThreads = null;

        if (poolInfo != null) {
          if (poolInfo.getQueueSize() != null) {
            maxQueueSize = poolInfo.getQueueSize().singles();
          }
          if (poolInfo.getKeepAlive() != null) {
            keepAlive = poolInfo.getKeepAlive().toString();
          }
          if (poolInfo.getMin() >= 0) {
            minThreads = poolInfo.getMin();
          }
          if (poolInfo.getMax() >= 0) {
            maxThreads = poolInfo.getMax();
          }
        }

        table.addCell(entry.getKey());
        table.addCell(poolInfo == null ? null : poolInfo.getThreadPoolType().getType());
        table.addCell(poolStats == null ? null : poolStats.getActive());
        table.addCell(poolStats == null ? null : poolStats.getThreads());
        table.addCell(poolStats == null ? null : poolStats.getQueue());
        table.addCell(maxQueueSize);
        table.addCell(poolStats == null ? null : poolStats.getRejected());
        table.addCell(poolStats == null ? null : poolStats.getLargest());
        table.addCell(poolStats == null ? null : poolStats.getCompleted());
        table.addCell(minThreads);
        table.addCell(maxThreads);
        table.addCell(keepAlive);

        table.endRow();
      }
    }

    return table;
  }