ReflectionUtils { public static void logThreadInfo(Log log, String title, long minInterval) { boolean dumpStack = false; if (log.isInfoEnabled()) { synchronized (ReflectionUtils.class) { long now = Time.monotonicNow(); if (now - previousLogTime >= minInterval * 1000) { previousLogTime = now; dumpStack = true; } } if (dumpStack) { try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); printThreadInfo(new PrintStream(buffer, false, "UTF-8"), title); log.info(buffer.toString(Charset.defaultCharset().name())); } catch (UnsupportedEncodingException ignored) { } } } }  static void setConf(Object theObject, Configuration conf); @SuppressWarnings("unchecked") static T newInstance(Class<T> theClass, Configuration conf); static void setContentionTracing(boolean val); synchronized static void printThreadInfo(PrintStream stream,
                                     String title); static void logThreadInfo(Log log,
                                   String title,
                                   long minInterval); static void logThreadInfo(Logger log,
                                   String title,
                                   long minInterval); @SuppressWarnings("unchecked") static Class<T> getClass(T o); @SuppressWarnings("unchecked") static T copy(Configuration conf, 
                                T src, T dst); @Deprecated static void cloneWritableInto(Writable dst, 
                                       Writable src); static List<Field> getDeclaredFieldsIncludingInherited(Class<?> clazz); static List<Method> getDeclaredMethodsIncludingInherited(Class<?> clazz);  }
@Test public void testLogThreadInfo() throws Exception { Logger logger = LoggerFactory.getLogger(TestReflectionUtils.class); LogCapturer logCapturer = LogCapturer.captureLogs(logger); final String title = "title"; ReflectionUtils.logThreadInfo(logger, title, 0L); assertThat(logCapturer.getOutput(), containsString("Process Thread Dump: " + title)); }