CountedRejectedExecutionHandler implements RejectedExecutionHandler { public static void monitorRejections( MeterRegistry registry, ThreadPoolExecutor executor, String name, Iterable<Tag> tags) { executor.setRejectedExecutionHandler( new CountedRejectedExecutionHandler( executor.getRejectedExecutionHandler(), registry, name, tags)); } CountedRejectedExecutionHandler(
      RejectedExecutionHandler delegate, MeterRegistry registry, String name, Iterable<Tag> tags); @Override void rejectedExecution(Runnable r, ThreadPoolExecutor executor); static void monitorRejections(
      MeterRegistry registry, ThreadPoolExecutor executor, String name, Iterable<Tag> tags);  }
@Test public void countRejections() { ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); executor.setRejectedExecutionHandler((r, executor1) -> {}); CountedRejectedExecutionHandler.monitorRejections( registry, executor, CountedRejectedExecutionHandler.class.getName(), userTags); CountDownLatch runnableTaskComplete = new CountDownLatch(1); Runnable stub = () -> { try { runnableTaskComplete.await(10, TimeUnit.SECONDS); } catch (InterruptedException e) { throw new IllegalStateException("runnable interrupted before completion"); } }; executor.submit(stub); for (int i = 0; i < 14; i++) { executor.submit( () -> { }); } assertEquals( registry .get("executor.rejected") .tags(userTags) .tag("name", CountedRejectedExecutionHandler.class.getName()) .counter() .count(), 14.0); runnableTaskComplete.countDown(); executor.shutdownNow(); }