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

com.arpnetworking.metrics.jvm.ExecutorServiceMetricsRunnable Maven / Gradle / Ivy

There is a newer version: 0.13.1
Show newest version
/**
 * Copyright 2017 Inscope Metrics Inc.
 *
 * 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.arpnetworking.metrics.jvm;

import com.arpnetworking.metrics.Metrics;
import com.arpnetworking.metrics.MetricsFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * An implementation of Runnable that collects all metrics for
 * registered ExecutorService instances each time its run.
 *
 * @author Ville Koskela (ville dot koskela at inscopemetrics dot com)
 */
// CHECKSTYLE.OFF: FinalClass - Allow clients to inherit from this.
public class ExecutorServiceMetricsRunnable extends AbstractMetricsRunnable {
// CHECKSTYLE.ON: FinalClass

    @Override
    protected void collectMetrics(final Metrics metrics) {
        for (final Map.Entry entry : _executorServices.entrySet()) {
            final String name = entry.getKey();
            final ExecutorService executorService = entry.getValue();
            if (executorService instanceof ForkJoinPool) {
                processForkJoinPool(metrics, name, (ForkJoinPool) executorService);
            }
            if (executorService instanceof ThreadPoolExecutor) {
                // NOTE: That a ScheduledThreadPoolExecutor is a ThreadPoolExecutor
                processThreadPoolExecutor(metrics, name, (ThreadPoolExecutor) executorService);
            }
        }
    }

    /**
     * Generate samples for a ForkJoinPool.
     *
     * Includes metrics for:
     * 
    *
  • active_threads
  • *
  • queued_submissions
  • *
  • queued_tasks
  • *
  • parallelism
  • *
  • thread_pool_size
  • *
* * @param metrics this unit of work's Metrics instance * @param name the name of the executor service * @param executorService the ForkJoinPool instance to sample */ protected void processForkJoinPool( final Metrics metrics, final String name, final ForkJoinPool executorService) { final String prefix = String.join( "/", ROOT_NAMESPACE, name); metrics.setGauge( String.join( "/", prefix, "active_threads"), executorService.getActiveThreadCount()); metrics.setGauge( String.join( "/", prefix, "queued_submissions"), executorService.getQueuedSubmissionCount()); metrics.setGauge( String.join( "/", prefix, "queued_tasks"), executorService.getQueuedTaskCount()); metrics.setGauge( String.join( "/", prefix, "parallelism"), executorService.getParallelism()); metrics.setGauge( String.join( "/", prefix, "thread_pool_size"), executorService.getPoolSize()); } /** * Generate samples for a ThreadPoolExecutor. * * Includes metrics for: *
    *
  • active_threads
  • *
  • queued_tasks
  • *
  • completed_tasks (for all time)
  • *
  • thread_pool_maximum_size
  • *
  • thread_pool_size
  • *
* * @param metrics this unit of work's Metrics instance * @param name the name of the executor service * @param executorService the ForkJoinPool instance to sample */ protected void processThreadPoolExecutor( final Metrics metrics, final String name, final ThreadPoolExecutor executorService) { final String prefix = String.join( "/", ROOT_NAMESPACE, name); metrics.setGauge( String.join( "/", prefix, "active_threads"), executorService.getActiveCount()); metrics.setGauge( String.join( "/", prefix, "queued_tasks"), executorService.getQueue().size()); metrics.setGauge( String.join( "/", prefix, "completed_tasks"), executorService.getCompletedTaskCount()); metrics.setGauge( String.join( "/", prefix, "thread_pool_maximum_size"), executorService.getMaximumPoolSize()); metrics.setGauge( String.join( "/", prefix, "thread_pool_size"), executorService.getPoolSize()); } /** * Protected constructor. * * @param builder instance of {@link Builder} */ protected ExecutorServiceMetricsRunnable(final Builder builder) { super(builder._metricsFactory, builder._swallowException, LOGGER); _executorServices = builder._executorServices; } private final Map _executorServices; private static final String ROOT_NAMESPACE = "executor_services"; private static final Logger LOGGER = LoggerFactory.getLogger(JvmMetricsRunnable.class); /** * Builder for ExecutorServiceMetricsRunnable. * * @author Ville Koskela (ville dot koskela at inscopemetrics dot com) */ // CHECKSTYLE.OFF: FinalClass - Allow clients to inherit from this. public static class Builder { // CHECKSTYLE.ON: FinalClass /** * Builds an instance of ExecutorServiceMetricsRunnable. * * @return An instance of ExecutorServiceMetricsRunnable. */ public ExecutorServiceMetricsRunnable build() { if (_metricsFactory == null) { throw new IllegalArgumentException("MetricsFactory cannot be null."); } if (_swallowException == null) { throw new IllegalArgumentException("SwallowException cannot be null."); } if (_executorServices == null) { throw new IllegalArgumentException("ExecutorServices cannot be null."); } for (final ExecutorService executorService : _executorServices.values()) { // NOTE: That a ScheduledThreadPoolExecutor is a ThreadPoolExecutor if (!(executorService instanceof ForkJoinPool) && !(executorService instanceof ThreadPoolExecutor)) { throw new IllegalArgumentException( "Unsupported ExecutorService type: " + executorService.getClass().getName()); } } return new ExecutorServiceMetricsRunnable(this); } /** * Set the MetricsFactory instance. Required. Cannot be * null. * * @param value The value for the MetricsFactory instance. * @return This Builder instance. */ public Builder setMetricsFactory(final MetricsFactory value) { _metricsFactory = value; return this; } /** * Set the flag indicating if any exception caught during the process * of metrics collection should be logged and swallowed. Optional. * Defaults to true. Cannot be null. True indicates that the exception * will be logged and swallowed false indicates it will be rethrown as * a {@code RuntimeException}. * * @param value The value for the Boolean instance. * @return This Builder instance. */ public Builder setSwallowException(final Boolean value) { _swallowException = value; return this; } /** * Set the ExecutorService instances by name. Optional. * Defaults to an empty Map. Cannot be null. * * @param value The ExecutorService instances by name. * @return This Builder instance. */ public Builder setExecutorServices(final Map value) { // CHECKSTYLE.OFF: IllegalInstantiation - No Guava here _executorServices = Collections.unmodifiableMap(new HashMap<>(value)); // CHECKSTYLE.ON: IllegalInstantiation return this; } private MetricsFactory _metricsFactory; private Boolean _swallowException = true; private Map _executorServices; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy