This project has retired. For details please refer to its Attic page.
Source code
001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.util;
020
021import java.util.Map;
022import java.util.logging.Level;
023import java.util.logging.Logger;
024
025/**
026 * Methods to log the currently active set of threads with their stack traces. This is useful to log abnormal
027 * process exit situations, for instance the Driver timeout in the tests.
028 */
029public final class ThreadLogger {
030
031  /**
032   * This is a utility class that shall not be instantiated.
033   */
034  private ThreadLogger() {
035  }
036
037  /**
038   * Same as <code>logThreads(logger, level, prefix, "\n\t", "\n\t\t")</code>
039   */
040  public static void logThreads(final Logger logger, final Level level, final String prefix) {
041    logThreads(logger, level, prefix, "\n\t", "\n\t\t");
042  }
043
044  /**
045   * Logs the currently active threads and their stack trace to the given Logger and Level.
046   *
047   * @param logger             the Logger instance to log to.
048   * @param level              the Level to log into.
049   * @param prefix             a prefix of the log message.
050   * @param threadPrefix       logged before each thread, e.g. "\n\t" to create an indented list.
051   * @param stackElementPrefix logged before each stack trace element, e.g. "\n\t\t" to create an indented list.
052   */
053  public static void logThreads(
054      final Logger logger, final Level level, final String prefix,
055      final String threadPrefix, final String stackElementPrefix) {
056    logger.log(level, getFormattedThreadList(prefix, threadPrefix, stackElementPrefix));
057  }
058
059  /**
060   * Produces a String representation of the currently running threads.
061   *
062   * @param prefix             The prefix of the string returned.
063   * @param threadPrefix       Printed before each thread, e.g. "\n\t" to create an indented list.
064   * @param stackElementPrefix Printed before each stack trace element, e.g. "\n\t\t" to create an indented list.
065   * @return a String representation of the currently running threads.
066   */
067  public static String getFormattedThreadList(
068      final String prefix, final String threadPrefix, final String stackElementPrefix) {
069    final StringBuilder message = new StringBuilder(prefix);
070    for (final Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) {
071      message.append(threadPrefix).append("Thread '").append(entry.getKey().getName()).append("':");
072      for (final StackTraceElement element : entry.getValue()) {
073        message.append(stackElementPrefix).append(element.toString());
074      }
075    }
076    return message.toString();
077  }
078
079  /**
080   * Same as <code>getFormattedThreadList(prefix, "\n\t", "\n\t\t")</code>
081   */
082  public static String getFormattedThreadList(final String prefix) {
083    return getFormattedThreadList(prefix, "\n\t", "\n\t\t");
084  }
085
086  /**
087   * An example how to use the above methods.
088   *
089   * @param args ignored.
090   */
091  public static void main(final String[] args) {
092    logThreads(Logger.getAnonymousLogger(), Level.INFO, "Threads active:");
093  }
094}