package com.codahale.metrics.jetty9;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.RatioGauge;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

import java.util.concurrent.BlockingQueue;

import static com.codahale.metrics.MetricRegistry.name;

public class InstrumentedQueuedThreadPool extends QueuedThreadPool {
    private final MetricRegistry metricRegistry;

    public InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry) {
        this(registry, 200);
    }

    public InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads) {
        this(registry, maxThreads, 8);
    }

    public InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads) {
        this(registry, maxThreads, minThreads, 60000);
    }

    public InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads,
                                        @Name("idleTimeout") int idleTimeout) {
        this(registry, maxThreads, minThreads, idleTimeout, null);
    }

    public InstrumentedQueuedThreadPool(@Name("registry") MetricRegistry registry,
                                        @Name("maxThreads") int maxThreads,
                                        @Name("minThreads") int minThreads,
                                        @Name("idleTimeout") int idleTimeout,
                                        @Name("queue") BlockingQueue<Runnable> queue) {
        super(maxThreads, minThreads, idleTimeout, queue);
        this.metricRegistry = registry;
    }

    @Override
    protected void doStart() throws Exception {
        super.doStart();
        metricRegistry.register(name(QueuedThreadPool.class, getName(), "utilization"), new RatioGauge() {
            @Override
            protected Ratio getRatio() {
                return Ratio.of(getThreads() - getIdleThreads(), getThreads());
            }
        });
        metricRegistry.register(name(QueuedThreadPool.class, getName(), "utilization-max"), new RatioGauge() {
            @Override
            protected Ratio getRatio() {
                return Ratio.of(getThreads() - getIdleThreads(), getMaxThreads());
            }
        });
        metricRegistry.register(name(QueuedThreadPool.class, getName(), "size"), new Gauge<Integer>() {
            @Override
            public Integer getValue() {
                return getThreads();
            }
        });
        metricRegistry.register(name(QueuedThreadPool.class, getName(), "jobs"), new Gauge<Integer>() {
            @Override
            public Integer getValue() {
                // This assumes the QueuedThreadPool is using a BlockingArrayQueue or
                // ArrayBlockingQueue for its queue, and is therefore a constant-time operation.
                return getQueue().size();
            }
        });
    }
}

@@ -471,16 +471,43 @@
 egistry;
+%0A    private String prefix;
 %0A%0A    pu
@@ -1929,97 +1929,822 @@
     
-super(maxThreads, minThreads, idleTimeout, queue);%0A        this.metricRegistry = registry
+this(registry, maxThreads, minThreads, idleTimeout, queue, null);%0A    %7D%0A%0A    public InstrumentedQueuedThreadPool(@Name(%22registry%22) MetricRegistry registry,%0A                                        @Name(%22maxThreads%22) int maxThreads,%0A                                        @Name(%22minThreads%22) int minThreads,%0A                                        @Name(%22idleTimeout%22) int idleTimeout,%0A                                        @Name(%22queue%22) BlockingQueue%3CRunnable%3E queue,%0A                                        @Name(%22prefix%22) String prefix) %7B%0A        super(maxThreads, minThreads, idleTimeout, queue);%0A        this.metricRegistry = registry;%0A        this.prefix = prefix;%0A    %7D%0A%0A    public String getPrefix() %7B%0A        return prefix;%0A    %7D%0A%0A    public void setPrefix(String prefix) %7B%0A        this.prefix = prefix
 ;%0A  
@@ -2835,24 +2835,25 @@
 tart();%0A
+%0A
         
 metricRe
@@ -2848,70 +2848,168 @@
     
-metricRegistry.register(name(QueuedThreadPool.class, getName()
+final String prefix = this.prefix == null ? name(QueuedThreadPool.class, getName()) : name(this.prefix, getName());%0A%0A        metricRegistry.register(name(prefix
 , %22u
@@ -3251,41 +3251,14 @@
 ame(
-QueuedThreadPool.class, getName()
+prefix
 , %22u
@@ -3507,41 +3507,14 @@
 ame(
-QueuedThreadPool.class, getName()
+prefix
 , %22s
@@ -3709,41 +3709,14 @@
 ame(
-QueuedThreadPool.class, getName()
+prefix
 , %22j

Allow setting custom prefix in InstrumentedQueuedThreadPool