package org.apache.solr.core;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
public class Diagnostics {
protected static Logger log = LoggerFactory.getLogger(Diagnostics.class);
public interface Callable {
public void call(Object... data); // data depends on the context
}
public static void call(Callable callable, Object... data) {
try {
callable.call(data);
} catch (Exception e) {
log.error("TEST HOOK EXCEPTION", e);
}
}
public static void logThreadDumps(String message) {
StringBuilder sb = new StringBuilder(32768);
if (message == null) message = "============ THREAD DUMP REQUESTED ============";
sb.append(message);
sb.append("\n");
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
for (ThreadInfo info : threads) {
sb.append(info);
// sb.append("\n");
}
log.error(sb.toString());
}
public static String toString(StackTraceElement[] stackTrace, int skip) {
StringBuilder sb = new StringBuilder(2048);
try {
appendStackTrace(sb, stackTrace, skip, null, null, null);
} catch (Exception e) {
// impossible
}
return sb.toString();
}
public static String toString(StackTraceElement[] stackTrace, String... startClass_startMethod_end) {
String startClass = startClass_startMethod_end != null && startClass_startMethod_end.length >= 1 ? startClass_startMethod_end[0] : null;
String startMethod = startClass_startMethod_end != null && startClass_startMethod_end.length >= 2 ? startClass_startMethod_end[1] : null;
String endSubstring = startClass_startMethod_end != null && startClass_startMethod_end.length >= 3 ? startClass_startMethod_end[2] : null;
StringBuilder sb = new StringBuilder(2048);
try {
appendStackTrace(sb, stackTrace, -1, startClass, startMethod, endSubstring);
} catch (Exception e) {
// impossible
}
return sb.toString();
}
public static void appendStackTrace(Appendable out, StackTraceElement[] stackTrace, int skip, String startClass, String startMethod, String endSubstring) throws IOException {
if (startClass == null && startMethod == null && skip < 0) {
startClass = Diagnostics.class.getName();
}
if (endSubstring == null) {
endSubstring = ".solr.";
}
int lastInteresting = stackTrace.length;
while (endSubstring != null && --lastInteresting >= 0) {
StackTraceElement trace = stackTrace[lastInteresting];
if (trace.getClassName().contains(endSubstring)) break;
}
int firstInteresting = skip;
if (firstInteresting < 0 && (startClass != null || startMethod != null) ) {
boolean matched = false;
for (firstInteresting=0; firstInteresting < lastInteresting; firstInteresting++) {
StackTraceElement trace = stackTrace[firstInteresting];
String className = trace.getClassName();
String method = trace.getMethodName();
boolean classMatch = startClass!=null && className.contains(startClass);
boolean methodMatch = startMethod!=null && method.contains(startMethod);
if ( (classMatch || startClass == null) && (methodMatch || startMethod == null) )
{
matched = true;
continue;
}
if (matched) break;
}
firstInteresting--;
}
appendStackTrace(out, stackTrace, firstInteresting, lastInteresting+1);
}
public static void appendStackTrace(Appendable out, StackTraceElement[] stackTrace, int start, int end) throws IOException {
for (int i=Math.max(0,start); i<end; i++) {
StackTraceElement trace = stackTrace[i];
out.append("\n\t");
appendStackTraceElement(out, trace);
}
out.append("\n");
}
public static void appendStackTraceElement(Appendable out, StackTraceElement e) throws IOException {
out.append(e.getClassName());
out.append('.');
out.append(e.getMethodName());
if (e.isNativeMethod()) {
out.append("(Native Method)");
} else {
String fileName = e.getFileName();
int lineNumber = e.getLineNumber();
if (fileName != null) {
out.append('(');
out.append(e.getFileName());
if (lineNumber > 0) {
out.append(':');
out.append(Integer.toString(lineNumber));
}
out.append(')');
} else {
out.append("(Unknown Source)");
}
}
}
}