줄 번호를 로그에 인쇄하는 방법 로그에 정보를 출력 할 때 해당 출력이 소스 코드에있는 줄 번호를 인쇄하고 싶습니다. 스택 추적에서 볼 수 있듯이 예외가 발생한 행 번호가 표시됩니다. 스택 추적은 예외 개체에서 사용할 수 있습니다.
다른 대안은 로그에 인쇄 할 때 줄 번호를 수동으로 포함하는 것과 같습니다. 다른 방법이 있습니까?
줄 번호를 로그에 인쇄하는 방법 로그에 정보를 출력 할 때 해당 출력이 소스 코드에있는 줄 번호를 인쇄하고 싶습니다. 스택 추적에서 볼 수 있듯이 예외가 발생한 행 번호가 표시됩니다. 스택 추적은 예외 개체에서 사용할 수 있습니다.
다른 대안은 로그에 인쇄 할 때 줄 번호를 수동으로 포함하는 것과 같습니다. 다른 방법이 있습니까?
답변:
에서 Angsuman 차크라보티 :
/** Get the current line number.
* @return int - Current line number.
*/
public static int getLineNumber() {
return Thread.currentThread().getStackTrace()[2].getLineNumber();
}
우리는 Android 작업에 다음과 같은 사용자 정의 클래스를 사용했습니다.
import android.util.Log;
public class DebugLog {
public final static boolean DEBUG = true;
public static void log(String message) {
if (DEBUG) {
String fullClassName = Thread.currentThread().getStackTrace()[2].getClassName();
String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
int lineNumber = Thread.currentThread().getStackTrace()[2].getLineNumber();
Log.d(className + "." + methodName + "():" + lineNumber, message);
}
}
}
getStackTrace()[3]
대신에getStackTrace()[2]
빠르고 더러운 방법 :
System.out.println("I'm in line #" +
new Exception().getStackTrace()[0].getLineNumber());
자세한 내용은 다음과 같습니다.
StackTraceElement l = new Exception().getStackTrace()[0];
System.out.println(
l.getClassName()+"/"+l.getMethodName()+":"+l.getLineNumber());
다음과 같이 출력됩니다 :
com.example.mytest.MyClass/myMethod:103
System.out.println("i am here: " + new Exception().getStackTrace()[0]);
나는 :) 필요는 나에게 모든 세부 정보를 제공합니다
나는 당신의 질문에 대답하지 않으면 서 대답해야합니다. 디버깅을 지원하기 위해 줄 번호를 찾고 있다고 가정합니다. 더 좋은 방법이 있습니다. 현재 줄을 얻는 방법이 있습니다. 내가 본 것은 느리다. java.util.logging package 또는 log4j 와 같은 로깅 프레임 워크를 사용하는 것이 좋습니다 . 이 패키지를 사용하면 클래스 이름에 대한 컨텍스트를 포함하도록 로깅 정보를 구성 할 수 있습니다. 그런 다음 각 로그 메시지는 그 출처를 알 수있을만큼 고유합니다. 결과적으로 코드에는 '로거'변수가 있습니다.
logger.debug("a really descriptive message")
대신에
System.out.println("a really descriptive message")
Log4J를 사용하면 라인 번호를 출력 패턴의 일부로 포함 할 수 있습니다. 이 작업을 수행하는 방법에 대한 자세한 내용 은 http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html 을 참조 하십시오 (변환 패턴의 핵심 요소는 "L"). 그러나 Javadoc에는 다음이 포함됩니다.
경고 발신자 위치 정보 생성이 매우 느립니다. 실행 속도가 문제가 아닌 한 사용을 피해야합니다.
@ simon.buchan이 게시 한 코드는 작동합니다 ...
Thread.currentThread().getStackTrace()[2].getLineNumber()
그러나 메소드에서 호출하면 항상 메소드의 행 번호를 반환하므로 코드 스 니펫을 인라인으로 사용하십시오.
log4j 와 같은 로깅 툴킷을 사용하는 것이 좋습니다 . 런타임시 속성 파일을 통해 로깅을 구성 할 수 있으며 줄 번호 / 파일 이름 로깅과 같은 기능을 설정 / 해제 할 수 있습니다.
PatternLayout 에 대한 javadoc을 살펴보면 옵션의 전체 목록을 볼 수 있습니다. 다음은 % L입니다.
나는이 작은 메소드를 사용하여 호출 한 메소드의 추적 번호와 라인 번호를 출력합니다.
Log.d(TAG, "Where did i put this debug code again? " + Utils.lineOut());
해당 소스 코드 행으로 이동하려면 출력을 두 번 클릭하십시오!
코드를 어디에 두 었는지에 따라 레벨 값을 조정해야 할 수도 있습니다.
public static String lineOut() {
int level = 3;
StackTraceElement[] traces;
traces = Thread.currentThread().getStackTrace();
return (" at " + traces[level] + " " );
}
Util
에서 왔습니까?
특히 릴리스 용으로 컴파일 된 경우 코드와 줄 번호 일관성을 보장 할 수 없습니다. 어쨌든 그 목적으로 줄 번호를 사용하지 않는 것이 좋습니다. 예외가 발생한 장소의 페이로드를 제공하는 것이 좋습니다 (메소드 메소드는 메시지를 메소드 호출의 세부 사항을 포함하도록 설정하는 것이 좋습니다).
예외 처리 향상을위한 기술로 예외 강화를보고 싶을 수도 있습니다. http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html
먼저 일반적인 방법 (유틸리티 클래스, 일반 오래된 java1.4 코드에서는 java1.5 이상에서 다시 작성해야 할 수도 있음)
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils)
*/
public static String getClassMethodLine(final Class aclass) {
final StackTraceElement st = getCallingStackTraceElement(aclass);
final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber()
+")] <" + Thread.currentThread().getName() + ">: ";
return amsg;
}
그런 다음 특정 유틸리티 메소드가 올바른 stackElement를 가져옵니다.
/**
* Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
* Stored in array of the callstack. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
* @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
*/
public static StackTraceElement getCallingStackTraceElement(final Class aclass) {
final Throwable t = new Throwable();
final StackTraceElement[] ste = t.getStackTrace();
int index = 1;
final int limit = ste.length;
StackTraceElement st = ste[index];
String className = st.getClassName();
boolean aclassfound = false;
if(aclass == null) {
aclassfound = true;
}
StackTraceElement resst = null;
while(index < limit) {
if(shouldExamine(className, aclass) == true) {
if(resst == null) {
resst = st;
}
if(aclassfound == true) {
final StackTraceElement ast = onClassfound(aclass, className, st);
if(ast != null) {
resst = ast;
break;
}
}
else
{
if(aclass != null && aclass.getName().equals(className) == true) {
aclassfound = true;
}
}
}
index = index + 1;
st = ste[index];
className = st.getClassName();
}
if(isNull(resst)) {
throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
}
return resst;
}
static private boolean shouldExamine(String className, Class aclass) {
final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith(LOG_UTILS
) == false || (aclass !=null && aclass.getName().endsWith(LOG_UTILS)));
return res;
}
static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st) {
StackTraceElement resst = null;
if(aclass != null && aclass.getName().equals(className) == false)
{
resst = st;
}
if(aclass == null)
{
resst = st;
}
return resst;
}
우리가 사용하는 로거는 다음과 같습니다.
그것은 안드로이드 로거를 감싸고 클래스 이름, 메소드 이름 및 줄 번호를 표시합니다.
이 링크를 봐 . 이 방법으로 LogCat 행을 두 번 클릭하면 라인 코드로 이동할 수 있습니다.
또한이 코드를 사용하여 줄 번호를 얻을 수 있습니다.
public static int getLineNumber()
{
int lineNumber = 0;
StackTraceElement[] stackTraceElement = Thread.currentThread()
.getStackTrace();
int currentIndex = -1;
for (int i = 0; i < stackTraceElement.length; i++) {
if (stackTraceElement[i].getMethodName().compareTo("getLineNumber") == 0)
{
currentIndex = i + 1;
break;
}
}
lineNumber = stackTraceElement[currentIndex].getLineNumber();
return lineNumber;
}
private static final int CLIENT_CODE_STACK_INDEX;
static {
// Finds out the index of "this code" in the returned stack Trace - funny but it differs in JDK 1.5 and 1.6
int i = 0;
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
i++;
if (ste.getClassName().equals(Trace.class.getName())) {
break;
}
}
CLIENT_CODE_STACK_INDEX = i;
}
private String methodName() {
StackTraceElement ste=Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX+1];
return ste.getMethodName()+":"+ste.getLineNumber();
}
이것들은 모두 현재 스레드의 스레드 번호와 메소드를 얻습니다. 예외를 예상하는 곳에 try catch를 사용하면 효과적입니다. 그러나 처리되지 않은 예외를 잡으려면 기본 포착되지 않은 예외 핸들러를 사용하고 있으며 현재 스레드는 예외를 발생시킨 클래스 메소드가 아니라 핸들러 함수의 행 번호를 리턴합니다. Thread.currentThread ()를 사용하는 대신 예외 핸들러가 전달한 Throwable을 사용하십시오.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
if(fShowUncaughtMessage(e,t))
System.exit(1);
}
});
위의 처리기 함수 (fShowUncaughtMessage)에서 e.getStackTrace () [0]을 사용하여 가해자를 확보하십시오.
아래 코드는 로깅 라인에 대한 테스트 코드이며 로깅 방법이 호출되는 클래스 이름과 메소드 이름이 없습니다.
public class Utils {
/*
* debug variable enables/disables all log messages to logcat
* Useful to disable prior to app store submission
*/
public static final boolean debug = true;
/*
* l method used to log passed string and returns the
* calling file as the tag, method and line number prior
* to the string's message
*/
public static void l(String s) {
if (debug) {
String[] msg = trace(Thread.currentThread().getStackTrace(), 3);
Log.i(msg[0], msg[1] + s);
} else {
return;
}
}
/*
* l (tag, string)
* used to pass logging messages as normal but can be disabled
* when debug == false
*/
public static void l(String t, String s) {
if (debug) {
Log.i(t, s);
} else {
return;
}
}
/*
* trace
* Gathers the calling file, method, and line from the stack
* returns a string array with element 0 as file name and
* element 1 as method[line]
*/
public static String[] trace(final StackTraceElement e[], final int level) {
if (e != null && e.length >= level) {
final StackTraceElement s = e[level];
if (s != null) { return new String[] {
e[level].getFileName(), e[level].getMethodName() + "[" + e[level].getLineNumber() + "]"
};}
}
return null;
}
}
는 stackLevel
이 메서드를 호출 깊이에 따라 달라집니다. 0에서 큰 수까지 시도하여 어떤 차이를 볼 수 있습니다.
stackLevel
합법적 이라면 다음 과 같은 문자열을 얻습니다.java.lang.Thread.getStackTrace(Thread.java:1536)
public static String getCodeLocationInfo(int stackLevel) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if (stackLevel < 0 || stackLevel >= stackTraceElements.length) {
return "Stack Level Out Of StackTrace Bounds";
}
StackTraceElement stackTraceElement = stackTraceElements[stackLevel];
String fullClassName = stackTraceElement.getClassName();
String methodName = stackTraceElement.getMethodName();
String fileName = stackTraceElement.getFileName();
int lineNumber = stackTraceElement.getLineNumber();
return String.format("%s.%s(%s:%s)", fullClassName, methodName, fileName, lineNumber);
}
이것이 바로이 lib XDDLib 에서 구현 한 기능 입니다. (하지만 안드로이드 용입니다)
Lg.d("int array:", intArrayOf(1, 2, 3), "int list:", listOf(4, 5, 6))
밑줄 이 표시된 텍스트 를 한 번 클릭 하면 log 명령이있는 위치로 이동합니다
이는 StackTraceElement
이 라이브러리 외부의 첫 번째 요소에 의해 결정됩니다. 따라서,이 lib 디렉토리 외부 어느 곳이 될 것입니다 법률, 포함 lambda expression
, static initialization block
등
그것은 나를 위해 작동하는 방식
String str = "select os.name from os where os.idos="+nameid; try {
PreparedStatement stmt = conn.prepareStatement(str);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
a = rs.getString("os.n1ame");//<<<----Here is the ERROR
}
stmt.close();
} catch (SQLException e) {
System.out.println("error line : " + e.getStackTrace()[2].getLineNumber());
return a;
}
사용할 수 있습니다-> Reporter.log ( "");